create method

Stream<PackagexApiStatus> create({
  1. required String newName,
  2. required Directory directoryPackage,
  3. required bool isApplication,
  4. required PackagexConfig? packagexConfig,
})

Implementation

Stream<PackagexApiStatus> create({
  required String newName,
  required Directory directoryPackage,
  required bool isApplication,
  required PackagexConfig? packagexConfig,
}) async* {
  packagexConfig ??= PackagexConfig({});
  Directory directory_project = await Future(() async {
    return Directory(Directory(
            path.join(directoryPackage.uri.toFilePath(), newName.trim()))
        .uri
        .toFilePath());
  });
  String project_name = path.basename(directory_project.path);
  yield PackagexApiStatus(
      packagexApiStatusType: PackagexApiStatusType.info,
      value: "Started Create Project: ${project_name}");

  File file_pubspec = File(path.join(directory_project.path, "pubspec.yaml"));
  if (file_pubspec.existsSync() == false) {
    yield PackagexApiStatus(
        packagexApiStatusType: PackagexApiStatusType.info,
        value:
            "Started Create Project: ${(isApplication) ? "flutter" : "dart"} ${project_name}");
    List<String> arguments = () {
      List<String> defaults_args = [
        "create",
        newName,
        "--no-pub",
      ];
      if (isApplication) {
        defaults_args.addAll([
          "--offline",
        ]);
      } else {
        defaults_args.addAll([
          "--force",
        ]);
      }
      return defaults_args;
    }();
    Process process = await Process.start(
      (isApplication) ? "flutter" : "dart",
      arguments,
      workingDirectory: directory_project.parent.uri.toFilePath(),
    );
    process.stderr.listen((event) {
      stderr.add(event);
    });
    process.stdout.listen((event) {
      stdout.add(event);
    });
    int exit_code = await (process.exitCode);
    if (exit_code != 0) {
      yield PackagexApiStatus(
          packagexApiStatusType: PackagexApiStatusType.failed,
          value:
              "Failed Create Project: ${(isApplication) ? "flutter" : "dart"} ${project_name}");
      return;
    } else {
      yield PackagexApiStatus(
          packagexApiStatusType: PackagexApiStatusType.succes,
          value:
              "Succes Create Project: ${(isApplication) ? "flutter" : "dart"} ${project_name}");
    }
  }

  PackagexPubspec packagexPubspec = PackagexPubspec({});

  Map yaml_code =
      (yaml.loadYaml(file_pubspec.readAsStringSync(), recover: true) as Map);
  packagexPubspec.rawData = yaml_code.clone();
  yield PackagexApiStatus(
      packagexApiStatusType: PackagexApiStatusType.info,
      value:
          "Started Check Pubspec Configuration: ${path.basename(file_pubspec.path)}");

  PackagexPubspec packagexPubspec_default = PackagexPubspec.create(
    dependencies: PackagexPubspecDependencies({
      "packagex": '^0.0.54',
    }),
    dev_dependencies: PackagexPubspecDevDependencies({
      "msix": '^3.16.7',
    }),
    packagex: PackagexConfig.create(
      name: project_name,
      dart_name: project_name,
      flutter_target: "main",
      dart_target: project_name,
      flutter_name: project_name,
      is_without_platform_name: true,
      flutter_commands: PackagexConfigFlutterCommands.create(
        obfuscate: true,
        split_debug_info: "0.0.0",
        build_name: "0.0.0",
        build_number: 1,
        split_per_abi: true,
        no_tree_shake_icons: true,
      ),
      project_id: "azkadev.packagex",
      github_is_org: false,
      github_username: "azkadev",
    ),
    msix_config: PackagexMsixConfig.create(
      display_name: project_name,
      install_certificate: false,
    ),
  );
  yield PackagexApiStatus(
      packagexApiStatusType: PackagexApiStatusType.info,
      value:
          "Update Pubspec Configuration: ${path.basename(file_pubspec.path)}");

  packagexPubspec.rawData.general_lib_utils_updateMapIfNotSameOrEmptyOrNull(
      data: packagexPubspec_default.rawData, ignoreKeys: ["@type"]);
  packagexPubspec.rawData
      .general_lib_utils_removeRecursiveByKeys(keyDatas: ["@type"]);
  yield PackagexApiStatus(
      packagexApiStatusType: PackagexApiStatusType.info,
      value:
          "Remove Pubspec Keys: [\"@type\"] ${path.basename(file_pubspec.path)}");
  await file_pubspec
      .writeAsString(YamlWriter().write(packagexPubspec.toJson()));

  packagexPubspec.packagex.rawData.general_lib_utils_updateMapWithReplace(
      data: packagexConfig.rawData, ignoreKeys: ["@type"]);
  packagexPubspec.rawData
      .general_lib_utils_removeRecursiveByKeys(keyDatas: ["@type"]);
  if (isApplication) {
    if (!packagexPubspec.dev_dependencies.rawData.containsKey("msix")) {
      String message = "Add Package: Msix --dev";
      yield PackagexApiStatus(
          packagexApiStatusType: PackagexApiStatusType.info,
          value: "Starting ${message}");
      Process process = await Process.start(
        "flutter",
        ["pub", "add", "--dev", "msix"],
        workingDirectory: directory_project.parent.uri.toFilePath(),
      );
      process.stderr.listen((event) {
        stderr.add(event);
      });
      process.stdout.listen((event) {
        stdout.add(event);
      });
      int exit_code = await (process.exitCode);
      if (exit_code != 0) {
        yield PackagexApiStatus(
            packagexApiStatusType: PackagexApiStatusType.failed,
            value: "Failed ${message}");
        return;
      } else {
        yield PackagexApiStatus(
            packagexApiStatusType: PackagexApiStatusType.succes,
            value: "Succes ${message}");
      }
    }
  }
  // linux

  String scripts = """
Maintainer: "anonymous@noemail.com>"
Package: ${(packagexPubspec.name ?? project_name).packagex_utils_extension_toLinuxProgram()}
Version: ${packagexPubspec.version}
Section: x11
Priority: optional
Architecture: {{architecture_os}}
Essential: no
Installed-Size: 0
Description: "-"
Homepage: "-"
""";
  scripts = scripts.replaceAllMapped(
      RegExp(r"({{architecture_os}})", caseSensitive: false), (match) {
    if (Platform.isAndroid) {
      return "all";
    } else {
      return "all";
    }
  });
  // create folder
  //
  List<List<String>> packagex_linux_folders = [
    ["DEBIAN"],
    ["usr", "bin"],
    ["usr", "lib"],
    ["usr", "local"],
    ["usr", "local", "bin"],
    ["usr", "local", "lib"],
    ["usr", "share", "applications"],
    ["usr", "share", project_name.packagex_utils_extension_toLinuxProgram()],
  ];
  Directory directory_packagex_linux =
      Directory(path.join(directory_project.path, "linux", "packagex"));
  for (var i = 0; i < packagex_linux_folders.length; i++) {
    Directory directory_procces = Directory(path.join(
        directory_packagex_linux.path,
        path.joinAll(packagex_linux_folders[i])));
    if (directory_procces.existsSync() == false) {
      await directory_procces.create(recursive: true);
    }
  }

  File file_debian_control_packagex_linux =
      File(path.join(directory_packagex_linux.path, "DEBIAN", "control"));
  if (file_debian_control_packagex_linux.parent.existsSync() == false) {
    await file_debian_control_packagex_linux.parent.create(recursive: true);
  }
  if (file_debian_control_packagex_linux.existsSync() == false) {
    await file_debian_control_packagex_linux.writeAsString(scripts);
  }

  File file_debian_postinst_packagex_linux =
      File(path.join(directory_packagex_linux.path, "DEBIAN", "postinst"));
  if (file_debian_postinst_packagex_linux.parent.existsSync() == false) {
    await file_debian_postinst_packagex_linux.parent.create(recursive: true);
  }
  List<String> default_debian_postinsts_packagex_linux = [
    "ln -s /usr/share/${project_name.packagex_utils_extension_toLinuxProgram()}/${project_name} /usr/bin/${project_name.packagex_utils_extension_toLinuxProgram()}-app",
    "chmod +x /usr/bin/${project_name.packagex_utils_extension_toLinuxProgram()}-app",
  ];
  if (file_debian_postinst_packagex_linux.existsSync() == false) {
    await file_debian_postinst_packagex_linux.writeAsString("""
#!/usr/bin/env sh
${default_debian_postinsts_packagex_linux.join("\n")}
exit 0
""");
  } else {
    String origin_data =
        await file_debian_postinst_packagex_linux.readAsString();
    List<String> origin_datas =
        origin_data.split("\n").map((e) => e.trim()).toList();
    origin_datas.removeWhere((element) => element.trim() == "exit 0");
    bool is_found_update = false;
    for (var i = 0; i < default_debian_postinsts_packagex_linux.length; i++) {
      String default_debian_postinst_packagex_linux =
          default_debian_postinsts_packagex_linux[i];
      if (!origin_datas.contains(default_debian_postinst_packagex_linux)) {
        is_found_update = true;
        origin_datas.add(default_debian_postinst_packagex_linux);
      }
    }
    if (origin_datas.contains("#!/usr/bin/env sh") == false) {
      origin_datas.insert(0, "#!/usr/bin/env sh");
    }
    if (origin_datas.contains("exit 0") == false) {
      origin_datas.add("exit 0");
    }

    await file_debian_postinst_packagex_linux
        .writeAsString(origin_datas.join("\n"));
  }

  File file_debian_postrm_packagex_linux =
      File(path.join(directory_packagex_linux.path, "DEBIAN", "postrm"));
  if (file_debian_postrm_packagex_linux.parent.existsSync() == false) {
    await file_debian_postrm_packagex_linux.parent.create(recursive: true);
  }
  List<String> default_debian_postrms_packagex_linux = [
    "rm -rf /usr/bin/${project_name.packagex_utils_extension_toLinuxProgram()}",
    "rm -rf /usr/bin/${project_name.packagex_utils_extension_toLinuxProgram()}-app",
    "rm -rf /usr/local/share/${project_name.packagex_utils_extension_toLinuxProgram()}",
  ];
  if (file_debian_postrm_packagex_linux.existsSync() == false) {
    await file_debian_postrm_packagex_linux.writeAsString("""
#!/usr/bin/env sh
${default_debian_postrms_packagex_linux.join("\n")}
""");
  } else {
    default_debian_postrms_packagex_linux.removeAt(0);
    default_debian_postrms_packagex_linux.removeAt(0);
    String origin_data =
        await file_debian_postrm_packagex_linux.readAsString();
    List<String> origin_datas =
        origin_data.split("\n").map((e) => e.trim()).toList();
    bool is_found_update = false;
    for (var i = 0; i < default_debian_postrms_packagex_linux.length; i++) {
      String default_debian_postrm_packagex_linux =
          default_debian_postrms_packagex_linux[i];
      if (!origin_datas.contains(default_debian_postrm_packagex_linux)) {
        is_found_update = true;
        origin_datas.add(default_debian_postrm_packagex_linux);
      }
    }
    if (origin_datas.contains("#!/usr/bin/env sh") == false) {
      origin_datas.insert(0, "#!/usr/bin/env sh");
    }

    await file_debian_postrm_packagex_linux
        .writeAsString(origin_datas.join("\n"));
  }

  List<String> folder_bins = [
    path.join(directory_packagex_linux.path, "usr", "bin"),
    path.join(directory_packagex_linux.path, "usr", "local", "bin"),
  ];

  for (var i = 0; i < folder_bins.length; i++) {
    String folder_bin = folder_bins[i];

    File file_bin_packagex_linux_gitignore =
        File(path.join(folder_bin, ".gitignore"));
    if (file_bin_packagex_linux_gitignore.parent.existsSync() == false) {
      await file_bin_packagex_linux_gitignore.parent.create(recursive: true);
    }
    await file_bin_packagex_linux_gitignore.writeAsString("""*
!.gitignore"""
        .trim());
  }

  File file_gitignore_packagex_linux =
      File(path.join(directory_packagex_linux.path, ".gitignore"));
  if (file_gitignore_packagex_linux.parent.existsSync() == false) {
    await file_gitignore_packagex_linux.parent.create(recursive: true);
  }

  List<String> default_gitignores_packagex_linux = [
    "usr/bin/${project_name}",
    "usr/share/${project_name}",
    "usr/local/bin/${project_name}",
    "usr/bin/${project_name.packagex_utils_extension_toLinuxProgram()}",
    "usr/share/${project_name.packagex_utils_extension_toLinuxProgram()}",
    "usr/local/bin/${project_name.packagex_utils_extension_toLinuxProgram()}",
    "usr/local/share/${project_name.packagex_utils_extension_toLinuxProgram()}",
  ];
  if (file_gitignore_packagex_linux.existsSync() == false) {
    await file_gitignore_packagex_linux
        .writeAsString(default_gitignores_packagex_linux.join("\n"));
  } else {
    String origin_data = await file_gitignore_packagex_linux.readAsString();
    List<String> origin_datas = origin_data.split("\n");
    bool is_found_update = false;
    for (var i = 0; i < default_gitignores_packagex_linux.length; i++) {
      String default_gitignore_packagex_linux =
          default_gitignores_packagex_linux[i];
      if (!origin_datas.contains(default_gitignore_packagex_linux)) {
        is_found_update = true;
        origin_datas.add(default_gitignore_packagex_linux);
      }
    }
    await file_gitignore_packagex_linux
        .writeAsString(origin_datas.join("\n"));
  }

  String app_desktop_linux = """
[Desktop Entry]
Type=Application
Version=${packagexPubspec.version}
Name=${project_name.split("_").map((e) => e.toUpperCaseFirstData()).join(" ")}
GenericName=General Application
Exec=${project_name.packagex_utils_extension_toLinuxProgram()}-app -- %u
Categories=Music;Media;
Keywords=Hello;World;Test;Application;
StartupNotify=true
""";
  File file_application_packagex_linux = File(path.join(
      directory_packagex_linux.path,
      "usr",
      "share",
      "applications",
      "${project_name}.desktop"));
  if (file_application_packagex_linux.parent.existsSync() == false) {
    await file_application_packagex_linux.parent.create(recursive: true);
  }

  if (file_application_packagex_linux.existsSync() == false) {
    await file_application_packagex_linux.writeAsString(app_desktop_linux);
  }
  if (Platform.isLinux) {
    String message =
        "Set Permission 775: ${file_debian_postinst_packagex_linux.path} ${file_debian_postrm_packagex_linux.path}";
    yield PackagexApiStatus(
        packagexApiStatusType: PackagexApiStatusType.info,
        value: "Starting ${message}");
    Process process = await Process.start(
      "chmod",
      [
        "775",
        file_debian_postinst_packagex_linux.path,
        file_debian_postrm_packagex_linux.path,
      ],
      runInShell: true,
      workingDirectory: directory_project.parent.uri.toFilePath(),
    );
    process.stderr.listen((event) {
      stderr.add(event);
    });
    process.stdout.listen((event) {
      stdout.add(event);
    });
    int exit_code = await (process.exitCode);
    if (exit_code != 0) {
      yield PackagexApiStatus(
          packagexApiStatusType: PackagexApiStatusType.failed,
          value: "Failed ${message}");
      return;
    } else {
      yield PackagexApiStatus(
          packagexApiStatusType: PackagexApiStatusType.succes,
          value: "Succes ${message}");
    }
  }
  yield PackagexApiStatus(
      packagexApiStatusType: PackagexApiStatusType.info,
      value: "Finished Create Project: ${project_name}");
}