Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RatakondalaArun/web-support #374

Merged
merged 24 commits into from Jul 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
180a0a5
style(analysis): formatted
RatakondalaArun Jul 8, 2022
8b925d0
chore(lints): disabled `sort_constructors_first`
RatakondalaArun Jul 8, 2022
2db23d4
chore(vscode): add vscode workspace config
RatakondalaArun Jul 8, 2022
9087923
vendor(deps): added new dependencies
RatakondalaArun Jul 8, 2022
3a5cbff
feat(web): constants for web platform
RatakondalaArun Jul 8, 2022
e597498
feat(logger): added logger
RatakondalaArun Jul 8, 2022
4a49ff8
feat(web): support for web icons
RatakondalaArun Jul 8, 2022
b2b8982
feat(cli-option): added --prefix option
RatakondalaArun Jul 10, 2022
9a1f828
fix(config): type error when invalid config is passed
RatakondalaArun Jul 10, 2022
542e7fe
vendor(deps): added test dependencies
RatakondalaArun Jul 10, 2022
d3c061d
test(fli_config): added tests for fli config
RatakondalaArun Jul 10, 2022
c2aaaa8
test(utils): added tests for utils
RatakondalaArun Jul 10, 2022
bae9be2
test(web): added tests for web icon templates
RatakondalaArun Jul 10, 2022
a769629
fix(logging): added verbose logging to platform failure
RatakondalaArun Jul 10, 2022
12da70f
vendor(deps): added mokito for tests
RatakondalaArun Jul 10, 2022
3e2578e
test(icon_generator): added tests for IconGenerator
RatakondalaArun Jul 10, 2022
96a54a5
test(web): added tests for web icon generator
RatakondalaArun Jul 10, 2022
24bc6e7
test: added common entrypoint to all tests
RatakondalaArun Jul 10, 2022
4fac239
style: add missing space
RatakondalaArun Jul 20, 2022
4aa4162
fix(generator): fixed typo in a method
RatakondalaArun Jul 20, 2022
af10715
fix(lint): filxed lint warnings for `public_member_api_docs`
RatakondalaArun Jul 20, 2022
610fcb8
fix(lint): filxed lint warnings for `require_trailing_commas`
RatakondalaArun Jul 20, 2022
6713bd4
style: sorted imports
RatakondalaArun Jul 20, 2022
3a5822e
style: sort variable order
RatakondalaArun Jul 20, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 8 additions & 5 deletions analysis_options.yaml
Expand Up @@ -13,12 +13,13 @@ analyzer:
# Please see https://github.com/flutter/flutter/pull/24528 for details.
RatakondalaArun marked this conversation as resolved.
Show resolved Hide resolved
sdk_version_async_exported_from_core: ignore
exclude:
- 'bin/cache/**'
- "bin/cache/**"
# the following two are relative to the stocks example and the flutter package respectively
# see https://github.com/dart-lang/sdk/issues/28463
- 'lib/i18n/stock_messages_*.dart'
- 'lib/src/http/**'
- 'example/**'
- "lib/i18n/stock_messages_*.dart"
- "lib/src/http/**"
- "example/**"
- "**/*.g.dart"

linter:
rules:
Expand Down Expand Up @@ -128,7 +129,7 @@ linter:
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
- recursive_getters
- slash_for_doc_comments
- sort_constructors_first
# - sort_constructors_first: vscode's command "dart:sort members" does not follow this
- sort_pub_dependencies
- sort_unnamed_constructors_first
# - super_goes_last # no longer needed w/ Dart 2
Expand Down Expand Up @@ -157,3 +158,5 @@ linter:
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
- valid_regexps
# - void_checks # not yet tested
- public_member_api_docs
- require_trailing_commas
24 changes: 24 additions & 0 deletions flutter_launcher_icons.code-workspace
@@ -0,0 +1,24 @@
{
"folders": [
{
"name": "Flutter Launcher Icons",
"path": "."
}
],
"settings": {
"[dart]": {
"editor.formatOnSave": true,
// "editor.formatOnType": true,
"editor.rulers": [
120
],
"editor.selectionHighlight": false,
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": false,
"files.insertFinalNewline": true
},
"dart.lineLength": 120,
}
}
109 changes: 109 additions & 0 deletions lib/abs/icon_generator.dart
@@ -0,0 +1,109 @@
import 'dart:io';

import 'package:flutter_launcher_icons/flutter_launcher_icons_config.dart';
import 'package:flutter_launcher_icons/logger.dart';

/// A base class to generate icons
abstract class IconGenerator {
/// Contains config
final IconGeneratorContext context;

/// Name of the platform this [IconGenerator] is created for.
final String platformName;

/// Creates a instance of [IconGenerator].
///
/// A [context] is created and provided by [generateIconsFor],
/// [platformName] takes the name of the platform that this [IconGenerator]
/// is implemented for
///
/// Also Refer
/// - [WebIconGenerator] generate icons for web
/// - [generateIconFor] generates icons for given platform
IconGenerator(this.context, this.platformName);

/// Creates icons for this platform.
void createIcons();

/// Should return `true` if this platform
/// has all the requirments to create icons.
/// This runs before to [createIcons]
bool validateRequirements();
}

/// Provides easy access to user arguments and configuration
class IconGeneratorContext {
/// Contains configuration from configuration file
final FlutterLauncherIconsConfig config;

/// A logger
final FLILogger logger;

/// Value of `--prefix` flag
final String prefixPath;

/// Value of `--flavor` flag
final String? flavor;

/// Creates an instance of [IconGeneratorContext]
IconGeneratorContext({
required this.config,
required this.logger,
required this.prefixPath,
this.flavor,
});

/// Shortcut for `config.webConfig`
WebConfig? get webConfig => config.webConfig;
}

/// Generates Icon for given platforms
void generateIconsFor({
required FlutterLauncherIconsConfig config,
required String? flavor,
required String prefixPath,
required FLILogger logger,
required List<IconGenerator> Function(IconGeneratorContext context) platforms,
}) {
try {
final platformList = platforms(IconGeneratorContext(
config: config,
logger: logger,
prefixPath: prefixPath,
flavor: flavor,
));
if (platformList.isEmpty) {
// ? maybe we can print help
logger.info('No platform provided');
}

for (final platform in platformList) {
final progress = logger.progress('Creating Icons for ${platform.platformName}');
logger.verbose('Validating platform requirments for ${platform.platformName}');
// in case a platform throws an exception it should not effect other platforms
try {
if (!platform.validateRequirements()) {
logger.error('Requirments failed for platform ${platform.platformName}. Skipped');
progress.cancel();
continue;
}
platform.createIcons();
progress.finish(message: 'done', showTiming: true);
} catch (e, st) {
progress.cancel();
logger
..error(e.toString())
..verbose(st);
continue;
}
}
} catch (e, st) {
// todo: better error handling
// stacktrace should only print when verbose is turned on
RatakondalaArun marked this conversation as resolved.
Show resolved Hide resolved
// else a normal help line
logger
..error(e.toString())
..verbose(st);
exit(1);
}
}
52 changes: 36 additions & 16 deletions lib/constants.dart
@@ -1,35 +1,55 @@
String androidResFolder(String? flavor) =>
"android/app/src/${flavor ?? 'main'}/res/";
String androidColorsFile(String? flavor) =>
"android/app/src/${flavor ?? 'main'}/res/values/colors.xml";
import 'package:path/path.dart' as path;

/// Relative path to android resource folder
String androidResFolder(String? flavor) => "android/app/src/${flavor ?? 'main'}/res/";

/// Relative path to android colors.xml file
String androidColorsFile(String? flavor) => "android/app/src/${flavor ?? 'main'}/res/values/colors.xml";

const String androidManifestFile = 'android/app/src/main/AndroidManifest.xml';
const String androidGradleFile = 'android/app/build.gradle';
const String androidLocalPropertiesFile = 'android/local.properties';
const String androidFileName = 'ic_launcher.png';
const String androidAdaptiveForegroundFileName = 'ic_launcher_foreground.png';
const String androidAdaptiveBackgroundFileName = 'ic_launcher_background.png';
String androidAdaptiveXmlFolder(String? flavor) =>
androidResFolder(flavor) + 'mipmap-anydpi-v26/';
String androidAdaptiveXmlFolder(String? flavor) => androidResFolder(flavor) + 'mipmap-anydpi-v26/';
const String androidDefaultIconName = 'ic_launcher';

const String iosDefaultIconFolder =
'ios/Runner/Assets.xcassets/AppIcon.appiconset/';
const String iosDefaultIconFolder = 'ios/Runner/Assets.xcassets/AppIcon.appiconset/';
const String iosAssetFolder = 'ios/Runner/Assets.xcassets/';
const String iosConfigFile = 'ios/Runner.xcodeproj/project.pbxproj';
const String iosDefaultIconName = 'Icon-App';

// web
/// favicon.ico size
const int kFaviconSize = 16;

/// Relative web direcotry path
String webDirPath = path.join('web');

/// Relative web icons directory path
String webIconsDirPath = path.join(webDirPath, 'icons');

/// Relative web manifest.json file path
String webManifestFilePath = path.join(webDirPath, 'manifest.json');
// todo: support for other images formats
/// Relative favicon.png path
String webFaviconFilePath = path.join(webDirPath, 'favicon.png');

/// Relative index.html file path
String webIndexFilePath = path.join(webDirPath, 'index.html');

/// Relative pubspec.yaml path
String pubspecFilePath = path.join('pubspec.yaml');

const String errorMissingImagePath =
'Missing "image_path" or "image_path_android" + "image_path_ios" within configuration';
const String errorMissingPlatform =
'No platform specified within config to generate icons for.';
const String errorMissingRegularAndroid =
'Adaptive icon config found but no regular Android config. '
const String errorMissingPlatform = 'No platform specified within config to generate icons for.';
const String errorMissingRegularAndroid = 'Adaptive icon config found but no regular Android config. '
'Below API 26 the regular Android config is required';
const String errorMissingMinSdk =
'Cannot not find minSdk from android/app/build.gradle or android/local.properties'
const String errorMissingMinSdk = 'Cannot not find minSdk from android/app/build.gradle or android/local.properties'
'Specify minSdk in either android/app/build.gradle or android/local.properties';
const String errorIncorrectIconName =
'The icon name must contain only lowercase a-z, 0-9, or underscore: '
const String errorIncorrectIconName = 'The icon name must contain only lowercase a-z, 0-9, or underscore: '
'E.g. "ic_my_new_icon"';

String introMessage(String currentVersion) => '''
Expand Down
14 changes: 14 additions & 0 deletions lib/custom_exceptions.dart
Expand Up @@ -39,3 +39,17 @@ class NoDecoderForImageFormatException implements Exception {
return generateError(this, message);
}
}

/// A exception to throw when given [fileName] is not found
class FileNotFoundException implements Exception {
/// Creates a instance of [FileNotFoundException].
const FileNotFoundException(this.fileName);

/// Name of the file
final String fileName;

@override
String toString() {
return generateError(this, '$fileName file not found');
}
}