├── .gitignore
├── .swift-sh-version
├── .swift-version
├── .xcodegen-version
├── Makefile
├── Modules
├── App
│ ├── Resources
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ └── Launch Screen.storyboard
│ ├── Sources
│ │ └── App Support
│ │ │ ├── App-Bridging-Header.h
│ │ │ ├── AppDelegate.swift
│ │ │ └── PrefixHeader.pch
│ ├── Supporting Files
│ │ ├── App.entitlements
│ │ └── Info.plist
│ ├── app.yml
│ └── xcconfigs
│ │ ├── App-Debug.xcconfig
│ │ ├── App-Release.xcconfig
│ │ └── App-Shared.xcconfig
├── project.xcconfig
└── xcconfigs
│ ├── Project-Debug.xcconfig
│ ├── Project-Release.xcconfig
│ └── Project-Shared.xcconfig
├── README.md
├── project.yml
└── tools
├── !Mac-App-Template
├── Resources
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ └── Base.lproj
│ │ └── Main.storyboard
├── Sources
│ ├── AppDelegate.swift
│ └── ViewController.swift
├── Supporting Files
│ ├── Info.plist
│ └── {{Module}}.entitlements
├── xcconfigs
│ ├── {{Module}}-Debug.xcconfig
│ ├── {{Module}}-Release.xcconfig
│ └── {{Module}}-Shared.xcconfig
└── {{Module}}.yml
├── !Module-Template
├── Sources
│ └── {{Module}}.swift
├── Supporting Files
│ └── Info.plist
├── xcconfigs
│ ├── {{Module}}-Debug.xcconfig
│ ├── {{Module}}-Release.xcconfig
│ └── {{Module}}-Shared.xcconfig
└── {{Module}}.yml
├── !iOS-App-Template
├── Resources
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ └── Launch Screen.storyboard
├── Sources
│ └── App Support
│ │ ├── App-Bridging-Header.h
│ │ ├── AppDelegate.swift
│ │ └── PrefixHeader.pch
├── Supporting Files
│ ├── App.entitlements
│ └── Info.plist
├── xcconfigs
│ ├── {{Module}}-Debug.xcconfig
│ ├── {{Module}}-Release.xcconfig
│ └── {{Module}}-Shared.xcconfig
└── {{Module}}.yml
├── ensure-swift-sh.sh
├── ensure-xcodegen.sh
├── new-module.swift
└── start.swift
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/xcode,swift
3 | # Edit at https://www.gitignore.io/?templates=xcode,swift
4 |
5 | ### Swift ###
6 | # Xcode
7 | #
8 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
9 |
10 | ## Build generated
11 | build/
12 | DerivedData/
13 |
14 | ## Various settings
15 | *.pbxuser
16 | !default.pbxuser
17 | *.mode1v3
18 | !default.mode1v3
19 | *.mode2v3
20 | !default.mode2v3
21 | *.perspectivev3
22 | !default.perspectivev3
23 | xcuserdata/
24 |
25 | ## Other
26 | *.moved-aside
27 | *.xccheckout
28 | *.xcscmblueprint
29 |
30 | ## Obj-C/Swift specific
31 | *.hmap
32 | *.ipa
33 | *.dSYM.zip
34 | *.dSYM
35 |
36 | ## Playgrounds
37 | timeline.xctimeline
38 | playground.xcworkspace
39 |
40 | # Swift Package Manager
41 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
42 | # Packages/
43 | # Package.pins
44 | # Package.resolved
45 | .build/
46 |
47 | # CocoaPods
48 | # We recommend against adding the Pods directory to your .gitignore. However
49 | # you should judge for yourself, the pros and cons are mentioned at:
50 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
51 | # Pods/
52 | # Add this line if you want to avoid checking in source code from the Xcode workspace
53 | # *.xcworkspace
54 |
55 | # Carthage
56 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
57 | # Carthage/Checkouts
58 |
59 | Carthage/Build
60 |
61 | # fastlane
62 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
63 | # screenshots whenever they are needed.
64 | # For more information about the recommended setup visit:
65 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
66 |
67 | fastlane/report.xml
68 | fastlane/Preview.html
69 | fastlane/screenshots/**/*.png
70 | fastlane/test_output
71 |
72 | # Code Injection
73 | # After new code Injection tools there's a generated folder /iOSInjectionProject
74 | # https://github.com/johnno1962/injectionforxcode
75 |
76 | iOSInjectionProject/
77 |
78 | ### Xcode ###
79 | # Xcode
80 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
81 |
82 | ## User settings
83 |
84 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
85 |
86 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
87 |
88 | ### Xcode Patch ###
89 | *.xcodeproj/*
90 | !*.xcodeproj/project.pbxproj
91 | !*.xcodeproj/xcshareddata/
92 | !*.xcworkspace/contents.xcworkspacedata
93 | /*.gcno
94 | **/xcshareddata/WorkspaceSettings.xcsettings
95 |
96 | # End of https://www.gitignore.io/api/xcode,swift
97 |
98 | # xcodegen
99 | *.xcodeproj
100 | .DS_Store
101 | vendor/
102 |
103 |
--------------------------------------------------------------------------------
/.swift-sh-version:
--------------------------------------------------------------------------------
1 | 1.14.0
2 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.1
2 |
--------------------------------------------------------------------------------
/.xcodegen-version:
--------------------------------------------------------------------------------
1 | 2.10.1
2 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: project
2 | project:
3 | @chmod +x ./tools/ensure-xcodegen.sh
4 | @./tools/ensure-xcodegen.sh
5 | @./vendor/XcodeGen
6 |
7 | .PHONY: start
8 | start:
9 | @chmod +x ./tools/ensure-swift-sh.sh
10 | @./tools/ensure-swift-sh.sh
11 | @./vendor/swift-sh ./tools/start.swift
12 |
13 | .PHONY: new-module
14 | new-module:
15 | @chmod +x ./tools/ensure-swift-sh.sh
16 | @./tools/ensure-swift-sh.sh
17 | @./vendor/swift-sh ./tools/new-module.swift
18 |
--------------------------------------------------------------------------------
/Modules/App/Resources/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "size" : "1024x1024",
46 | "scale" : "1x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/Modules/App/Resources/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Modules/App/Resources/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Modules/App/Sources/App Support/App-Bridging-Header.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsorge/ios-project-template/a94fa3ace1440dbb1066625ebd4781ed84f0b782/Modules/App/Sources/App Support/App-Bridging-Header.h
--------------------------------------------------------------------------------
/Modules/App/Sources/App Support/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | @UIApplicationMain
4 | final class AppDelegate: NSObject, UIApplicationDelegate {
5 | var window: UIWindow?
6 |
7 | func applicationDidFinishLaunching(_ application: UIApplication) {
8 | let window = UIWindow()
9 | self.window = window
10 |
11 | let root = UIViewController()
12 | root.view.backgroundColor = .red
13 | window.rootViewController = root
14 | window.makeKeyAndVisible()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Modules/App/Sources/App Support/PrefixHeader.pch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsorge/ios-project-template/a94fa3ace1440dbb1066625ebd4781ed84f0b782/Modules/App/Sources/App Support/PrefixHeader.pch
--------------------------------------------------------------------------------
/Modules/App/Supporting Files/App.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 | com.apple.developer.ubiquity-kvstore-identifier
8 | $(TeamIdentifierPrefix)$(CFBundleIdentifier)
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Modules/App/Supporting Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | ${APP_VERSION}
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${BUILD_NUMBER}
23 | ITSAppUsesNonExemptEncryption
24 |
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | Launch Screen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 |
37 | UIViewControllerBasedStatusBarAppearance
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Modules/App/app.yml:
--------------------------------------------------------------------------------
1 | targets:
2 | '{{App-Name}}':
3 | type: application
4 | platform: iOS
5 | sources:
6 | - Sources
7 | - Resources
8 | configFiles:
9 | Debug: xcconfigs/App-Debug.xcconfig
10 | Release: xcconfigs/App-Release.xcconfig
11 |
--------------------------------------------------------------------------------
/Modules/App/xcconfigs/App-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "App-Shared.xcconfig"
2 |
3 | SWIFT_OPTIMIZATION_LEVEL = -Onone
4 |
--------------------------------------------------------------------------------
/Modules/App/xcconfigs/App-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "App-Shared.xcconfig"
2 |
3 | PROVISIONING_PROFILE_SPECIFIER =
4 | CODE_SIGN_IDENTITY = iPhone Distribution
5 | CODE_SIGN_STYLE = Manual
6 |
--------------------------------------------------------------------------------
/Modules/App/xcconfigs/App-Shared.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../project.xcconfig"
2 |
3 | IPHONEOS_DEPLOYMENT_TARGET = $(IOS_VERSION_SHARED)
4 | SWIFT_VERSION = $(SWIFT_VERSION_SHARED)
5 |
6 | DEVELOPMENT_TEAM = $(DEV_TEAM)
7 |
8 | SWIFT_MODULE_NAME = $(APP_NAME)
9 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
10 | CODE_SIGN_STYLE = Automatic
11 | CODE_SIGN_ENTITLEMENTS = $(SRCROOT)/Modules/App/Supporting Files/App.entitlements
12 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/Modules/App
13 | GCC_PREFIX_HEADER = $(SRCROOT)/Modules/App/Sources/App Support/PrefixHeader.pch
14 | SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/Modules/App/Sources/App Support/App-Bridging-Header.h
15 | SWIFT_OBJC_INTERFACE_HEADER_NAME = $(SWIFT_MODULE_NAME)-Swift.h
16 |
17 | PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID).ios
18 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
19 | CLANG_ENABLE_MODULES = YES
20 | CLANG_STATIC_ANALYZER_MODE = deep
21 | CODE_SIGN_IDENTITY = iPhone Developer
22 | CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer
23 | DEFINES_MODULE = YES
24 | ENABLE_BITCODE = NO
25 | GCC_PRECOMPILE_PREFIX_HEADER = YES
26 | IBSC_NOTICES = NO
27 | IBSC_WARNINGS = NO
28 | INFOPLIST_FILE = $(SRCROOT)/Modules/App/Supporting Files/Info.plist
29 | LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks
30 | PRODUCT_NAME = $(TARGET_NAME)
31 | PROVISIONING_PROFILE_SPECIFIER =
32 | RUN_CLANG_STATIC_ANALYZER = NO
33 | SWIFT_SWIFT3_OBJC_INFERENCE = Off
34 | TARGETED_DEVICE_FAMILY = 1
35 |
--------------------------------------------------------------------------------
/Modules/project.xcconfig:
--------------------------------------------------------------------------------
1 | APP_NAME = {{App-Name}}
2 |
3 | APP_VERSION = 1.0
4 |
5 | BUILD_NUMBER = 1
6 |
7 | BUNDLE_ID = io.taphouse.{{App-Name}}
8 |
9 | DEV_TEAM =
10 |
11 | SWIFT_VERSION_SHARED = 5.0
12 |
13 | IOS_VERSION_SHARED = 13.0
14 |
15 | MACOS_VERSION_SHARED = 15.0
16 |
--------------------------------------------------------------------------------
/Modules/xcconfigs/Project-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Project-Shared.xcconfig"
2 |
3 | COPY_PHASE_STRIP = NO
4 | ENABLE_TESTABILITY = YES
5 | GCC_DYNAMIC_NO_PIC = NO
6 | GCC_OPTIMIZATION_LEVEL = 0
7 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited)
8 | GCC_SYMBOLS_PRIVATE_EXTERN = NO
9 | METAL_ENABLE_DEBUG_INFO = YES
10 | ONLY_ACTIVE_ARCH = YES
11 |
--------------------------------------------------------------------------------
/Modules/xcconfigs/Project-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Project-Shared.xcconfig"
2 |
3 | COPY_PHASE_STRIP = YES
4 | ENABLE_NS_ASSERTIONS = NO
5 | METAL_ENABLE_DEBUG_INFO = NO
6 | SWIFT_OPTIMIZATION_LEVEL = -Owholemodule
7 | VALIDATE_PRODUCT = YES
8 | DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
9 |
--------------------------------------------------------------------------------
/Modules/xcconfigs/Project-Shared.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../project.xcconfig"
2 |
3 | CLANG_ANALYZER_NONNULL = YES
4 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE
5 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES
6 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES
7 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
8 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
9 | DEBUG_INFORMATION_FORMAT = dwarf
10 | PRODUCT_NAME = "$(TARGET_NAME)"
11 | SWIFT_VERSION = $(SWIFT_VERSION_SHARED)
12 | IPHONEOS_DEPLOYMENT_TARGET = $(IOS_VERSION_SHARED)
13 |
14 | ALWAYS_SEARCH_USER_PATHS = NO
15 | CLANG_CXX_LANGUAGE_STANDARD = gnu++0x
16 | CLANG_CXX_LIBRARY = libc++
17 | CLANG_ENABLE_MODULES = YES
18 | CLANG_ENABLE_OBJC_ARC = YES
19 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
20 |
21 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES
22 | CLANG_WARN_BOOL_CONVERSION = YES
23 | CLANG_WARN_COMMA = YES
24 | CLANG_WARN_CONSTANT_CONVERSION = YES
25 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR
26 | CLANG_WARN_EMPTY_BODY = YES
27 | CLANG_WARN_ENUM_CONVERSION = YES
28 | CLANG_WARN_INFINITE_RECURSION = YES
29 | CLANG_WARN_INT_CONVERSION = YES
30 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES
31 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES
32 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR
33 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES
34 | CLANG_WARN_STRICT_PROTOTYPES = YES
35 | CLANG_WARN_SUSPICIOUS_MOVE = YES
36 | CLANG_WARN_UNREACHABLE_CODE = YES
37 | ENABLE_STRICT_OBJC_MSGSEND = YES
38 | GCC_C_LANGUAGE_STANDARD = gnu99
39 | GCC_NO_COMMON_BLOCKS = YES
40 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES
41 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR
42 | GCC_WARN_UNDECLARED_SELECTOR = YES
43 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE
44 | GCC_WARN_UNUSED_FUNCTION = YES
45 | GCC_WARN_UNUSED_VARIABLE = YES
46 | IBSC_WARNINGS = NO
47 | SWIFT_SWIFT3_OBJC_INFERENCE = Default
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iOS Project Template
2 |
3 | This is a template for making a new iOS app. To get started, run `make start`. Enter the name of your app, and the files will be updated to reflect it. Here's what is included:
4 |
5 | * A modular setup for your project with scaffolding using [xcodegen](https://github.com/yonaskolb/XcodeGen).
6 | * A basic app that includes a launch screen storyboard that will display your app name, and an app delegate.
7 | * To create your project there is a make command, just run `make project`.
8 | * To add a new module, run `make new-module` and it will walk through the steps and create the new module for you.
9 |
--------------------------------------------------------------------------------
/project.yml:
--------------------------------------------------------------------------------
1 | configFiles:
2 | Debug: Modules/xcconfigs/Project-Debug.xcconfig
3 | Release: Modules/xcconfigs/Project-Release.xcconfig
4 | fileGroups:
5 | - Modules/App
6 | include:
7 | - Modules/App/app.yml
8 | name: {{App-Name}}
9 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/Resources/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/Sources/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 |
3 | @NSApplicationMain
4 | class AppDelegate: NSObject, NSApplicationDelegate {
5 |
6 |
7 |
8 | func applicationDidFinishLaunching(_ aNotification: Notification) {
9 | // Insert code here to initialize your application
10 | }
11 |
12 | func applicationWillTerminate(_ aNotification: Notification) {
13 | // Insert code here to tear down your application
14 | }
15 |
16 |
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/Sources/ViewController.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 |
3 | class ViewController: NSViewController {
4 |
5 | override func viewDidLoad() {
6 | super.viewDidLoad()
7 |
8 | // Do any additional setup after loading the view.
9 | }
10 |
11 | override var representedObject: Any? {
12 | didSet {
13 | // Update the view, if already loaded.
14 | }
15 | }
16 |
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/Supporting Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | Copyright © 2019 Taphouse Software LLC. All rights reserved.
27 | NSMainStoryboardFile
28 | Main
29 | NSPrincipalClass
30 | NSApplication
31 | NSSupportsAutomaticTermination
32 |
33 | NSSupportsSuddenTermination
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/Supporting Files/{{Module}}.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/xcconfigs/{{Module}}-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "{{Module}}-Shared.xcconfig"
2 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/xcconfigs/{{Module}}-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "{{Module}}-Shared.xcconfig"
2 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/xcconfigs/{{Module}}-Shared.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../project.xcconfig"
2 |
3 | PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID).macos
4 | PRODUCT_NAME = $(TARGET_NAME)
5 | SWIFT_VERSION = $(SWIFT_VERSION_SHARED)
6 |
7 | INFOPLIST_FILE = $(SRCROOT)/Modules/{{Module}}/Info.plist
8 | CODE_SIGN_ENTITLEMENTS = $(SRCROOT)/Modules/{{Module}}/template.entitlements
9 |
10 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
11 | CODE_SIGN_STYLE = Automatic
12 | COMBINE_HIDPI_IMAGES = YES
13 | LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks
14 | SDKROOT = macosx
15 |
--------------------------------------------------------------------------------
/tools/!Mac-App-Template/{{Module}}.yml:
--------------------------------------------------------------------------------
1 | targets:
2 | {{Module}}:
3 | type: application
4 | platform: macOS
5 | sources:
6 | - Sources
7 | - Resources
8 | configFiles:
9 | Debug: xcconfigs/{{Module}}-Debug.xcconfig
10 | Release: xcconfigs/{{Module}}-Release.xcconfig
11 |
--------------------------------------------------------------------------------
/tools/!Module-Template/Sources/{{Module}}.swift:
--------------------------------------------------------------------------------
1 | public final class {{Module}} {}
2 |
--------------------------------------------------------------------------------
/tools/!Module-Template/Supporting Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/tools/!Module-Template/xcconfigs/{{Module}}-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "{{Module}}-Shared.xcconfig"
2 |
3 | DEBUG_INFORMATION_FORMAT = dwarf
4 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE
5 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG
6 | SWIFT_OPTIMIZATION_LEVEL = -Onone
7 |
--------------------------------------------------------------------------------
/tools/!Module-Template/xcconfigs/{{Module}}-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "{{Module}}-Shared.xcconfig"
2 |
3 | CODE_SIGN_IDENTITY = iPhone Developer
4 | COPY_PHASE_STRIP = NO
5 | DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
6 | MTL_ENABLE_DEBUG_INFO = NO
7 |
--------------------------------------------------------------------------------
/tools/!Module-Template/xcconfigs/{{Module}}-Shared.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../project.xcconfig"
2 |
3 | INFOPLIST_FILE = $(SRCROOT)/Modules/{{Module}}/Supporting Files/Info.plist
4 |
5 | SWIFT_VERSION = $(SWIFT_VERSION_SHARED)
6 | IPHONEOS_DEPLOYMENT_TARGET = $(IOS_VERSION_SHARED)
7 | PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID).$(PRODUCT_NAME)
8 | DEVELOPMENT_TEAM = $(DEV_TEAM)
9 |
10 | LD_NO_PIE[sdk=*simulator*] = YES
11 | CLANG_ANALYZER_NONNULL = YES
12 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE
13 | CLANG_CXX_LANGUAGE_STANDARD = gnu++14
14 | CLANG_ENABLE_OBJC_WEAK = YES
15 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES
16 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES
17 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
18 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
19 | CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer
20 | CODE_SIGN_STYLE = Automatic
21 | CURRENT_PROJECT_VERSION = 1
22 | DEFINES_MODULE = YES
23 | DYLIB_COMPATIBILITY_VERSION = 1
24 | DYLIB_CURRENT_VERSION = 1
25 | DYLIB_INSTALL_NAME_BASE = @rpath
26 | GCC_C_LANGUAGE_STANDARD = gnu11
27 | INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/Frameworks
28 | LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @loader_path/Frameworks
29 | MTL_FAST_MATH = YES
30 | PRODUCT_NAME = $(TARGET_NAME:c99extidentifier)
31 | SKIP_INSTALL = YES
32 | TARGETED_DEVICE_FAMILY = 1,2
33 | VERSION_INFO_PREFIX =
34 | VERSIONING_SYSTEM = apple-generic
35 |
--------------------------------------------------------------------------------
/tools/!Module-Template/{{Module}}.yml:
--------------------------------------------------------------------------------
1 | targets:
2 | {{Module}}:
3 | type: framework
4 | platform: iOS
5 | sources:
6 | - Sources
7 | configFiles:
8 | Debug: xcconfigs/{{Module}}-Debug.xcconfig
9 | Release: xcconfigs/{{Module}}-Release.xcconfig
10 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Resources/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "size" : "1024x1024",
46 | "scale" : "1x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Resources/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Resources/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Sources/App Support/App-Bridging-Header.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsorge/ios-project-template/a94fa3ace1440dbb1066625ebd4781ed84f0b782/tools/!iOS-App-Template/Sources/App Support/App-Bridging-Header.h
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Sources/App Support/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | @UIApplicationMain
4 | final class AppDelegate: NSObject, UIApplicationDelegate {
5 | var window: UIWindow?
6 |
7 | func applicationDidFinishLaunching(_ application: UIApplication) {
8 | let window = UIWindow()
9 | self.window = window
10 |
11 | let root = UIViewController()
12 | root.view.backgroundColor = .red
13 | window.rootViewController = root
14 | window.makeKeyAndVisible()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Sources/App Support/PrefixHeader.pch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsorge/ios-project-template/a94fa3ace1440dbb1066625ebd4781ed84f0b782/tools/!iOS-App-Template/Sources/App Support/PrefixHeader.pch
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Supporting Files/App.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 | com.apple.developer.ubiquity-kvstore-identifier
8 | $(TeamIdentifierPrefix)$(CFBundleIdentifier)
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/Supporting Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | ${APP_VERSION}
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${BUILD_NUMBER}
23 | ITSAppUsesNonExemptEncryption
24 |
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | Launch Screen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 |
37 | UIViewControllerBasedStatusBarAppearance
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/xcconfigs/{{Module}}-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "{{Module}}-Shared.xcconfig"
2 |
3 | SWIFT_OPTIMIZATION_LEVEL = -Onone
4 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/xcconfigs/{{Module}}-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "{{Module}}-Shared.xcconfig"
2 |
3 | PROVISIONING_PROFILE_SPECIFIER =
4 | CODE_SIGN_IDENTITY = iPhone Distribution
5 | CODE_SIGN_STYLE = Manual
6 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/xcconfigs/{{Module}}-Shared.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../project.xcconfig"
2 |
3 | IPHONEOS_DEPLOYMENT_TARGET = $(IOS_VERSION_SHARED)
4 | SWIFT_VERSION = $(SWIFT_VERSION_SHARED)
5 |
6 | DEVELOPMENT_TEAM = $(DEV_TEAM)
7 |
8 | SWIFT_MODULE_NAME = $(APP_NAME)
9 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
10 | CODE_SIGN_STYLE = Automatic
11 | CODE_SIGN_ENTITLEMENTS = $(SRCROOT)/Modules/App/Supporting Files/App.entitlements
12 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/Modules/App
13 | GCC_PREFIX_HEADER = $(SRCROOT)/Modules/App/Sources/App Support/PrefixHeader.pch
14 | SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/Modules/App/Sources/App Support/App-Bridging-Header.h
15 | SWIFT_OBJC_INTERFACE_HEADER_NAME = $(SWIFT_MODULE_NAME)-Swift.h
16 |
17 | PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID).ios
18 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
19 | CLANG_ENABLE_MODULES = YES
20 | CLANG_STATIC_ANALYZER_MODE = deep
21 | CODE_SIGN_IDENTITY = iPhone Developer
22 | CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer
23 | DEFINES_MODULE = YES
24 | ENABLE_BITCODE = NO
25 | GCC_PRECOMPILE_PREFIX_HEADER = YES
26 | IBSC_NOTICES = NO
27 | IBSC_WARNINGS = NO
28 | INFOPLIST_FILE = $(SRCROOT)/Modules/App/Supporting Files/Info.plist
29 | LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks
30 | PRODUCT_NAME = $(TARGET_NAME)
31 | PROVISIONING_PROFILE_SPECIFIER =
32 | RUN_CLANG_STATIC_ANALYZER = NO
33 | SWIFT_SWIFT3_OBJC_INFERENCE = Off
34 | TARGETED_DEVICE_FAMILY = 1
35 | SDKROOT = iphoneos
36 |
--------------------------------------------------------------------------------
/tools/!iOS-App-Template/{{Module}}.yml:
--------------------------------------------------------------------------------
1 | targets:
2 | '{{Module}}':
3 | type: application
4 | platform: iOS
5 | sources:
6 | - Sources
7 | - Resources
8 | configFiles:
9 | Debug: xcconfigs/{{Module}}-Debug.xcconfig
10 | Release: xcconfigs/{{Module}}-Release.xcconfig
11 |
--------------------------------------------------------------------------------
/tools/ensure-swift-sh.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -o pipefail
5 | set -u
6 |
7 | required_version="$(cat .swift-sh-version)"
8 | install_location=./vendor
9 |
10 | install() {
11 | if [ ! -d $install_location ]; then
12 | mkdir $install_location;
13 | fi;
14 |
15 | rm -f $install_location/XcodeGen $install_location/xcodegen.tar.gz
16 |
17 | curl --location --fail --retry 5 \
18 | https://github.com/mxcl/swift-sh/archive/"$required_version".zip \
19 | --output $install_location/swift-sh-pkg.zip
20 |
21 | (
22 | cd $install_location
23 | unzip -o swift-sh-pkg.zip
24 | unzipped_path=./swift-sh-$required_version
25 | swift build --package-path $unzipped_path/ -c release
26 | mv $unzipped_path/.build/release/swift-sh swift-sh
27 | rm -rf $unzipped_path
28 | rm swift-sh-pkg.zip
29 | echo "$required_version" > swift-sh-version
30 | )
31 |
32 | echo "Installed swift-sh locally"
33 | }
34 |
35 | if [ ! -x $install_location/swift-sh ]; then
36 | install
37 | elif [[ ! $required_version == $(cat $install_location/swift-sh-version) ]]; then
38 | install
39 | fi
40 |
--------------------------------------------------------------------------------
/tools/ensure-xcodegen.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -o pipefail
5 | set -u
6 |
7 | required_version="$(cat .xcodegen-version)"
8 | install_location=./vendor
9 |
10 | install() {
11 | if [ ! -d $install_location ]; then
12 | mkdir $install_location;
13 | fi;
14 |
15 | rm -f ./tmp/XcodeGen ./tmp/xcodegen.tar.gz
16 |
17 | curl --location --fail --retry 5 \
18 | https://github.com/yonaskolb/XcodeGen/releases/download/"$required_version"/xcodegen.zip \
19 | --output $install_location/xcodegen.zip
20 |
21 | (
22 | cd $install_location
23 | unzip -o xcodegen.zip -d download > /dev/null
24 | mv download/xcodegen/bin/xcodegen XcodeGen
25 | rm -rf xcodegen.zip download
26 | )
27 |
28 | echo "Installed XcodeGen locally"
29 | }
30 |
31 | if [ ! -x $install_location/XcodeGen ]; then
32 | install
33 | elif ! diff <(echo "Version: $required_version") <($install_location/XcodeGen version) > /dev/null; then
34 | install
35 | fi
36 |
--------------------------------------------------------------------------------
/tools/new-module.swift:
--------------------------------------------------------------------------------
1 | #!/usr/bin/swift sh
2 |
3 | import Files // @JohnSundell ~> 3.1.0
4 | import Foundation
5 | import Yams // @jpsim ~> 2.0.0
6 |
7 | /// Used to interact with the console in a CLI context
8 | struct Console {
9 | /// The type of output to print messages to the console
10 | enum OutputType {
11 | /// Standard Output
12 | case standard
13 | /// Standard Error
14 | case error
15 | }
16 |
17 | /// Reads the input from Standard Input
18 | static func getInput() -> String? {
19 | return String(data: FileHandle.standardInput.availableData, encoding: .utf8)?
20 | .trimmingCharacters(in: .newlines)
21 | }
22 |
23 | /// Prints the message to the specified output
24 | ///
25 | /// - parameter message: The message to print
26 | /// - parameter output: The output type to send the message to. It gets prepended with "Error: "
27 | static func writeMessage(_ message: String, to output: OutputType = .standard) {
28 | switch output {
29 | case .standard:
30 | print(message)
31 | case .error:
32 | fputs("Error: \(message)\n", stderr)
33 | }
34 | }
35 | }
36 |
37 | enum ModuleType: Int, CaseIterable {
38 | case framework = 1
39 | case iosApp = 2
40 | case macApp = 3
41 |
42 | init?(text: String) {
43 | guard let num = Int(text), let moduleType = ModuleType(rawValue: num) else { return nil }
44 | self = moduleType
45 | }
46 |
47 | var templateFolder: String {
48 | switch self {
49 | case .framework: return "!Module-Template"
50 | case .iosApp: return "!iOS-App-Template"
51 | case .macApp: return "!Mac-App-Template"
52 | }
53 | }
54 | }
55 |
56 | Console.writeMessage("What is the name of you new module?")
57 | guard let moduleName = Console.getInput(), moduleName.isEmpty == false else {
58 | Console.writeMessage("There must be a module name entered")
59 | exit(EXIT_FAILURE)
60 | }
61 |
62 | Console.writeMessage("What kind of module is it?\n1. Framework\n2. iOS app\n3. Mac app")
63 | guard let moduleTypeInput = Console.getInput(), let moduleType = ModuleType(text: moduleTypeInput) else {
64 | Console.writeMessage("There needs to be a valid module type selected")
65 | exit(EXIT_FAILURE)
66 | }
67 |
68 | func replaceToken(_ token: String, in file: File, with name: String) throws {
69 | if let fileContents = try? file.readAsString(), fileContents.contains(token) {
70 | let replacedContents = fileContents.replacingOccurrences(of: token, with: name)
71 | try file.write(string: replacedContents)
72 | }
73 |
74 | if file.name.contains(token) {
75 | let newName = file.name.replacingOccurrences(of: token, with: name)
76 | try file.rename(to: newName)
77 | }
78 | }
79 |
80 | func addProjectDependency(_ depName: String) throws {
81 | let projectFile = try Folder.current.file(named: "project.yml")
82 | let projectContents = try projectFile.readAsString()
83 | guard var projectYaml = try? Yams.load(yaml: projectContents) as? [String: Any] else {
84 | Console.writeMessage("Module created but not added to the project yet. Do that manually.", to: .error)
85 | exit(0)
86 | }
87 |
88 | var includes = [String]()
89 | if let projectIncludes = projectYaml["include"] as? [String] {
90 | includes = projectIncludes
91 | }
92 |
93 | includes.append("Modules/\(depName)/\(depName).yml")
94 | projectYaml["include"] = includes
95 |
96 | var fileGroups = [String]()
97 | if let projectGroups = projectYaml["fileGroups"] as? [String] {
98 | fileGroups = projectGroups
99 | }
100 |
101 | fileGroups.append("Modules/\(depName)/")
102 | projectYaml["fileGroups"] = fileGroups
103 |
104 | let encodedProject = try Yams.dump(object: projectYaml)
105 | try projectFile.write(string: encodedProject)
106 | }
107 |
108 | func addTargetDependency(_ depName: String) throws {
109 | let appYamlFile = try Folder.current.subfolder(atPath: "Modules/App").file(named: "app.yml")
110 | let yamlContents = try appYamlFile.readAsString()
111 | guard var appYaml = try? Yams.load(yaml: yamlContents) as? [String: Any] else {
112 | Console.writeMessage("Module created but not added as an app dependency yet. Do that manually.", to: .error)
113 | exit(0)
114 | }
115 |
116 | guard var targets = appYaml["targets"] as? [String: Any],
117 | let appName = targets.keys.first,
118 | var appTarget = targets[appName] as? [String: Any]
119 | else { return }
120 |
121 | var deps = [[String: Any]]()
122 | if let appDeps = appTarget["depdendencies"] as? [[String: Any]] {
123 | deps = appDeps
124 | }
125 |
126 | deps.append(["target": depName])
127 | appTarget["dependencies"] = deps
128 | targets[appName] = appTarget
129 | appYaml["targets"] = targets
130 |
131 |
132 | let encodedAppFile = try Yams.dump(object: appYaml)
133 | try appYamlFile.write(string: encodedAppFile)
134 | }
135 |
136 | let moduleToken = "{{Module}}"
137 |
138 | // copy template folder over
139 | let templateFolder = try Folder.current.subfolder(atPath: "tools/\(moduleType.templateFolder)")
140 | let targetFolder = try Folder.current.subfolder(atPath: "Modules").createSubfolderIfNeeded(withName: moduleName)
141 |
142 | for file in templateFolder.files {
143 | let newFile = try file.copy(to: targetFolder)
144 | try replaceToken(moduleToken, in: newFile, with: moduleName)
145 | }
146 |
147 | for folder in templateFolder.subfolders {
148 | let newFolder = try folder.copy(to: targetFolder)
149 |
150 | for file in newFolder.files {
151 | try replaceToken(moduleToken, in: file, with: moduleName)
152 | }
153 | }
154 |
155 | try addProjectDependency(moduleName)
156 |
157 | if moduleType == .framework {
158 | try addTargetDependency(moduleName)
159 | }
160 |
161 |
--------------------------------------------------------------------------------
/tools/start.swift:
--------------------------------------------------------------------------------
1 | #!/usr/bin/swift sh
2 |
3 | import Files // @JohnSundell ~> 3.1.0
4 | import Foundation
5 |
6 | /// Used to interact with the console in a CLI context
7 | struct Console {
8 | /// The type of output to print messages to the console
9 | enum OutputType {
10 | /// Standard Output
11 | case standard
12 | /// Standard Error
13 | case error
14 | }
15 |
16 | /// Reads the input from Standard Input
17 | static func getInput() -> String? {
18 | return String(data: FileHandle.standardInput.availableData, encoding: .utf8)?
19 | .trimmingCharacters(in: .newlines)
20 | }
21 |
22 | /// Prints the message to the specified output
23 | ///
24 | /// - parameter message: The message to print
25 | /// - parameter output: The output type to send the message to. It gets prepended with "Error: "
26 | static func writeMessage(_ message: String, to output: OutputType = .standard) {
27 | switch output {
28 | case .standard:
29 | print(message)
30 | case .error:
31 | fputs("Error: \(message)\n", stderr)
32 | }
33 | }
34 | }
35 |
36 | Console.writeMessage("What is the name of your app?")
37 | guard let appName = Console.getInput(), appName.isEmpty == false else {
38 | Console.writeMessage("There must be an app name entered")
39 | exit(EXIT_FAILURE)
40 | }
41 |
42 | func replaceToken(_ token: String, in file: File, with name: String) throws {
43 | if let fileContents = try? file.readAsString(), fileContents.contains(token) {
44 | let replacedContents = fileContents.replacingOccurrences(of: token, with: name)
45 | try file.write(string: replacedContents)
46 | }
47 |
48 | if file.name.contains(token) {
49 | let newName = file.name.replacingOccurrences(of: token, with: name)
50 | try file.rename(to: newName)
51 | }
52 | }
53 |
54 | let appToken = "{{App-Name}}"
55 |
56 | var files = [File]()
57 | files.append(contentsOf: Folder.current.files)
58 |
59 | let modulesFolder = try Folder.current.subfolder(atPath: "Modules")
60 | files.append(contentsOf: modulesFolder.files)
61 |
62 | let appFolder = try Folder.current.subfolder(atPath: "Modules/App")
63 | files.append(contentsOf: appFolder.files)
64 |
65 | for folder in appFolder.subfolders {
66 | files.append(contentsOf: folder.files)
67 | }
68 |
69 | for file in files {
70 | try replaceToken(appToken, in: file, with: appName)
71 | }
72 |
--------------------------------------------------------------------------------