Skip to content

Commit

Permalink
add teminal progress bar ui
Browse files Browse the repository at this point in the history
  • Loading branch information
YehudaKremer committed Apr 15, 2021
1 parent 6585411 commit 4e74a8c
Show file tree
Hide file tree
Showing 9 changed files with 304 additions and 110 deletions.
9 changes: 2 additions & 7 deletions lib/msix.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,12 @@ class Msix {
await config.getConfigValues(cliArguments);
config.validateConfigValues();
final assets = Assets();
assets.cleanTemporaryFiles();
assets.cleanTemporaryFiles(clearMsixFiles: true);
assets.createIconsFolder();
assets.copyIcons();
assets.copyVCLibsFiles();

Manifest()..generateAppxManifest();

if (!config.haveAnyIconFromUser()) {
Makepri.generatePRI();
}

Makepri.generatePRI();
Makeappx.pack();
Signtool.sign();
assets.cleanTemporaryFiles();
Expand Down
30 changes: 19 additions & 11 deletions lib/src/assets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ class Assets {
}

void createIconsFolder() {
Log.startTask('creating app icons folder');
Log.taskStarted('creating app icons folder');

var iconsFolderPath = '${_config.buildFilesFolder}\\Images';
try {
Directory(iconsFolderPath).createSync();
} catch (e) {
Log.error('fail to create app icons folder in: $iconsFolderPath\n$e');
exit(0);
}

Log.completeTask();
Log.taskCompleted();
}

void copyIcons() {
Log.startTask('copying app icons');
Log.taskStarted('copying app icons');

if (_config.haveAnyIconFromUser()) {
_config.tileIconPath = _copyIconToBuildFolder(_config.tileIconPath ??
Expand All @@ -45,21 +44,21 @@ class Assets {
_config.vsGeneratedIconsFolderPath ?? _config.defaultsIconsFolderPath());
}

Log.completeTask();
Log.taskCompleted();
}

void copyVCLibsFiles() {
Log.startTask('copying VC libraries');
Log.taskStarted('copying VC libraries');

for (var file in _vCLibsFiles) {
File(file.path).copySync('${_config.buildFilesFolder}/${basename(file.path)}');
}

Log.completeTask();
Log.taskCompleted();
}

void cleanTemporaryFiles() {
Log.startTask('cleaning temporary files');
void cleanTemporaryFiles({clearMsixFiles = false}) {
Log.taskStarted('cleaning temporary files');

try {
var appxManifest = File('${_config.buildFilesFolder}/AppxManifest.xml');
Expand Down Expand Up @@ -87,11 +86,21 @@ class Assets {
var fileToDelete = File('${_config.buildFilesFolder}/${basename(file.path)}');
if (fileToDelete.existsSync()) fileToDelete.deleteSync();
}

if (clearMsixFiles) {
Directory(_config.buildFilesFolder)
.listSync(recursive: true, followLinks: false)
.map((e) => File(e.path))
.where((f) => basename(f.path).contains('.msix'))
.forEach((file) {
file.deleteSync();
});
}
} catch (e) {
Log.error('fail to clean temporary files from ${_config.buildFilesFolder}: $e');
}

Log.completeTask();
Log.taskCompleted();
}

void _copyVsGeneratedIcons(String iconsFolderPath) {
Expand All @@ -113,7 +122,6 @@ class Assets {
File(iconPath).copySync('${_config.buildFilesFolder}/$newPath');
} catch (e) {
Log.error('fail to copy icon: $iconPath\n$e');
exit(0);
}

return newPath;
Expand Down
8 changes: 3 additions & 5 deletions lib/src/cli/makeappx.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import '../configuration.dart';

class Makeappx {
static void pack() {
Log.startTask('packing');
Log.taskStarted('packing');
final config = injector.get<Configuration>();
var msixPath = '${config.buildFilesFolder}/${config.appName}.msix';
var makeappxPath = '${config.msixToolkitPath()}/Redist.${config.architecture}/makeappx.exe';
Expand All @@ -21,13 +21,11 @@ class Makeappx {
]);

if (result.stderr.toString().length > 0) {
Log.error(result.stdout);
Log.error(result.stdout, andExit: false);
Log.error(result.stderr);
exit(0);
} else if (result.exitCode != 0) {
Log.error(result.stdout);
exit(0);
}
Log.completeTask();
Log.taskCompleted();
}
}
74 changes: 39 additions & 35 deletions lib/src/cli/makepri.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,51 @@ import '../configuration.dart';

class Makepri {
static void generatePRI() {
Log.startTask('generate PRI file');
Log.taskStarted('generate PRI file');
final config = injector.get<Configuration>();
var makepriPath = '${config.msixToolkitPath()}/Redist.${config.architecture}/makepri.exe';

var result = Process.runSync(makepriPath,
['createconfig', '/cf', '${config.buildFilesFolder}\\priconfig.xml', '/dq', 'en-US', '/o']);
if (!config.haveAnyIconFromUser()) {
var makepriPath = '${config.msixToolkitPath()}/Redist.${config.architecture}/makepri.exe';

if (result.stderr.toString().length > 0) {
Log.error(result.stdout);
Log.error(result.stderr);
exit(0);
} else if (result.exitCode != 0) {
Log.error(result.stdout);
exit(0);
}
var result = Process.runSync(makepriPath, [
'createconfig',
'/cf',
'${config.buildFilesFolder}\\priconfig.xml',
'/dq',
'en-US',
'/o'
]);

result = Process.runSync(makepriPath, [
'new',
'/cf',
'${config.buildFilesFolder}\\priconfig.xml',
'/pr',
config.buildFilesFolder,
'/mn',
'${config.buildFilesFolder}\\AppxManifest.xml',
'/of',
'${config.buildFilesFolder}\\resources.pri',
'/o',
]);
if (result.stderr.toString().length > 0) {
Log.error(result.stdout, andExit: false);
Log.error(result.stderr);
} else if (result.exitCode != 0) {
Log.error(result.stdout);
}

var priconfig = File('${config.buildFilesFolder}/priconfig.xml');
if (priconfig.existsSync()) priconfig.deleteSync();
result = Process.runSync(makepriPath, [
'new',
'/cf',
'${config.buildFilesFolder}\\priconfig.xml',
'/pr',
config.buildFilesFolder,
'/mn',
'${config.buildFilesFolder}\\AppxManifest.xml',
'/of',
'${config.buildFilesFolder}\\resources.pri',
'/o',
]);

if (result.stderr.toString().length > 0) {
Log.error(result.stdout);
Log.error(result.stderr);
exit(0);
} else if (result.exitCode != 0) {
Log.error(result.stdout);
exit(0);
}
var priconfig = File('${config.buildFilesFolder}/priconfig.xml');
if (priconfig.existsSync()) priconfig.deleteSync();

Log.completeTask();
if (result.stderr.toString().length > 0) {
Log.error(result.stdout, andExit: false);
Log.error(result.stderr);
} else if (result.exitCode != 0) {
Log.error(result.stdout);
}
}
Log.taskCompleted();
}
}
17 changes: 5 additions & 12 deletions lib/src/cli/signtool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ import '../configuration.dart';

class Signtool {
static void sign() {
Log.startTask('signing');
Log.taskStarted('signing');
final config = injector.get<Configuration>();

if (config.certificatePath.isNull) {
Log.warn(
'signing with TEST certificate, reason: Publisher provided but not Certificate Path');
} else {
if (!config.certificatePath.isNull) {
var signtoolPath = '${config.msixToolkitPath()}/Redist.${config.architecture}/signtool.exe';

ProcessResult signResults;
Expand Down Expand Up @@ -48,8 +45,8 @@ class Signtool {

if (!signResults.stdout.toString().contains('Number of files successfully Signed: 1') &&
signResults.stderr.toString().length > 0) {
Log.error(signResults.stdout);
Log.error(signResults.stderr);
Log.error(signResults.stdout, andExit: false);
Log.error(signResults.stderr, andExit: false);

if (signResults.stdout.toString().contains('Error: SignerSign() failed.') &&
!config.publisher.isNull) {
Expand All @@ -59,11 +56,7 @@ class Signtool {
exit(0);
}

if (config.isUsingTestCertificate) {
Log.warn(' *no certificate was specified, using TEST certificate');
}

Log.completeTask();
Log.taskCompleted();
}
}
}
34 changes: 11 additions & 23 deletions lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ class Configuration {
String msixToolkitPath() => '$msixAssetsPath/MSIX-Toolkit';

Future<void> getConfigValues(List<String> arguments) async {
Log.startTask('getting config values');

_parseCliArguments(arguments);
await _getAssetsFolderPath();
var pubspec = _getPubspec();
Expand All @@ -65,17 +63,14 @@ class Configuration {
architecture = config?['architecture']?.toString();
capabilities = config?['capabilities']?.toString();
languages = _getLanguages(config);

Log.completeTask();
}

/// Validate the configuration values and set default values
void validateConfigValues() {
Log.startTask('validating config values');
Log.taskStarted('validating config values');

if (appName.isNull) {
Log.error('App name is empty, check \'appName\' at pubspec.yaml');
exit(0);
}
if (appDescription.isNull) appDescription = appName;
if (displayName.isNull) displayName = appName!.replaceAll('_', '');
Expand All @@ -90,7 +85,6 @@ class Configuration {
if (!Directory(buildFilesFolder).existsSync()) {
Log.error(
'Build files not found as $buildFilesFolder, first run "flutter build windows" then try again');
exit(0);
}

final executables = Directory(buildFilesFolder)
Expand All @@ -103,37 +97,32 @@ class Configuration {

if (!RegExp(r'^(\*|\d+(\.\d+){3,3}(\.\*)?)$').hasMatch(msixVersion!)) {
Log.error('Msix version can be only in this format: "1.0.0.0"');
exit(0);
}

/// If no certificate was chosen then use test certificate
if (certificatePath.isNull) {
if (publisher.isNull) {
certificatePath = '$msixAssetsPath/test_certificate.pfx';
certificatePassword = '1234';
publisher = defaultPublisher;
isUsingTestCertificate = true;
}
certificatePath = '$msixAssetsPath/test_certificate.pfx';
certificatePassword = '1234';
publisher = defaultPublisher;
isUsingTestCertificate = true;
} else if (!File(certificatePath!).existsSync()) {
Log.error(
'The file certificate not found in: $certificatePath, check "msix_config: certificate_path" at pubspec.yaml');
exit(0);
} else if (publisher.isNull) {
Log.error('Certificate subject is empty, check "msix_config: publisher" at pubspec.yaml');
Log.error('Certificate subject is empty, check "msix_config: publisher" at pubspec.yaml',
andExit: false);
Log.warn('see what certificate-subject value is:');
Log.link(
'https://drive.google.com/file/d/1oAsnrp2Kf-jZ_kaRjyF5llQ0YZy1IwNe/view?usp=sharing');
exit(0);
} else if (extension(certificatePath!) == '.pfx' && certificatePassword.isNull) {
Log.error(
'Certificate password is empty, check "msix_config: certificate_password" at pubspec.yaml');
exit(0);
}

if (!['x86', 'x64'].contains(architecture)) {
Log.error(
'Architecture can be "x86" or "x64", check "msix_config: architecture" at pubspec.yaml');
exit(0);
}

if (iconsBackgroundColor != 'transparent' && !iconsBackgroundColor!.contains('#'))
Expand All @@ -142,18 +131,17 @@ class Configuration {
if (iconsBackgroundColor != 'transparent' &&
!RegExp(r'^#(?:[0-9a-fA-F]{3}){1,2}$').hasMatch(iconsBackgroundColor!)) {
Log.error('Icons background color can be only in this format: "#ffffff"');
exit(0);
}

Log.completeTask();
Log.taskCompleted();
}

bool haveAnyIconFromUser() =>
!logoPath.isNull || !startMenuIconPath.isNull || !tileIconPath.isNull;

/// parse the cli arguments
void _parseCliArguments(List<String> args) {
Log.startTask('parsing cli arguments');
Log.taskStarted('parsing cli arguments');

var parser = ArgParser()
..addOption('password', abbr: 'p')
Expand All @@ -164,10 +152,10 @@ class Configuration {
try {
argResults = parser.parse(args);
} catch (e) {
Log.warn('invalid cli arguments: $e');
Log.error('invalid cli arguments: $e');
}

Log.completeTask();
Log.taskCompleted();
}

/// Get the assets folder path from the .packages file
Expand Down
5 changes: 2 additions & 3 deletions lib/src/manifest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Manifest {
Manifest() : _config = injector.get<Configuration>();

void generateAppxManifest() {
Log.startTask('generate appx manifest');
Log.taskStarted('generate appx manifest');

var manifestContent = '''<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
Expand Down Expand Up @@ -102,10 +102,9 @@ class Manifest {
File(appxManifestPath).writeAsStringSync(manifestContent);
} catch (e) {
Log.error('fail to create manifest file: $e');
exit(0);
}

Log.completeTask();
Log.taskCompleted();
}

String _getVisualElements() {
Expand Down

0 comments on commit 4e74a8c

Please sign in to comment.