exec method

  1. @override
Future<void> exec(
  1. ExecContext context
)
override

Run command.

The contents of katana.yaml and the arguments of the command are passed to context.

コマンドを実行します。

contextkatana.yamlの内容やコマンドの引数が渡されます。

Implementation

@override
Future<void> exec(ExecContext context) async {
  final bin = context.yaml.getAsMap("bin");
  final flutter = bin.get("flutter", "flutter");
  final packageName = context.args.get(1, "");
  if (packageName.isEmpty) {
    error(
      "Please provide the name of the package.\r\nパッケージ名を記載してください。\r\n\r\nkatana package [package name]",
    );
    return;
  }
  final projectName = packageName.split(".").lastOrNull;
  final domain = packageName
      .split(".")
      .sublist(0, packageName.split(".").length - 1)
      .join(".");
  if (projectName.isEmpty || domain.isEmpty) {
    error(
      "The format of the package name should be specified in the following format.\r\nパッケージ名の形式は下記の形式で指定してください。\r\n\r\n[Domain].[ProjectName]\r\ne.g. net.mathru.website",
    );
    return;
  }
  await command(
    "Create a Flutter project.",
    [
      flutter,
      "create",
      "--org",
      domain,
      "--template=package",
      projectName!,
    ],
  );
  await _moveDirectoryContents(projectName, ".");
  Directory(projectName).deleteSync(recursive: true);
  File("test/${projectName.toSnakeCase()}_test.dart").deleteSync();
  await command(
    "Import packages.",
    [
      flutter,
      "pub",
      "add",
      ...importPackages,
    ],
  );
  await command(
    "Import dev packages.",
    [
      flutter,
      "pub",
      "add",
      "--dev",
      ...importDevPackages,
      "import_sorter",
    ],
  );
  label("Generate file for VSCode");
  for (final file in otherFiles.entries) {
    await file.value.generateFile(file.key);
  }
  label("Replace package main file.");
  await PackageMainCliCode(packageName: projectName)
      .generateFile("${projectName.toSnakeCase()}.dart");
  label("Replace package README.md file.");
  await PackageReadMeCliCode(packageName: projectName)
      .generateFile("README.md");
  label("Replace LICENSE");
  await const LicenseCliCode().generateFile("LICENSE");
  label("Create a pubspec_overrides.yaml");
  await const PubspecOverridesCliCode()
      .generateFile("pubspec_overrides.yaml");
  label("Create a build.yaml");
  await const BuildCliCode().generateFile("build.yaml");
  label("Edit a analysis_options.yaml");
  await const AnalysisOptionsCliCode().generateFile("analysis_options.yaml");
  label("Rewrite `.gitignore`.");
  final gitignore = File(".gitignore");
  if (!gitignore.existsSync()) {
    error("Cannot find `.gitignore`. Project is broken.");
    return;
  }
  final gitignores = await gitignore.readAsLines();
  if (!gitignores.any((e) => e.startsWith("pubspec_overrides.yaml"))) {
    gitignores.add("pubspec_overrides.yaml");
  }
  if (!gitignores.any((e) => e.startsWith("/android/app/.cxx/"))) {
    gitignores.add("/android/app/.cxx/");
  }
  await gitignore.writeAsString(gitignores.join("\n"));
  label("Rewrite `pubspec.yaml`.");
  final pubspec = File("pubspec.yaml");
  if (!pubspec.existsSync()) {
    error("Cannot find `pubspec.yaml`. Project is broken.");
    return;
  }
  final pubspecsRes = <String>[];
  final pubspecs = await pubspec.readAsLines();
  for (final tmp in pubspecs) {
    if (tmp.startsWith("homepage:")) {
      pubspecsRes.add("# homepage:");
    } else if (tmp.startsWith("flutter:")) {
      pubspecsRes.add("# flutter:");
    } else {
      pubspecsRes.add(tmp);
    }
  }
  await pubspec.writeAsString(pubspecsRes.join("\n"));
  await Future.delayed(const Duration(seconds: 5));
  await command(
    "Run the project's build_runner to generate code.",
    [
      flutter,
      "packages",
      "pub",
      "run",
      "build_runner",
      "build",
      "--delete-conflicting-outputs",
    ],
  );
  await command(
    "Run import sorter",
    [
      flutter,
      "pub",
      "run",
      "import_sorter:main",
      ".",
    ],
  );
}