Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ include: package:flame_lint/analysis_options.yaml

linter:
rules:
avoid_print: false # since it is a CLI application
avoid_print: true # should always use a Logger
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can just remove the override - it will be true by default :)


analyzer:
exclude:
- bricks/
- bricks/
15 changes: 12 additions & 3 deletions bin/ignite.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import 'package:ignite_cli/main.dart';
import 'dart:io';

void main(List<String> args) {
mainCommand(args);
import 'package:ignite_cli/flame_version_manager.dart';
import 'package:ignite_cli/ignite_commmand_runner.dart';
import 'package:mason_logger/mason_logger.dart';

Future<void> main(List<String> args) async {
final runner = IgniteCommandRunner(
logger: Logger(),
flameVersionManager: await FlameVersionManager.fetch(),
);

exit((await runner.run(args)).code);
}
120 changes: 101 additions & 19 deletions lib/commands/create_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,102 @@ import 'dart:io';

import 'package:args/args.dart';
import 'package:dartlin/dartlin.dart';
import 'package:ignite_cli/commands/ignite_command.dart';
import 'package:ignite_cli/flame_version_manager.dart';
import 'package:ignite_cli/templates/template.dart';
import 'package:ignite_cli/utils.dart';
import 'package:io/ansi.dart' as ansi;
import 'package:mason/mason.dart';
import 'package:process_run/process_run.dart';

Future<void> createCommand(ArgResults command) async {
class CreateCommand extends IgniteCommand {
CreateCommand(super.context) {
final packages = context.flameVersionManager.versions;
final flameVersions = packages[Package.flame]!;

argParser.addFlag(
'interactive',
abbr: 'i',
help: 'Whether to run in interactive mode or not.',
defaultsTo: true,
);
argParser.addOption(
'name',
help: 'The name of your game (valid dart identifier).',
);
argParser.addOption(
'org',
help: 'The org name, in reverse domain notation '
'(package name/bundle identifier).',
);
argParser.addFlag(
'create-folder',
abbr: 'f',
help: 'If you want to create a new folder on the current location with '
"the project name or if you are already on the new project's folder.",
);
argParser.addOption(
'template',
help: 'What Flame template you would like to use for your new project',
allowed: ['simple', 'example'],
);
argParser.addOption(
'flame-version',
help: 'What Flame version you would like to use.',
allowed: [
...flameVersions.versions.take(5),
'...',
flameVersions.versions.last,
],
);
argParser.addMultiOption(
'extra-packages',
help: 'Which packages to use',
allowed: packages.keys.map((e) => e.name).toList(),
);
}

@override
String get description => 'Create a new Flame project';

@override
String get name => 'create';

@override
Future<ExitCode> run() async {
final argResults = this.argResults;
if (argResults == null) {
return ExitCode.usage;
}

await createCommand(
context.logger,
argResults,
context.flameVersionManager,
);

return ExitCode.success;
}
}

Future<void> createCommand(
Logger logger,
ArgResults command,
FlameVersionManager flameVersionManager,
) async {
final interactive = command['interactive'] != 'false';

if (interactive) {
stdout.write('\nWelcome to ${ansi.red.wrap('Ignite CLI')}! 🔥\n');
stdout.write("Let's create a new project!\n\n");
logger
..info('\nWelcome to ${red.wrap('Ignite CLI')}! 🔥')
..info("Let's create a new project!\n");
}

final name = getString(
isInteractive: interactive,
logger: logger,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we standardize the logger to be the first parameter?

command,
'name',
'Choose a name for your project: ',
'Choose a name for your project',
desc: 'Note: this must be a valid dart identifier (no dashes). '
'For example: my_game',
validate: (it) => switch (it) {
Expand All @@ -34,6 +110,7 @@ Future<void> createCommand(ArgResults command) async {
);

final org = getString(
logger: logger,
isInteractive: interactive,
command,
'org',
Expand All @@ -48,9 +125,10 @@ Future<void> createCommand(ArgResults command) async {
},
);

final versions = FlameVersionManager.singleton.versions;
final versions = flameVersionManager.versions;
final flameVersions = versions[Package.flame]!;
final flameVersion = getOption(
logger: logger,
isInteractive: interactive,
command,
'flame-version',
Expand All @@ -60,11 +138,12 @@ Future<void> createCommand(ArgResults command) async {
fullOptions: flameVersions.versions.associateWith((e) => e),
);

final extraPackageOptions = FlameVersionManager.singleton.versions.keys
final extraPackageOptions = flameVersionManager.versions.keys
.where((key) => !Package.includedByDefault.contains(key))
.map((key) => key.name)
.toList();
final extraPackages = getMultiOption(
logger: logger,
isInteractive: interactive,
isRequired: false,
command,
Expand All @@ -83,9 +162,10 @@ Future<void> createCommand(ArgResults command) async {
final devDependencies = packages.where((e) => e.isDevDependency);

final currentDir = Directory.current.path;
print('\nYour current directory is: $currentDir');
logger.info('\nYour current directory is: $currentDir');

final createFolder = getOption(
logger: logger,
isInteractive: interactive,
command,
'create-folder',
Expand All @@ -98,8 +178,9 @@ Future<void> createCommand(ArgResults command) async {
) ==
'true';

print('\n');
logger.info('\n');
final template = getOption(
logger: logger,
isInteractive: interactive,
command,
'template',
Expand All @@ -112,26 +193,26 @@ Future<void> createCommand(ArgResults command) async {
if (createFolder) {
await runExecutableArguments('mkdir', [actualDir]);
}
print('\nRunning flutter create on $actualDir ...');
logger.info('\nRunning flutter create on $actualDir ...');

await runExecutableArguments(
'flutter',
'create --org $org --project-name $name .'.split(' '),
workingDirectory: actualDir,
verbose: true,
verbose: logger.level == Level.verbose,
);

await runExecutableArguments(
'rm',
'-rf lib test'.split(' '),
workingDirectory: actualDir,
verbose: true,
verbose: logger.level == Level.verbose,
);

final bundle = Template.byKey(template).bundle;
final generator = await MasonGenerator.fromBundle(bundle);
final target = DirectoryGeneratorTarget(
Directory(actualDir),
);
final target = DirectoryGeneratorTarget(Directory(actualDir));

final variables = <String, dynamic>{
'name': name,
'description': 'A simple Flame game.',
Expand All @@ -153,16 +234,17 @@ Future<void> createCommand(ArgResults command) async {
'rm',
'-rf test'.split(' '),
workingDirectory: actualDir,
verbose: true,
verbose: logger.level == Level.verbose,
);
}

await runExecutableArguments(
'flutter',
'pub get'.split(' '),
workingDirectory: actualDir,
verbose: true,
verbose: logger.level == Level.verbose,
);

print('Updated ${files.length} files on top of flutter create.\n');
print('Your new Flame project was successfully created!');
// logger.info('Updated ${files.length} files on top of flutter create.\n');
logger.info('Your new Flame project was successfully created!');
}
25 changes: 25 additions & 0 deletions lib/commands/ignite_command.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'dart:async';

import 'package:args/command_runner.dart';
import 'package:ignite_cli/flame_version_manager.dart';
import 'package:mason/mason.dart';
import 'package:mason_logger/mason_logger.dart';

abstract class IgniteCommand extends Command<ExitCode> {
final IgniteContext context;

IgniteCommand(this.context);

@override
Future<ExitCode> run();
}

class IgniteContext {
const IgniteContext({
required this.logger,
required this.flameVersionManager,
});

final Logger logger;
final FlameVersionManager flameVersionManager;
}
35 changes: 28 additions & 7 deletions lib/commands/version_command.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
import 'package:ignite_cli/version.g.dart';
import 'package:mason/mason.dart';
import 'package:process_run/process_run.dart';

Future<void> versionCommand() async {
print(r'$ ignite --version:');
print(igniteVersion);
print('');
await runExecutableArguments('dart', ['--version'], verbose: true);
print('');
await runExecutableArguments('flutter', ['--version'], verbose: true);
Future<void> versionCommand(Logger logger) async {
logger.info('ignite --version: $igniteVersion\n');

final [dartProcess, flutterProcess] = await [
runExecutableArguments(
'dart',
['--version'],
commandVerbose: false,
verbose: false,
),
runExecutableArguments(
'flutter',
['--version'],
commandVerbose: false,
verbose: false,
),
].wait;

logger.info('${dartProcess.stdout}');
logger.info('${flutterProcess.stdout}');

if (dartProcess.stderr case final String err when err.isNotEmpty) {
logger.err(err);
}
if (flutterProcess.stderr case final String err when err.isNotEmpty) {
logger.err(err);
}
}
6 changes: 0 additions & 6 deletions lib/flame_version_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@ import 'dart:convert';
import 'package:http/http.dart' as http;

class FlameVersionManager {
static late FlameVersionManager singleton;

static Future<void> init() async {
singleton = await FlameVersionManager.fetch();
}

final Map<Package, Versions> versions;

const FlameVersionManager._(this.versions);
Expand Down
Loading
Loading