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" ] )