run method
Runs the command to create a job and update the config file.
Implementation
@override
Future<void> run() async {
String configPath = globalResults?["config"] ?? "distribution.yaml";
final file = File(configPath);
if (!file.existsSync()) {
logger.logError("Configuration file not found: $configPath");
return;
}
var configJson = _loadYamlAsJson(file);
final Variables variables = Variables(
configJson["variables"],
globalResults,
);
var tasks = configJson["tasks"] ?? [];
String? taskKey;
String? jobKey;
String? jobName;
String? packageName;
String? description;
String? appId;
bool isWizard = argResults?["wizard"] ?? false;
if (isWizard) {
logger.logInfo("Starting job creation wizard...");
logger.logInfo("Available tasks:");
for (var task in tasks) {
logger.logInfo("${task["key"]} (${task["name"]})");
for (var job in task["jobs"] ?? []) {
logger.logInfo(" | ${job["key"]} - ${job["name"]}");
}
}
logger.logEmpty();
logger.logInfo("Please provide the following details:");
taskKey = await prompt("Enter task key");
if (tasks.indexWhere((task) => task["key"] == taskKey) == -1) {
logger.logError("Task with key $taskKey not found.");
return;
}
jobKey = await prompt("Enter job key");
jobName = await prompt("Enter job name");
description = await prompt("Enter job description", nullable: true);
packageName =
BuildInfo.androidPackageName ?? await prompt("Enter package name");
} else {
taskKey = argResults?["task-key"];
jobKey = argResults?["key"];
jobName = argResults?["name"];
packageName = argResults?["package-name"];
description = argResults?["description"];
}
taskKey = await variables.process(taskKey ?? "");
jobKey = await variables.process(jobKey ?? "");
jobName = await variables.process(jobName ?? "");
description = await variables.process(description ?? "");
packageName = await variables.process(packageName ?? "\${ANDROID_PACKAGE}");
final googleServiceFile = File(
path.join("android", "app", "google-services.json"),
);
if (googleServiceFile.existsSync()) {
final googleService = jsonDecode(googleServiceFile.readAsStringSync());
final List clients = googleService["client"];
final client = clients.firstWhere(
(client) =>
client["client_info"]["android_client_info"]["package_name"] ==
packageName,
orElse: () => {},
);
if (client.isNotEmpty) {
appId = client["client_info"]["mobilesdk_app_id"];
} else {
logger.logWarning(
"No Android client found in google-services.json. Please provide package name manually.",
);
}
}
if ((taskKey.isEmpty) ||
(jobKey.isEmpty) ||
(jobName.isEmpty) ||
(packageName.isEmpty)) {
logger.logError(
"`task-key`, `key`, `package_name`, and `name` are mandatory.",
);
return;
}
final taskIndex = tasks.indexWhere((task) => task["key"] == taskKey);
if (taskIndex == -1) {
logger.logError("Task with key $taskKey not found.");
return;
}
var task = tasks[taskIndex];
var jobs = task["jobs"] ?? [];
if (jobs.any((job) => job["key"] == jobKey)) {
logger.logError("Job with key $jobKey already exists.");
return;
}
BuilderJob? builderJob;
if (this is CreateBuilderCommand) {
List<String> platforms = <String>[];
if (isWizard) {
if (Platform.isMacOS) {
final input = await prompt(
"Enter platforms (android, ios)",
nullable: true,
);
if (input.isNotEmpty) {
platforms = input
.split(",")
.map((platform) => platform.trim())
.toList();
}
} else {
platforms.add("android");
}
} else if (argResults!["platform"] != null) {
platforms = (argResults!["platform"] as List<String>).toList();
}
builderJob = BuilderJob(
android: platforms.contains("android") == true
? android_arguments.Arguments.defaultConfigs(globalResults)
: null,
ios: platforms.contains("ios") == true
? ios_arguments.Arguments.defaultConfigs(globalResults)
: null,
);
} else {
builderJob = null;
}
PublisherJob? publisherJob;
if (this is CreatePublisherCommand) {
List<String> tools = <String>[];
if (isWizard) {
logger.logInfo("Available tools for publisher job:");
logger.logInfo("- firebase: Publish to Firebase App Distribution.");
logger.logInfo("- fastlane: Publish using Fastlane.");
if (Platform.isMacOS) {
logger.logInfo("- xcrun: Publish using Xcode command line tools.");
}
logger.logInfo("- github: Publish to GitHub.");
logger.logEmpty();
logger.logInfo(
"Please select the tools you want to use (comma-separated):",
);
final input = stdin.readLineSync();
if (input != null && input.isNotEmpty) {
tools = input.split(",").map((tool) => tool.trim()).toList();
}
} else if (argResults!["tools"] != null) {
tools = (argResults!["tools"] as List<String>).toList();
}
publisherJob = PublisherJob(
fastlane: tools.contains("fastlane") == true
? fastlane_publisher.Arguments.defaultConfigs(
packageName,
globalResults,
)
: null,
firebase: tools.contains("firebase") == true
? firebase_publisher.Arguments.defaultConfigs(
appId ?? "APP_ID",
globalResults,
)
: null,
xcrun: Platform.isMacOS
? tools.contains("xcrun") == true
? xcrun_publisher.Arguments.defaultConfigs(globalResults)
: null
: null,
github: tools.contains("github") == true
? github_publisher.Arguments.defaultConfigs(globalResults)
: null,
);
} else {
publisherJob = null;
}
if (builderJob == null && publisherJob == null) {
logger.logError("Invalid job type. Use 'builder' or 'publisher'.");
return;
}
jobs.add(
Job(
name: jobName,
key: jobKey,
description: description,
packageName: packageName,
builder: builderJob,
publisher: publisherJob,
).toJson(),
);
tasks[taskIndex]["jobs"] = jobs;
configJson["tasks"] = tasks;
await _writeYaml(file, configJson);
logger.logSuccess("Job created successfully: $jobName");
}