From 550ece1c947d9b2df98abf5f45777eab82071d7d Mon Sep 17 00:00:00 2001 From: leedongmyung Date: Mon, 26 May 2025 14:26:38 +0900 Subject: [PATCH] =?UTF-8?q?xcode=20file=20add=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/oto/commands/build/xcodeproj.dart | 57 +++++++++++++++++++++++++++ lib/oto/commands/command.dart | 3 ++ lib/oto/commands/util/json.dart | 18 +++++---- lib/oto/data/command_data.dart | 17 +++++++- lib/oto/data/command_data.g.dart | 28 +++++++++++++ pubspec.yaml | 2 +- 6 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 lib/oto/commands/build/xcodeproj.dart diff --git a/lib/oto/commands/build/xcodeproj.dart b/lib/oto/commands/build/xcodeproj.dart new file mode 100644 index 0000000..b7154a6 --- /dev/null +++ b/lib/oto/commands/build/xcodeproj.dart @@ -0,0 +1,57 @@ +import 'dart:io'; + +import 'package:dart_framework/platform/process.dart'; +import 'package:oto_cli/oto/application.dart'; +import 'package:oto_cli/oto/commands/command.dart'; +import 'package:oto_cli/oto/data/command_data.dart'; + +class XcodeprojAddFile extends Command { + Function? get error => null; + String rubyCode = ''' +# add_file_xcodeproj.rb +# encoding: UTF-8 +require 'xcodeproj' + +project = Xcodeproj::Project.open('{XCODEPROJ_PATH}') +target = project.targets.find { |t| t.name == '{TARGET}' } +group = project.main_group +file_ref = group.new_file('{ADD_FILE_PATH}') + +# ๐Ÿ“Œ ํƒ€๊ฒŸ์— ํŒŒ์ผ ํฌํ•จ +build_file = target.add_file_references([file_ref]).first + +# ๐Ÿ“Œ Copy Bundle Resources์— ๋ช…์‹œ์ ์œผ๋กœ ์ถ”๊ฐ€ +target.resources_build_phase.add_file_reference(file_ref) + +project.save + +puts "โœ… {ADD_FILE_PATH} ํŒŒ์ผ์ด ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€๋˜๊ณ , Copy Bundle Resources์— ํฌํ•จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค." +'''; + + /* + * sudo gem install xcodeproj + */ + + @override + Future execute(DataCommand command) async { + var data = DataXcodeprojAddFile.fromJson(getParam(command)); + var template = rubyCode + .replaceAll('{TARGET}', data.target) + .replaceAll('{ADD_FILE_PATH}', data.addFilePath) + .replaceAll('{XCODEPROJ_PATH}', data.xcodeprojPath); + + var file = File('${data.workspace}/add_file_xcodeproj.rb'); + file.writeAsStringSync(template, flush: true); + + var shell = StringBuffer(); + shell.write('export LANG=en_US.UTF-8 && cd ${data.workspace}'); + shell.write(' && ruby add_file_xcodeproj.rb'); + + var process = await ProcessExecutor.start(shell, + workspace: workspace, + printStderr: true, + logHandler: Application.logWithType); + + return await completeProcess(process, command); + } +} diff --git a/lib/oto/commands/command.dart b/lib/oto/commands/command.dart index 3404fcb..5e3425f 100644 --- a/lib/oto/commands/command.dart +++ b/lib/oto/commands/command.dart @@ -14,6 +14,7 @@ import 'package:oto_cli/oto/commands/build/build_flutter.dart'; import 'package:oto_cli/oto/commands/build/build_ios.dart'; import 'package:oto_cli/oto/commands/build/build_msbuild.dart'; import 'package:oto_cli/oto/commands/build/testflight_ios.dart'; +import 'package:oto_cli/oto/commands/build/xcodeproj.dart'; import 'package:oto_cli/oto/commands/file/directory.dart'; import 'package:oto_cli/oto/commands/file/file.dart'; import 'package:oto_cli/oto/commands/file/file_diff_check.dart'; @@ -58,6 +59,7 @@ enum CommandType { TestflightUpload, TestflightStatusCheck, TestflightDistribute, + XcodeprojAddFile, BuildMSBuild, CodeSign, CodeSignVerify, @@ -131,6 +133,7 @@ abstract class Command { CommandType.TestflightUpload: () => TestflightUpload(), CommandType.TestflightStatusCheck: () => TestflightStatusCheck(), CommandType.TestflightDistribute: () => TestflightDistribute(), + CommandType.XcodeprojAddFile: () => XcodeprojAddFile(), CommandType.BuildMSBuild: () => BuildMSBuild(), CommandType.CodeSign: () => CodeSign(), CommandType.CodeSignVerify: () => CodeSignVerify(), diff --git a/lib/oto/commands/util/json.dart b/lib/oto/commands/util/json.dart index eec3924..d1b03ff 100644 --- a/lib/oto/commands/util/json.dart +++ b/lib/oto/commands/util/json.dart @@ -18,23 +18,23 @@ class JsonBase extends Command { var keys = item.from.split('.'); for (var i = 0; i < keys.length; ++i) { var key = keys[i]; - if(arrReg.hasMatch(key)) { + if (arrReg.hasMatch(key)) { //array case var match = arrReg.firstMatch(key); - if(match != null && match.groupCount != 0) { + if (match != null && match.groupCount != 0) { print(match.groupCount); var arrKey = match.group(1); var arrIndex = int.parse(match.group(2)!); if (temp.containsKey(arrKey)) { var arr = temp[arrKey] as List; - if(arr.length > arrIndex) { + if (arr.length > arrIndex) { var value = arr[arrIndex]; if (i == keys.length - 1) { await setProperty(item.setValue, value.toString()); break; } else { temp = value; - } + } } else { throw Exception('Out of range: "$key" in $item'); } @@ -56,8 +56,6 @@ class JsonBase extends Command { throw Exception('Not exist key: "$key" in $item'); } } - - } } } on Exception catch (e) { @@ -114,11 +112,17 @@ class JsonWriterFile extends Command { temp = temp[keys[i]]; } } else { - throw Exception('Not exist key: "$key" in $item'); + if (i == keys.length - 1) { + temp[keys[i]] = item.value; + } else { + temp[keys[i]] = {}; + temp = temp[keys[i]]; + } } } } content = jsonPrettyEncode(json); + print(content); file.writeAsStringSync(content, flush: true); } on Exception catch (e) { throw Exception('Json parsing error: $e'); diff --git a/lib/oto/data/command_data.dart b/lib/oto/data/command_data.dart index cca6e04..97437ef 100644 --- a/lib/oto/data/command_data.dart +++ b/lib/oto/data/command_data.dart @@ -364,7 +364,6 @@ class DataTestflightStatusCheck extends DataParam { Map toJson() => _$DataTestflightStatusCheckToJson(this); } - //TestflightUpload @JsonSerializable() class DataTestflightDistribute extends DataParam { @@ -402,6 +401,21 @@ class DataPublishiOS extends DataParam { Map toJson() => _$DataPublishiOSToJson(this); } +//DataXcodeprojAddFile +@JsonSerializable() +class DataXcodeprojAddFile extends DataParam { + DataXcodeprojAddFile(); + + late String addFilePath; + late String target; + late String xcodeprojPath; + + factory DataXcodeprojAddFile.fromJson(Map json) => + _$DataXcodeprojAddFileFromJson(json); + @override + Map toJson() => _$DataXcodeprojAddFileToJson(this); +} + //FTP @JsonSerializable() class DataFTP extends DataParam { @@ -1184,4 +1198,3 @@ class DataDelay extends DataParam { @override Map toJson() => _$DataDelayToJson(this); } - diff --git a/lib/oto/data/command_data.g.dart b/lib/oto/data/command_data.g.dart index c389dcd..74f32af 100644 --- a/lib/oto/data/command_data.g.dart +++ b/lib/oto/data/command_data.g.dart @@ -65,6 +65,7 @@ const _$CommandTypeEnumMap = { CommandType.TestflightUpload: 'TestflightUpload', CommandType.TestflightStatusCheck: 'TestflightStatusCheck', CommandType.TestflightDistribute: 'TestflightDistribute', + CommandType.XcodeprojAddFile: 'XcodeprojAddFile', CommandType.BuildMSBuild: 'BuildMSBuild', CommandType.CodeSign: 'CodeSign', CommandType.CodeSignVerify: 'CodeSignVerify', @@ -719,6 +720,33 @@ Map _$DataPublishiOSToJson(DataPublishiOS instance) => 'destinationPath': instance.destinationPath, }; +DataXcodeprojAddFile _$DataXcodeprojAddFileFromJson( + Map json) => + DataXcodeprojAddFile() + ..workspace = json['workspace'] as String? + ..passExitCodes = (json['passExitCodes'] as List?) + ?.map((e) => (e as num).toInt()) + .toList() + ..setResult = json['setResult'] as String? + ..setExitCode = json['setExitCode'] as String? + ..showPrint = json['showPrint'] as bool? + ..addFilePath = json['addFilePath'] as String + ..target = json['target'] as String + ..xcodeprojPath = json['xcodeprojPath'] as String; + +Map _$DataXcodeprojAddFileToJson( + DataXcodeprojAddFile instance) => + { + 'workspace': instance.workspace, + 'passExitCodes': instance.passExitCodes, + 'setResult': instance.setResult, + 'setExitCode': instance.setExitCode, + 'showPrint': instance.showPrint, + 'addFilePath': instance.addFilePath, + 'target': instance.target, + 'xcodeprojPath': instance.xcodeprojPath, + }; + DataFTP _$DataFTPFromJson(Map json) => DataFTP() ..workspace = json['workspace'] as String? ..passExitCodes = (json['passExitCodes'] as List?) diff --git a/pubspec.yaml b/pubspec.yaml index e3132a9..3f8b6ce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: xml: ^6.3.0 dev_dependencies: - lints: ^5.0.0 + lints: ^6.0.0 test: ^1.24.9 build_runner: ^2.1.4 json_serializable: ^6.0.1