Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SASU-0127] - Tuist Migration #129 #130

Merged
merged 14 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions .github/workflows/ios-build-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ jobs:
xcode-version: latest-stable
- name: Checkout
uses: actions/checkout@v3
- name: Xcodegen
uses: xavierLowmiller/xcodegen-action@1.1.2
- name: tuist Fetch
uses: tuist/tuist-action@0.13.0
with:
spec: project.yml
quiet: true
version: 'latest'
- name: Generate Project
run: |
xcodegen generate
command: 'fetch'
- name: tuist Generate
uses: tuist/[email protected]
with:
command: 'generate'
- name: Build
run: |
xcodebuild -scheme SampleAppSwiftUI clean build -sdk iphoneos -configuration Development CODE_SIGNING_ALLOWED=No -destination 'generic/platform=iOS Simulator' CONFIGURATION_BUILD_DIR=$PWD/build
Expand Down
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,17 @@ iOSInjectionProject/
*.xcodeproj
SampleAppSwiftUI.xcodeproj
SampleAppSwiftUI.xcworkspace


# Tuist
# Since we now generate .xcodeproj and .xcworkspace files with Tuist, git shouldn't track following files.
# **/Derived folder created on each project generation so git shouldn't track it

**/*.xcodeproj
**/*.xcworkspace
**/Derived/
Tuist/Dependencies/
Tuist/Dependencies/SwiftPackageManager
Tuist/Dependencies/graph.json
Tuist/.swiftpm
Tuist/Package.resolved
32 changes: 32 additions & 0 deletions .package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"pins" : [
{
"identity" : "cocoalumberjack",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CocoaLumberjack/CocoaLumberjack",
"state" : {
"revision" : "363ed23d19a931809ea834a7d722da830353806a",
"version" : "3.8.2"
}
},
{
"identity" : "pulse",
"kind" : "remoteSourceControl",
"location" : "https://github.com/kean/Pulse",
"state" : {
"revision" : "e8bc65bd43d1f32aef533e723f2d324830431120",
"version" : "3.7.3"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log.git",
"state" : {
"revision" : "532d8b529501fb73a2455b179e0bbb6d49b652ed",
"version" : "1.5.3"
}
}
],
"version" : 2
}
1 change: 1 addition & 0 deletions .tuist-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.35.2
26 changes: 26 additions & 0 deletions Projects/SampleAppSwiftUI/Project.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import ProjectDescription
import ProjectDescriptionHelpers

let project = Project.createAppProject(
name: "SampleAppSwiftUI",
projectPackages: [
Package.remote(url: "https://github.com/CocoaLumberjack/CocoaLumberjack", requirement: .upToNextMajor(from: "3.8.0")),
Package.remote(url: "https://github.com/kean/Pulse", requirement: .upToNextMajor(from: "3.0.0")),
Package.remote(url: "https://github.com/apple/swift-log.git", requirement: .upToNextMajor(from: "1.5.2"))
],
projectSettings: .projectSettings,
destinations: [.iPhone, .iPad, .macWithiPadDesign],
deploymentTargets: .iOS("16.0"),
appTargetScripts: [
.pre(path: .relativeToRoot("scripts/installation/swiftlint.sh"), name: "SwiftLint", basedOnDependencyAnalysis: false)
],
appTargetSettings: .targetSettings,
dependencies: [
.package(product: "CocoaLumberjack"),
.package(product: "CocoaLumberjackSwift"),
.package(product: "CocoaLumberjackSwiftLogBackend"),
.package(product: "PulseUI")
],
hasUnitTestTarget: true,
hasUITestTarget: true
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974

PRODUCT_BUNDLE_IDENTIFIER = com.adesso.SampleAppSwiftUI

base_url = https:/$()/min-api.cryptocompare.com/data/

webSocket_base_url = wss:/$()/streamer.cryptocompare.com/v2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension UIDevice {
return identifier + String(UnicodeScalar(UInt8(value)))
}

// swiftlint:disable:next function_body_length
// swiftlint:disable function_body_length cyclomatic_complexity line_length switch_case_alignment
func mapToDevice(identifier: String) -> String {
switch identifier {
case "iPhone6,1", "iPhone6,2":
Expand Down Expand Up @@ -98,6 +98,7 @@ extension UIDevice {
return identifier
}
}
// swiftlint:enable function_body_length cyclomatic_complexity line_length switch_case_alignment

return mapToDevice(identifier: identifier)
}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ final class NetworkLoaderTests: XCTestCase {
return (session, sut)
}

private func expect(_ sut: NetworkLoaderProtocol, toCompleteWith expectedError: AdessoError, using requestObject: RequestObject, when action: () -> Void, file: StaticString = #filePath, line: UInt = #line) {
private func expect(_ sut: NetworkLoaderProtocol,
toCompleteWith expectedError: AdessoError,
using requestObject: RequestObject,
when action: () -> Void,
file: StaticString = #filePath,
line: UInt = #line) {
let expectation = expectation(description: "Wait for request")

Task {
Expand Down
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,25 @@ This is the iOS SwiftUI Sample App created by adesso Turkey. The project serves
- [MacOS Ventura (13.4 or higher)](https://www.apple.com/macos/ventura/features/)
- [Xcode 15 or higher](https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes)
- [Swiftlint][github/swiftlint]
- [XcodeGen](https://github.com/yonaskolb/XcodeGen)
- [tuist](https://github.com/tuist/tuist)

## Installation

Because XcodeGen is used in this project, there will be no `.xcodeproj` or `.xcworkspace` files when it first cloned. To generate them using the `project.yml` file, run
Because `tuist` is used in this project, there will be no `.xcodeproj` or `.xcworkspace` files when it first cloned. To generate them using the [tuist manifest files](https://docs.tuist.io/tutorial/get-started) (like `Workspace.swift`, `Project.swift` etc.), first run

```sh
xcodegen
tuist fetch
```

to fetch swift package dependencies and after that you can run

```sh
tuist generate
```

to generate your project. Don't forget to run these tuist commands in the root directory of the project!


Swiftlint can also be installed via included scripts in the repository. Under the `{project_root}/scripts/installation` directory, simply run:

```
Expand Down Expand Up @@ -102,7 +111,7 @@ Gitflow is a legacy Git workflow that was originally a disruptive and novel stra

## Useful Tools and Resources

- [XcodeGen](https://github.com/yonaskolb/XcodeGen) - XcodeGen is a command line tool written in Swift that generates your Xcode project using your folder structure and a project spec.
- [tuist](https://github.com/tuist/tuist) - Tuist is a command line tool that helps you generate, maintain and interact with Xcode projects. It's open source and written in Swift.
- [SwiftLint][github/swiftlint] - A tool to enforce Swift style and conventions.
- [TestFlight](https://help.apple.com/itunes-connect/developer/#/devdc42b26b8) - TestFlight beta testing lets you distribute beta builds of your app to testers and collect feedback.
- [GithubActions](https://github.com/features/actions) - CI/CD faeature to build, test, and deploy your code right from GitHub.
Expand Down
13 changes: 13 additions & 0 deletions Tuist/Dependencies.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// swift-tools-version: 5.9

import ProjectDescription
import ProjectDescriptionHelpers

let dependencies = Dependencies(
swiftPackageManager: .init(
projectOptions: [
"LocalSwiftPackage": .options(disableSynthesizedResourceAccessors: false),
]
),
platforms: [.iOS]
)
8 changes: 8 additions & 0 deletions Tuist/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// swift-tools-version: 5.9

import PackageDescription

let package = Package(
name: "PackageName",
dependencies: []
)
42 changes: 42 additions & 0 deletions Tuist/ProjectDescriptionHelpers/BuildEnvironment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Foundation
import ProjectDescription

public enum BuildEnvironment: String, CaseIterable {
case appStore, development, production

public var name: String { rawValue.firstUppercased }

public var configurationName: ConfigurationName {
ConfigurationName(stringLiteral: name)
}

public var targetConfigPath: Path {
.relativeToRoot("Projects/SampleAppSwiftUI/SampleAppSwiftUI/Configs/\(name).xcconfig")
}

public var targetConfiguration: Configuration {
switch self {
case .appStore:
return .release(name: configurationName, xcconfig: targetConfigPath)
case .development:
return .debug(name: configurationName, xcconfig: targetConfigPath)
case .production:
return .debug(name: configurationName, xcconfig: targetConfigPath)
}
}

public var projectConfiguration: Configuration {
switch self {
case .appStore:
return .release(name: configurationName)
case .development:
return .debug(name: configurationName)
case .production:
return .debug(name: configurationName)
}
}
}

extension StringProtocol {
public var firstUppercased: String { prefix(1).uppercased() + dropFirst() }
}
92 changes: 92 additions & 0 deletions Tuist/ProjectDescriptionHelpers/Project+Templates.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import Foundation
import ProjectDescription

extension Project {

static func generateBundleId(for target: String) -> String {
"com.adesso.\(target)"
}

public static func createAppProject(
name: String,
projectPackages: [Package] = [],
projectSettings: Settings?,
destinations: Destinations,
deploymentTargets: DeploymentTargets?,
appTargetScripts: [TargetScript] = [],
appTargetSettings: Settings?,
dependencies: [TargetDependency] = [],
hasUnitTestTarget: Bool,
hasUITestTarget: Bool
) -> Project {
var targets: [Target] = []

let appTarget = Target(
name: name,
destinations: destinations,
product: .app,
productName: name,
bundleId: "$(PRODUCT_BUNDLE_IDENTIFIER)",
deploymentTargets: deploymentTargets,
infoPlist: .file(path: .relativeToRoot("Projects/\(name)/\(name)/Info.plist")),
sources: SourceFilesList.paths([.relativeToRoot("Projects/\(name)/\(name)/**")]),
resources: ResourceFileElements(
resources: [
ResourceFileElement.glob(pattern: .relativeToRoot("Projects/\(name)/\(name)/Resources/**"))
]
),
scripts: appTargetScripts,
dependencies: dependencies,
settings: appTargetSettings
)

targets.append(appTarget)

if hasUnitTestTarget {
let unitTestTargetName = "\(name)Tests"
let unitTestTarget = Target(
name: unitTestTargetName,
destinations: destinations,
product: .unitTests,
productName: unitTestTargetName,
bundleId: generateBundleId(for: unitTestTargetName),
deploymentTargets: deploymentTargets,
infoPlist: .file(path: .relativeToRoot("Projects/\(name)/\(unitTestTargetName)/Info.plist")),
sources: SourceFilesList.paths([.relativeToRoot("Projects/\(name)/\(unitTestTargetName)/**")]),
dependencies: dependencies
)

targets.append(unitTestTarget)
}

if hasUITestTarget {
let uiTestTargetName = "\(name)UITests"
let uiTestTarget = Target(
name: uiTestTargetName,
destinations: destinations,
product: .uiTests,
productName: uiTestTargetName,
bundleId: generateBundleId(for: uiTestTargetName),
deploymentTargets: deploymentTargets,
infoPlist: .file(path: .relativeToRoot("Projects/\(name)/\(uiTestTargetName)/Info.plist")),
sources: SourceFilesList.paths([.relativeToRoot("Projects/\(name)/\(uiTestTargetName)/**")])
)

targets.append(uiTestTarget)
}

return Project(
name: name,
options: .options(
automaticSchemesOptions: .disabled,
disableBundleAccessors: true,
disableSynthesizedResourceAccessors: true
),
packages: projectPackages,
settings: projectSettings,
targets: targets,
schemes: [Scheme.createScheme(for: name, executable: name, hasUnitTestTarget: hasUnitTestTarget, hasUITestTarget: hasUITestTarget)]
// schemes: Scheme.allSchemes(for: name, hasUnitTestTarget: hasUnitTestTarget, hasUITestTarget: hasUITestTarget) // MARK: If you want to create separate scheme for all BuildEnvironment use this method
)
}
}
Loading
Loading