diff --git a/DependencyGraphs/AllGraph.png b/DependencyGraphs/AllGraph.png
index afc8a144f..89d5fa3e9 100644
Binary files a/DependencyGraphs/AllGraph.png and b/DependencyGraphs/AllGraph.png differ
diff --git a/DependencyGraphs/AppGraph.png b/DependencyGraphs/AppGraph.png
index e7401c647..787fa2e58 100644
Binary files a/DependencyGraphs/AppGraph.png and b/DependencyGraphs/AppGraph.png differ
diff --git a/DependencyGraphs/TestGraph.png b/DependencyGraphs/TestGraph.png
index f48a89ae8..6d0269e7d 100644
Binary files a/DependencyGraphs/TestGraph.png and b/DependencyGraphs/TestGraph.png differ
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/.swiftlint.yml b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/.swiftlint.yml
new file mode 100644
index 000000000..e8820dc9e
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/.swiftlint.yml
@@ -0,0 +1,12 @@
+disabled_rules:
+- trailing_whitespace
+- identifier_name
+- type_name
+- force_cast
+- shorthand_operator
+- line_length
+
+excluded:
+- Sources/Application/AppDelegate.swift
+- Sources/Application/SceneDelegate.swift
+- "Tuist"
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Project.swift b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Project.swift
new file mode 100644
index 000000000..90dee2a63
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Project.swift
@@ -0,0 +1,22 @@
+//
+// Project.swift
+// ProjectDescriptionHelpers
+//
+// Created by sejin on 2022/10/02.
+//
+
+import ProjectDescription
+import ProjectDescriptionHelpers
+import UtilityPlugin
+
+let project = Project.makeModule(
+ name: "SOPT-Stamp-Demo",
+ platform: .iOS,
+ product: .app,
+ dependencies: [
+ .Project.Data,
+ .Project.Presentation
+ ],
+ resources: ["Resources/**"],
+ infoPlist: .extendingDefault(with: Project.baseinfoPlist)
+)
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 000000000..eb8789700
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 000000000..13613e3ee
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,13 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/Contents.json b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/Contents.json
new file mode 100644
index 000000000..73c00596a
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Launch Screen.storyboard b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Launch Screen.storyboard
new file mode 100644
index 000000000..52cfadaf1
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Resources/Launch Screen.storyboard
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/Application/AppDelegate.swift b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/Application/AppDelegate.swift
new file mode 100644
index 000000000..339200923
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/Application/AppDelegate.swift
@@ -0,0 +1,32 @@
+//
+// AppDelegate.swift
+// ProjectDescriptionHelpers
+//
+// Created by 양수빈 on 2022/10/01.
+//
+
+import UIKit
+
+import Core
+
+@main
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+
+ return true
+ }
+
+ // MARK: UISceneSession Lifecycle
+
+ func application( _ application: UIApplication,
+ configurationForConnecting connectingSceneSession: UISceneSession,
+ options: UIScene.ConnectionOptions
+ ) -> UISceneConfiguration {
+ return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
+ }
+
+ func application( _ application: UIApplication,
+ didDiscardSceneSessions sceneSessions: Set
+ ) {}
+}
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/Application/SceneDelegate.swift b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/Application/SceneDelegate.swift
new file mode 100644
index 000000000..637f600b6
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/Application/SceneDelegate.swift
@@ -0,0 +1,39 @@
+//
+// SceneDelegate.swift
+// ProjectDescriptionHelpers
+//
+// Created by 양수빈 on 2022/10/01.
+//
+
+import UIKit
+
+import Presentation
+
+class SceneDelegate: UIResponder, UIWindowSceneDelegate {
+
+ var window: UIWindow?
+
+ func scene(_ scene: UIScene,
+ willConnectTo session: UISceneSession,
+ options connectionOptions: UIScene.ConnectionOptions) {
+ guard let scene = (scene as? UIWindowScene) else { return }
+
+ window = UIWindow(frame: scene.coordinateSpace.bounds)
+ window?.windowScene = scene
+ let vc = TestVC()
+ window?.rootViewController = UINavigationController(rootViewController: vc)
+ window?.makeKeyAndVisible()
+ }
+
+ func sceneDidDisconnect(_ scene: UIScene) {}
+
+ func sceneDidBecomeActive(_ scene: UIScene) {
+ UIApplication.shared.applicationIconBadgeNumber = 0
+ }
+
+ func sceneWillResignActive(_ scene: UIScene) {}
+
+ func sceneWillEnterForeground(_ scene: UIScene) {}
+
+ func sceneDidEnterBackground(_ scene: UIScene) {}
+}
diff --git a/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/ModuleFactory/ModuleFactory.swift b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/ModuleFactory/ModuleFactory.swift
new file mode 100644
index 000000000..8e0096fcb
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Demo/SOPT-Stamp-Demo/Sources/ModuleFactory/ModuleFactory.swift
@@ -0,0 +1,23 @@
+//
+// ModuleFactory.swift
+// SOPT-Stamp-iOS
+//
+// Created by 양수빈 on 2022/10/06.
+// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
+//
+
+import Foundation
+
+import Presentation
+import Network
+import Domain
+import Data
+
+public class ModuleFactory {
+ static let shared = ModuleFactory()
+ private init() { }
+}
+
+extension ModuleFactory: ModuleFactoryInterface {
+
+}
diff --git a/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Resources/Launch Screen.storyboard b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Resources/Launch Screen.storyboard
new file mode 100644
index 000000000..52cfadaf1
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Resources/Launch Screen.storyboard
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Application/AppDelegate.swift b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Application/AppDelegate.swift
new file mode 100644
index 000000000..a2eb4e824
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Application/AppDelegate.swift
@@ -0,0 +1,30 @@
+//
+// AppDelegate.swift
+// ProjectDescriptionHelpers
+//
+// Created by 양수빈 on 2022/10/01.
+//
+
+import UIKit
+
+@main
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+
+ return true
+ }
+
+ // MARK: UISceneSession Lifecycle
+
+ func application( _ application: UIApplication,
+ configurationForConnecting connectingSceneSession: UISceneSession,
+ options: UIScene.ConnectionOptions
+ ) -> UISceneConfiguration {
+ return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
+ }
+
+ func application( _ application: UIApplication,
+ didDiscardSceneSessions sceneSessions: Set
+ ) {}
+}
diff --git a/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Application/SceneDelegate.swift b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Application/SceneDelegate.swift
new file mode 100644
index 000000000..c43f02e7c
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Application/SceneDelegate.swift
@@ -0,0 +1,38 @@
+//
+// SceneDelegate.swift
+// ProjectDescriptionHelpers
+//
+// Created by 양수빈 on 2022/10/01.
+//
+
+import UIKit
+
+class SceneDelegate: UIResponder, UIWindowSceneDelegate {
+
+ var window: UIWindow?
+
+ func scene(_ scene: UIScene,
+ willConnectTo session: UISceneSession,
+ options connectionOptions: UIScene.ConnectionOptions) {
+ guard let scene = (scene as? UIWindowScene) else { return }
+
+ window = UIWindow(frame: scene.coordinateSpace.bounds)
+ window?.windowScene = scene
+ let vc = UIViewController()
+ vc.view.backgroundColor = .gray
+ window?.rootViewController = UINavigationController(rootViewController: vc)
+ window?.makeKeyAndVisible()
+ }
+
+ func sceneDidDisconnect(_ scene: UIScene) {}
+
+ func sceneDidBecomeActive(_ scene: UIScene) {
+ UIApplication.shared.applicationIconBadgeNumber = 0
+ }
+
+ func sceneWillResignActive(_ scene: UIScene) {}
+
+ func sceneWillEnterForeground(_ scene: UIScene) {}
+
+ func sceneDidEnterBackground(_ scene: UIScene) {}
+}
diff --git a/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Demo+/UIFont+.swift b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Demo+/UIFont+.swift
new file mode 100644
index 000000000..5a30a32bb
--- /dev/null
+++ b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Demo/Sources/Demo+/UIFont+.swift
@@ -0,0 +1,59 @@
+//
+// UIFont+.swift
+// DSKitDemoApp
+//
+// Created by Junho Lee on 2022/11/27.
+// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
+//
+
+import UIKit
+
+extension UIFont {
+ @nonobjc public class var h1: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.bold.font(size: 20)
+ }
+
+ @nonobjc public class var h2: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.bold.font(size: 18)
+ }
+
+ @nonobjc public class var h3: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.bold.font(size: 16)
+ }
+
+ @nonobjc public class var subtitle1: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.medium.font(size: 16)
+ }
+
+ @nonobjc public class var subtitle2: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.regular.font(size: 16)
+ }
+
+ @nonobjc public class var subtitle3: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.medium.font(size: 14)
+ }
+
+ @nonobjc public class var caption1: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.regular.font(size: 14)
+ }
+
+ @nonobjc public class var caption2: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.medium.font(size: 12)
+ }
+
+ @nonobjc public class var caption3: UIFont {
+ return DSKitDemoAppFontFamily.Pretendard.regular.font(size: 12)
+ }
+
+ @nonobjc public class var id: UIFont {
+ return DSKitDemoAppFontFamily.Montserrat.regular.font(size: 12)
+ }
+
+ @nonobjc public class var number1: UIFont {
+ return DSKitDemoAppFontFamily.Montserrat.bold.font(size: 24)
+ }
+
+ @nonobjc public class var number2: UIFont {
+ return DSKitDemoAppFontFamily.Montserrat.regular.font(size: 30)
+ }
+}
diff --git a/SOPT-Stamp-iOS/Projects/Modules/DSKit/Project.swift b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Project.swift
index 9f355e66c..05d92e26b 100644
--- a/SOPT-Stamp-iOS/Projects/Modules/DSKit/Project.swift
+++ b/SOPT-Stamp-iOS/Projects/Modules/DSKit/Project.swift
@@ -14,5 +14,6 @@ let project = Project.makeModule(
dependencies: [
.Project.Core
],
- resources: ["Resources/**"]
+ resources: ["Resources/**"],
+ hasDemoApp: true
)
diff --git a/SOPT-Stamp-iOS/Tuist/ProjectDescriptionHelpers/Project+Templates.swift b/SOPT-Stamp-iOS/Tuist/ProjectDescriptionHelpers/Project+Templates.swift
index d27bb5fca..9219bec38 100644
--- a/SOPT-Stamp-iOS/Tuist/ProjectDescriptionHelpers/Project+Templates.swift
+++ b/SOPT-Stamp-iOS/Tuist/ProjectDescriptionHelpers/Project+Templates.swift
@@ -12,7 +12,9 @@ public extension Project {
sources: SourceFilesList = ["Sources/**"],
resources: ResourceFileElements? = nil,
infoPlist: InfoPlist = .default,
- hasTest: Bool = false
+ resourceSynthesizers: [ResourceSynthesizer] = .default,
+ hasTest: Bool = false,
+ hasDemoApp: Bool = false
) -> Project {
return project(
name: name,
@@ -23,7 +25,9 @@ public extension Project {
sources: sources,
resources: resources,
infoPlist: infoPlist,
- hasTest: hasTest
+ resourceSynthesizers: resourceSynthesizers,
+ hasTest: hasTest,
+ hasDemoApp: hasDemoApp
)
}
}
@@ -40,13 +44,15 @@ public extension Project {
sources: SourceFilesList,
resources: ResourceFileElements? = nil,
infoPlist: InfoPlist,
- hasTest: Bool = false
+ resourceSynthesizers: [ResourceSynthesizer] = .default,
+ hasTest: Bool = false,
+ hasDemoApp: Bool = false
) -> Project {
let settings: Settings = .settings(
base: product == .app
- ? .init().setCodeSignManualForApp()
- : .init().setCodeSignManual(),
+ ? .init().setCodeSignManualForApp()
+ : .init().setCodeSignManual(),
debug: .init()
.setProvisioningDevelopment(),
release: .init()
@@ -69,26 +75,48 @@ public extension Project {
scripts: [.SwiftLintString],
dependencies: dependencies
)
-
- let schemes: [Scheme] = [.makeScheme(target: .debug, name: name)]
- let targets: [Target] = hasTest
- ? [appTarget, makeTestTarget(name: name)]
- : [appTarget]
-
+ let demoAppTarget: Target = {
+ let demoSource: SourceFilesList = ["Demo/Sources/**"]
+ let demoGlobs: [SourceFileGlob] = [.glob("Sources/**", excluding: ["Sources/UIFont+.swift"])]
+ let demoSources: SourceFilesList = SourceFilesList(globs: demoGlobs + demoSource.globs)
+ let demoResources: ResourceFileElements = ["Demo/Resources/**", "Resources/**"]
+ return makeDemoAppTarget(name: name, sources: demoSources, resources: demoResources)
+ }()
+
+ let schemes: [Scheme] = hasDemoApp
+ ? [.makeScheme(target: .debug, name: name), .makeDemoScheme(target: .debug, name: name)]
+ : [.makeScheme(target: .debug, name: name)]
+
+ var targets: [Target]
+ switch (hasTest, hasDemoApp) {
+ case (true, true):
+ targets = [appTarget, makeTestTarget(name: name, isDemo: true), demoAppTarget]
+ case (true, false):
+ targets = [appTarget, makeTestTarget(name: name)]
+ case (false, true):
+ targets = [appTarget, demoAppTarget]
+ case (false, false):
+ targets = [appTarget]
+ }
+
return Project(
name: name,
organizationName: organizationName,
packages: packages,
settings: settings,
targets: targets,
- schemes: schemes
+ schemes: schemes,
+ resourceSynthesizers: resourceSynthesizers
)
}
}
public extension Project {
- static func makeTestTarget(name: String) -> Target {
+ static func makeTestTarget(name: String, isDemo: Bool = false) -> Target {
+ let testTargetDependencies: [TargetDependency] = isDemo
+ ? [.target(name: "\(name)DemoApp"), .SPM.Nimble, .SPM.Quick]
+ : [.target(name: name), .SPM.Nimble, .SPM.Quick]
return Target(
name: "\(name)Tests",
platform: .iOS,
@@ -97,7 +125,24 @@ public extension Project {
deploymentTarget: Environment.deploymentTarget,
infoPlist: .default,
sources: ["Tests/**"],
- dependencies: [.target(name: name), .SPM.Nimble, .SPM.Quick]
+ dependencies: testTargetDependencies
+ )
+ }
+
+ static func makeDemoAppTarget(name: String, sources: SourceFilesList, resources: ResourceFileElements) -> Target {
+ return Target(
+ name: "\(name)DemoApp",
+ platform: .iOS,
+ product: .app,
+ bundleId: "\(Environment.organizationName).\(name)DemoApp",
+ deploymentTarget: Environment.deploymentTarget,
+ infoPlist: .extendingDefault(with: baseinfoPlist),
+ sources: sources,
+ resources: resources,
+ scripts: [.SwiftLintString],
+ dependencies: [
+ .target(name: name)
+ ]
)
}
}
@@ -120,4 +165,21 @@ extension Scheme {
analyzeAction: .analyzeAction(configuration: target)
)
}
+
+ static func makeDemoScheme(target: ConfigurationName, name: String) -> Scheme {
+ return Scheme(
+ name: name,
+ shared: true,
+ buildAction: .buildAction(targets: ["\(name)DemoApp"]),
+ testAction: .targets(
+ ["\(name)Tests"],
+ configuration: target,
+ options: .options(coverage: true, codeCoverageTargets: ["\(name)DemoApp"])
+ ),
+ runAction: .runAction(configuration: target),
+ archiveAction: .archiveAction(configuration: target),
+ profileAction: .profileAction(configuration: target),
+ analyzeAction: .analyzeAction(configuration: target)
+ )
+ }
}
diff --git a/SOPT-Stamp-iOS/Workspace.swift b/SOPT-Stamp-iOS/Workspace.swift
index 2ec060f53..d16e204c6 100644
--- a/SOPT-Stamp-iOS/Workspace.swift
+++ b/SOPT-Stamp-iOS/Workspace.swift
@@ -10,6 +10,7 @@ import ProjectDescription
let workspace = Workspace(
name: "SOPT-Stamp-iOS",
projects: [
- "Projects/SOPT-Stamp-iOS"
+ "Projects/SOPT-Stamp-iOS",
+ "Projects/Demo/SOPT-Stamp-Demo"
]
)