diff --git a/.mise.toml b/.mise.toml index 3e1eebc..9ccb620 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,2 +1,2 @@ [tools] -tuist = "4.18.0" \ No newline at end of file +tuist = "4.21.1" \ No newline at end of file diff --git a/DependencyGraph/graphMaker.sh b/DependencyGraph/graphMaker.sh index 36562b3..0eb333f 100644 --- a/DependencyGraph/graphMaker.sh +++ b/DependencyGraph/graphMaker.sh @@ -1,6 +1,12 @@ -tuist graph PomoNyang -d -t -f dot -sed -i '' '/Example/d; /ThirdParty_/d' graph.dot -dot -Tpng graph.dot -o DependencyGraph/pomonyang_graph.png +TUIST_BUILD_CONFIG=prod tuist graph PomoNyang -d -t -f dot +sed -i '' '/ThirdParty_/d' graph.dot +dot -Tpng graph.dot -o DependencyGraph/pomonyang_prod_graph.png rm graph.dot -open DependencyGraph/pomonyang_graph.png +TUIST_BUILD_CONFIG=dev tuist graph -d -f dot +sed -i '' '/ThirdParty_/d' graph.dot +dot -Tpng graph.dot -o DependencyGraph/pomonyang_dev_graph.png +rm graph.dot + +open DependencyGraph/pomonyang_dev_graph.png +open DependencyGraph/pomonyang_prod_graph.png diff --git a/DependencyGraph/pomonyang_dev_graph.png b/DependencyGraph/pomonyang_dev_graph.png new file mode 100644 index 0000000..a0b6847 Binary files /dev/null and b/DependencyGraph/pomonyang_dev_graph.png differ diff --git a/DependencyGraph/pomonyang_graph.png b/DependencyGraph/pomonyang_prod_graph.png similarity index 100% rename from DependencyGraph/pomonyang_graph.png rename to DependencyGraph/pomonyang_prod_graph.png diff --git a/Makefile b/Makefile index f8fa7d3..01c3f48 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,9 @@ ### Tuist ### +.PHONY: manifests +manifests: + tuist edit + .PHONY: install install: carthage update --platform iOS --use-xcframeworks --use-netrc --cache-builds --verbose --project-directory "XCFramework/" @@ -17,7 +21,7 @@ cache: module: tuist scaffold Framework --layer ${layer} --name ${name} -.PHONY: cleanj +.PHONY: clean clean: tuist clean rm -rf XCFramework/Carthage @@ -27,9 +31,14 @@ clean: ### SUGAR ### -.PHONY: pomonyang -pomonyang: - make generate config=${config} target="PomoNyang" +.PHONY: dev +dev: + make generate config=dev + +.PHONY: prod +prod: + make generate config=prod + ### Script ### diff --git a/Package.swift b/Package.swift index 4045470..d06827f 100644 --- a/Package.swift +++ b/Package.swift @@ -7,7 +7,6 @@ import ProjectDescriptionHelpers let packageSettings: PackageSettings = .init( productTypes: [ - "Moya": .framework, "KakaoSDKCommon": .framework, "KakaoSDKAuth": .framework, // "KakaoSDKUser": .framework, @@ -25,7 +24,6 @@ let package: Package = .init( platforms: [.iOS(.v17)], dependencies: [ .package(url: "https://github.com/pointfreeco/swift-composable-architecture.git", exact: "1.11.2"), - .package(url: "https://github.com/kakao/kakao-ios-sdk.git", exact: "2.22.0"), - .package(url: "https://github.com/Moya/Moya.git", exact: "15.0.3") + .package(url: "https://github.com/kakao/kakao-ios-sdk.git", exact: "2.22.0") ] ) diff --git a/Plugins/DependencyPlugin/ProjectDescriptionHelpers/DEP+SPMTarget.swift b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/DEP+SPMTarget.swift index dec3885..495e27b 100644 --- a/Plugins/DependencyPlugin/ProjectDescriptionHelpers/DEP+SPMTarget.swift +++ b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/DEP+SPMTarget.swift @@ -25,7 +25,4 @@ public extension DEP.SPMTarget { static let KakaoSDKNavi: TargetDependency = .external(name: "KakaoSDKNavi") static let KakaoSDKTemplate: TargetDependency = .external(name: "KakaoSDKTemplate") static let KakaoAdSDK: TargetDependency = .external(name: "KakaoAdSDK") - - // MARK: - Moya - static let Moya: TargetDependency = .external(name: "Moya") } diff --git a/Plugins/DependencyPlugin/ProjectDescriptionHelpers/TargetDependency+Modulable.swift b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/TargetDependency+Modulable.swift index b5f7c3b..a60eebb 100644 --- a/Plugins/DependencyPlugin/ProjectDescriptionHelpers/TargetDependency+Modulable.swift +++ b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/TargetDependency+Modulable.swift @@ -16,14 +16,14 @@ extension TargetDependency { /// ex) path: "Projects/Core/Logger", target: "LoggerInterface" public static func dependency(module: T, target: TargetType = .sources) -> TargetDependency { let moduleName = String(describing: module) - return .project(target: "\(moduleName)\(target.postfixName)", path: .relativeToRoot("Projects/\(module.path)")) + return .project(target: "\(moduleName)\(target.suffixName)", path: .relativeToRoot("Projects/\(module.path)")) } public enum TargetType: Hashable { case sources case interface - public var postfixName: String { + public var suffixName: String { switch self { case .sources: return "" diff --git a/Projects/Core/APIClient/Project.swift b/Projects/Core/APIClient/Project.swift index 3689b21..0951bc6 100644 --- a/Projects/Core/APIClient/Project.swift +++ b/Projects/Core/APIClient/Project.swift @@ -8,7 +8,7 @@ let project: Project = .project( module: PomoNyang.Core.APIClient, scripts: [], targets: [ - .sources(.staticLibrary), + .sources, .interface, .tests, .testing diff --git a/Projects/Domain/AppService/Project.swift b/Projects/Domain/AppService/Project.swift index 5b95ecd..9ef7447 100644 --- a/Projects/Domain/AppService/Project.swift +++ b/Projects/Domain/AppService/Project.swift @@ -8,7 +8,7 @@ let project: Project = .project( module: PomoNyang.Domain.AppService, scripts: [], targets: [ - .sources(.staticLibrary), + .sources, .interface, .tests, .testing diff --git a/Projects/Domain/Model/Project.swift b/Projects/Domain/Model/Project.swift index 0e965d8..84d5340 100644 --- a/Projects/Domain/Model/Project.swift +++ b/Projects/Domain/Model/Project.swift @@ -8,7 +8,7 @@ let project: Project = .project( module: PomoNyang.Domain.Model, scripts: [], targets: [ - .sources(.staticLibrary), + .sources, .interface, .tests, .testing diff --git a/Projects/Feature/AppFeature/Project.swift b/Projects/Feature/AppFeature/Project.swift index 05cb7c5..94e7fe7 100644 --- a/Projects/Feature/AppFeature/Project.swift +++ b/Projects/Feature/AppFeature/Project.swift @@ -8,7 +8,7 @@ let project: Project = .project( module: PomoNyang.Feature.AppFeature, scripts: [], targets: [ - .sources(.staticLibrary), + .sources, .interface, .tests, .testing diff --git a/Projects/Shared/DesignSystem/Project.swift b/Projects/Shared/DesignSystem/Project.swift index 1a1f6fe..2719721 100644 --- a/Projects/Shared/DesignSystem/Project.swift +++ b/Projects/Shared/DesignSystem/Project.swift @@ -6,9 +6,10 @@ import DependencyPlugin let project: Project = .project( module: PomoNyang.Shared.DesignSystem, + includeResource: true, scripts: [], targets: [ - .sources(.staticFramework), + .sources, .interface, .tests, .testing diff --git a/Projects/Shared/Utils/Project.swift b/Projects/Shared/Utils/Project.swift index bd903d3..d4fed33 100644 --- a/Projects/Shared/Utils/Project.swift +++ b/Projects/Shared/Utils/Project.swift @@ -8,7 +8,7 @@ let project: Project = .project( module: PomoNyang.Shared.Utils, scripts: [], targets: [ - .sources(.staticLibrary), + .sources, .interface, .tests, .testing diff --git a/README.md b/README.md index b8be287..d01bf25 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,14 @@ - ```mise install tuist``` (프로젝트 루트 경로에서) ### 프로젝트 생성 -- 뽀모냥 앱 프로젝트 생성 - - ```make pomonyang``` -- conifg={configuration} 붙여서 빌드 환경 변경 (dev, prod) - - 예시: ```make pomonyang config=dev``` +- 개발환경 생성 + - ```make dev``` +- 운영환경 생성 + - ```make prod``` ### Tuist +- Manifests 생성 + - ```make manifests``` - 외부 라이브러리 구성 - ```make install``` - 프로젝트 변경 사항 반영 및 열기 (target: 타겟명) @@ -31,5 +33,8 @@ - Xcode 파일 생성 템플릿 추가 - ```make template``` -### 의존성 그래프 (테스트, 데모, 외부의존성 제외) - ![PomoNyang](DependencyGraph/pomonyang_graph.png) \ No newline at end of file +### 의존성 그래프 (외부의존성 제외) +- 운영 환경 +![PomoNyang](DependencyGraph/pomonyang_prod_graph.png) +- 개발 환경 +![PomoNyang](DependencyGraph/pomonyang_dev_graph.png) \ No newline at end of file diff --git a/Tuist/ProjectDescriptionHelpers/Templates/Product+Extension.swift b/Tuist/ProjectDescriptionHelpers/Templates/Product+Extension.swift deleted file mode 100644 index d5dfbac..0000000 --- a/Tuist/ProjectDescriptionHelpers/Templates/Product+Extension.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// Product+Extension.swift -// ProjectDescriptionHelpers -// -// Created by MinseokKang on 2024/07/15. -// - -import ProjectDescription - -extension Product { - var isResourceRequired: Bool { - switch self { - case .app, - .framework, - .staticFramework, - .bundle, - .unitTests, - .uiTests, - .appClip, - .appExtension, - .watch2App, - .watch2Extension, - .tvTopShelfExtension, - .messagesExtension, - .stickerPackExtension: - return true - - case .staticLibrary, - .dynamicLibrary, - .commandLineTool, - .xpc, - .systemExtension, - .extensionKitExtension, - .macro: - return false - - @unknown default: - fatalError("\(self.rawValue) is not handled!") - } - } -} diff --git a/Tuist/ProjectDescriptionHelpers/Templates/Project+Extension.swift b/Tuist/ProjectDescriptionHelpers/Templates/Project+Extension.swift index c16fb97..dc633fb 100644 --- a/Tuist/ProjectDescriptionHelpers/Templates/Project+Extension.swift +++ b/Tuist/ProjectDescriptionHelpers/Templates/Project+Extension.swift @@ -15,9 +15,9 @@ extension Project { options: Project.Options = .options(disableSynthesizedResourceAccessors: true), packages: [Package] = [], infoPlist: InfoPlist = .default, - includeResource: Bool? = nil, + includeResource: Bool = false, scripts: [TargetScript], - targets: Set, // [.sources(.staticLibrary), .interface, .tests, .testing, .example], + targets: Set, // [.sources, .interface, .tests, .testing, .example], dependencies: [TargetDependency], schemes: [Scheme] = [], resourceSynthesizers: [ResourceSynthesizer] = [] @@ -25,96 +25,84 @@ extension Project { let name = String(describing: module) var projectTargets: [Target] = [] targets.forEach { targetType in - let targetName = "\(name)\(targetType.postfixName)" + let targetName = "\(name)\(targetType.suffixName)" switch targetType { - case .sources(let machOType): - let resources: ResourceFileElements? = if let includeResource { - includeResource ? ["Resources/**"] : nil - } else { - machOType.isResourceRequired ? ["Resources/**"] : nil - } - let target: Target = .target( - name: targetName, - product: machOType, - infoPlist: infoPlist, - sources: ["Sources/**/*.swift"], - resources: resources, - scripts: scripts, - dependencies: [ - targets.contains(.interface) ? [.target(name: "\(name)Interface")] : [], - dependencies - ].flatMap { $0 } - ) - projectTargets.append(target) - - case .interface: - let target: Target = .target( - name: targetName, - product: .staticLibrary, - infoPlist: infoPlist, - sources: ["Interface/**/*.swift"], - resources: nil, - scripts: [], - dependencies: [] - ) - projectTargets.append(target) - - case .tests: - let target: Target = .target( - name: targetName, - product: .unitTests, - infoPlist: infoPlist, - sources: ["Tests/**/*.swift"], - resources: nil, - scripts: [], - dependencies: [ - [.target(name: "\(name)")], // sources 의존성 연결 - targets.contains(.testing) ? [.target(name: "\(name)Testing")] : [] - ].flatMap { $0 } - ) - projectTargets.append(target) - - case .testing: - let target: Target = .target( - name: targetName, - product: .framework, - infoPlist: infoPlist, - sources: ["Testing/**/*.swift"], - resources: nil, - scripts: [], - dependencies: targets.contains(.interface) ? [.target(name: "\(name)Interface")] : [] - ) - projectTargets.append(target) - - case .example: - let target: Target = .target( - name: targetName, - product: .app, - infoPlist: InfoPlist.Example.app(name: targetName), - sources: ["Example/Sources/**/*.swift"], - resources: ["Example/Resources/**"], - scripts: [.reveal(target: .dev)], - dependencies: [ - [.target(name: "\(name)")], // sources 의존성 연결 - targets.contains(.testing) ? [.target(name: "\(name)Testing")] : [] - ].flatMap { $0 } - ) - projectTargets.append(target) - - case .preview: - let target: Target = .target( - name: targetName, - product: .framework, - infoPlist: infoPlist, - sources: ["Preview/Sources/**/*.swift"], - resources: ["Preview/Resources/**"], - scripts: [], - dependencies: [ - .target(name: "\(name)") // sources 의존성 연결 - ] - ) - projectTargets.append(target) + case .sources: + let product: Product = if includeResource { + currentConfig == .dev ? .framework : .staticFramework + } else { + currentConfig == .dev ? .framework : .staticLibrary + } + let resources: ResourceFileElements? = includeResource ? ["Resources/**"] : nil + let target: Target = .target( + name: targetName, + product: product, + infoPlist: infoPlist, + sources: ["Sources/**/*.swift"], + resources: resources, + scripts: scripts, + dependencies: [ + targets.contains(.interface) ? [.target(name: "\(name)Interface")] : [], + dependencies + ].flatMap { $0 } + ) + projectTargets.append(target) + + case .interface: + let product: Product = currentConfig == .dev ? .framework : .staticLibrary + let target: Target = .target( + name: targetName, + product: product, + infoPlist: infoPlist, + sources: ["Interface/**/*.swift"], + resources: nil, + scripts: [], + dependencies: [] + ) + projectTargets.append(target) + + case .tests: + let target: Target = .target( + name: targetName, + product: .unitTests, + infoPlist: infoPlist, + sources: ["Tests/**/*.swift"], + resources: nil, + scripts: [], + dependencies: [ + [.target(name: "\(name)")], // sources 의존성 연결 + targets.contains(.testing) ? [.target(name: "\(name)Testing")] : [] + ].flatMap { $0 } + ) + projectTargets.append(target) + + case .testing: + let target: Target = .target( + name: targetName, + product: .framework, + infoPlist: infoPlist, + sources: ["Testing/**/*.swift"], + resources: nil, + scripts: [], + dependencies: targets.contains(.interface) ? [.target(name: "\(name)Interface")] : [] + ) + projectTargets.append(target) + + case .example: + let target: Target = .target( + name: targetName, + product: .app, + infoPlist: InfoPlist.Example.app(name: targetName), + sources: ["Example/Sources/**/*.swift"], + resources: ["Example/Resources/**"], + scripts: [.reveal(target: .dev)], + dependencies: [ + [.target(name: "\(name)")], // sources 의존성 연결 + targets.contains(.testing) ? [.target(name: "\(name)Testing")] : [] + ].flatMap { $0 } + ) + projectTargets.append(target) } } @@ -134,10 +122,10 @@ extension Project { } extension Project { - /// based on µFeatures Architecture + Preview + /// based on µFeatures Architecture public enum TargetType: Hashable { /// Feature 소스코드 타겟 - case sources(Product) + case sources /// Feature 소스코드의 인터페이스 case interface /// 테스트를 위한 타겟 @@ -146,41 +134,19 @@ extension Project { case testing /// 데모앱을 위한 타겟 case example - /// Xcode Preview를 위한 타겟 - case preview - public var postfixName: String { + public var suffixName: String { switch self { - case .sources: - return "" - case .interface: - return "Interface" - case .tests: - return "Tests" - case .testing: - return "Testing" - case .example: - return "Example" - case .preview: - return "Preview" - } - } - - // associated value 상관없이 case로 hash하면 됨 - public func hash(into hasher: inout Hasher) { - switch self { - case .sources: - hasher.combine(0) - case .interface: - hasher.combine(1) - case .tests: - hasher.combine(2) - case .testing: - hasher.combine(3) - case .example: - hasher.combine(4) - case .preview: - hasher.combine(5) + case .sources: + return "" + case .interface: + return "Interface" + case .tests: + return "Tests" + case .testing: + return "Testing" + case .example: + return "Example" } } }