Swiftformat update (#3782)
* Update swiftformat binary * Add swiftformat rules * Run format swift * Format files which used to be excluded * fixup! extensionacl * fixup! Format * Fix lint issues * Make linting errors in app_with_framework_where_framework_failing_swiftlint
This commit is contained in:
parent
e68096b431
commit
67406d6e7d
|
@ -1,7 +1,7 @@
|
|||
# file options
|
||||
|
||||
--symlinks ignore
|
||||
--exclude Tests/XCTestManifests.swift,projects/tuist/fixtures/,projects/tuist/features/,Project.swift
|
||||
--exclude Tests/XCTestManifests.swift,projects/tuist/features,projects/tuist/fixtures/app_with_framework_where_framework_failing_swiftlint
|
||||
|
||||
# format options
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
|||
--semicolons inline
|
||||
--stripunusedargs always
|
||||
--trimwhitespace always
|
||||
--wraparguments preserve
|
||||
--wrapcollections preserve
|
||||
--wraparguments before-first
|
||||
--maxwidth 130
|
||||
--wrapcollections before-first
|
||||
--wraparguments before-first
|
||||
--extensionacl on-declarations
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.43.5
|
||||
0.48.18
|
||||
|
|
|
@ -16,6 +16,9 @@ identifier_name:
|
|||
min_length:
|
||||
error: 1
|
||||
warning: 1
|
||||
max_length:
|
||||
warning: 60
|
||||
error: 80
|
||||
inclusive_language:
|
||||
override_allowed_terms:
|
||||
- masterKey
|
||||
|
|
896
Project.swift
896
Project.swift
|
@ -44,459 +44,459 @@ func targets() -> [Target] {
|
|||
]
|
||||
),
|
||||
]
|
||||
+ [
|
||||
Target.module(
|
||||
name: "TuistSupport",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.external(name: "ArgumentParser"),
|
||||
.external(name: "Checksum"),
|
||||
.external(name: "CombineExt"),
|
||||
.external(name: "CryptoSwift"),
|
||||
.external(name: "GraphViz"),
|
||||
.external(name: "KeychainAccess"),
|
||||
.external(name: "Logging"),
|
||||
.external(name: "PathKit"),
|
||||
.external(name: "Queuer"),
|
||||
.external(name: "RxBlocking"),
|
||||
.external(name: "RxRelay"),
|
||||
.external(name: "RxSwift"),
|
||||
.external(name: "Signals"),
|
||||
.external(name: "Stencil"),
|
||||
.external(name: "StencilSwiftKit"),
|
||||
.external(name: "Swifter"),
|
||||
.external(name: "SwiftToolsSupport-auto"),
|
||||
.external(name: "XcodeProj"),
|
||||
.external(name: "Zip"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistKit",
|
||||
hasTesting: false,
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGenerator"),
|
||||
.target(name: "TuistCache"),
|
||||
.target(name: "TuistAutomation"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "ProjectAutomation"),
|
||||
.target(name: "TuistLoader"),
|
||||
.target(name: "TuistScaffold"),
|
||||
.target(name: "TuistSigning"),
|
||||
.target(name: "TuistDependencies"),
|
||||
.target(name: "TuistLinting"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistMigration"),
|
||||
.target(name: "TuistAsyncQueue"),
|
||||
.target(name: "TuistAnalytics"),
|
||||
.target(name: "TuistPlugin"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistTasks"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistAutomation"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "ProjectAutomation"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistCacheTesting"),
|
||||
.target(name: "TuistGeneratorTesting"),
|
||||
.target(name: "TuistScaffoldTesting"),
|
||||
.target(name: "TuistCloudTesting"),
|
||||
.target(name: "TuistAutomationTesting"),
|
||||
.target(name: "TuistSigningTesting"),
|
||||
.target(name: "TuistDependenciesTesting"),
|
||||
.target(name: "TuistLintingTesting"),
|
||||
.target(name: "TuistMigrationTesting"),
|
||||
.target(name: "TuistAsyncQueueTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistPlugin"),
|
||||
.target(name: "TuistPluginTesting"),
|
||||
.target(name: "TuistTasksTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "ProjectAutomation"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistCloudTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistEnvKit",
|
||||
hasTesting: false,
|
||||
dependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistGraph",
|
||||
dependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistCore",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGraph"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting")
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistGenerator",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.external(name: "SwiftGenKit"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSigningTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistCloud",
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistTasks",
|
||||
hasTests: false,
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistCache",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistScaffold",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistLoader",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "ProjectDescription"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistAsyncQueue",
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistPlugin",
|
||||
dependencies: [
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistLoader"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistScaffold"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistLoader"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistScaffoldTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraph"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "ProjectDescription",
|
||||
hasTesting: false,
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistSupport"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "ProjectAutomation",
|
||||
hasTests: false,
|
||||
hasTesting: false
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistSigning",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistAnalytics",
|
||||
hasTesting: false,
|
||||
dependencies: [
|
||||
.target(name: "TuistAsyncQueue"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistLoader"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistMigration",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistLinting",
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistDependencies",
|
||||
dependencies: [
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistAutomation",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting")
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
)
|
||||
]
|
||||
.flatMap { $0 }
|
||||
+ [
|
||||
Target.module(
|
||||
name: "TuistSupport",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.external(name: "ArgumentParser"),
|
||||
.external(name: "Checksum"),
|
||||
.external(name: "CombineExt"),
|
||||
.external(name: "CryptoSwift"),
|
||||
.external(name: "GraphViz"),
|
||||
.external(name: "KeychainAccess"),
|
||||
.external(name: "Logging"),
|
||||
.external(name: "PathKit"),
|
||||
.external(name: "Queuer"),
|
||||
.external(name: "RxBlocking"),
|
||||
.external(name: "RxRelay"),
|
||||
.external(name: "RxSwift"),
|
||||
.external(name: "Signals"),
|
||||
.external(name: "Stencil"),
|
||||
.external(name: "StencilSwiftKit"),
|
||||
.external(name: "Swifter"),
|
||||
.external(name: "SwiftToolsSupport-auto"),
|
||||
.external(name: "XcodeProj"),
|
||||
.external(name: "Zip"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistKit",
|
||||
hasTesting: false,
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGenerator"),
|
||||
.target(name: "TuistCache"),
|
||||
.target(name: "TuistAutomation"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "ProjectAutomation"),
|
||||
.target(name: "TuistLoader"),
|
||||
.target(name: "TuistScaffold"),
|
||||
.target(name: "TuistSigning"),
|
||||
.target(name: "TuistDependencies"),
|
||||
.target(name: "TuistLinting"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistMigration"),
|
||||
.target(name: "TuistAsyncQueue"),
|
||||
.target(name: "TuistAnalytics"),
|
||||
.target(name: "TuistPlugin"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistTasks"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistAutomation"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "ProjectAutomation"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistCacheTesting"),
|
||||
.target(name: "TuistGeneratorTesting"),
|
||||
.target(name: "TuistScaffoldTesting"),
|
||||
.target(name: "TuistCloudTesting"),
|
||||
.target(name: "TuistAutomationTesting"),
|
||||
.target(name: "TuistSigningTesting"),
|
||||
.target(name: "TuistDependenciesTesting"),
|
||||
.target(name: "TuistLintingTesting"),
|
||||
.target(name: "TuistMigrationTesting"),
|
||||
.target(name: "TuistAsyncQueueTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistPlugin"),
|
||||
.target(name: "TuistPluginTesting"),
|
||||
.target(name: "TuistTasksTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "ProjectAutomation"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistCloudTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistEnvKit",
|
||||
hasTesting: false,
|
||||
dependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistGraph",
|
||||
dependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistCore",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGraph"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistGenerator",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.external(name: "SwiftGenKit"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSigningTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistCloud",
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistTasks",
|
||||
hasTests: false,
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistCache",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistScaffold",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistLoader",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "ProjectDescription"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistAsyncQueue",
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistPlugin",
|
||||
dependencies: [
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistLoader"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistScaffold"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistLoader"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistSupport"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistScaffoldTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraph"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "ProjectDescription",
|
||||
hasTesting: false,
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistSupport"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "ProjectAutomation",
|
||||
hasTests: false,
|
||||
hasTesting: false
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistSigning",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistAnalytics",
|
||||
hasTesting: false,
|
||||
dependencies: [
|
||||
.target(name: "TuistAsyncQueue"),
|
||||
.target(name: "TuistCloud"),
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistLoader"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistMigration",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistLinting",
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistDependencies",
|
||||
dependencies: [
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
.target(name: "TuistLoaderTesting"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
Target.module(
|
||||
name: "TuistAutomation",
|
||||
hasIntegrationTests: true,
|
||||
dependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistGraph"),
|
||||
.target(name: "TuistSupport"),
|
||||
],
|
||||
testDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
testingDependencies: [
|
||||
.target(name: "TuistCore"),
|
||||
.target(name: "TuistCoreTesting"),
|
||||
.target(name: "ProjectDescription"),
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
],
|
||||
integrationTestsDependencies: [
|
||||
.target(name: "TuistSupportTesting"),
|
||||
.target(name: "TuistGraphTesting"),
|
||||
]
|
||||
),
|
||||
]
|
||||
.flatMap { $0 }
|
||||
}
|
||||
|
||||
let project = Project(
|
||||
name: "Tuist",
|
||||
options: [
|
||||
.textSettings(indentWidth: 4, tabWidth: 4)
|
||||
.textSettings(indentWidth: 4, tabWidth: 4),
|
||||
],
|
||||
settings: .settings(
|
||||
configurations: [
|
||||
|
|
|
@ -52,7 +52,11 @@ public enum CompatibleXcodeVersions: ExpressibleByArrayLiteral, ExpressibleByStr
|
|||
case "list":
|
||||
self = .list(try container.decode([String].self, forKey: .value))
|
||||
default:
|
||||
throw DecodingError.dataCorruptedError(forKey: CodignKeys.type, in: container, debugDescription: "Invalid type \(type)")
|
||||
throw DecodingError.dataCorruptedError(
|
||||
forKey: CodignKeys.type,
|
||||
in: container,
|
||||
debugDescription: "Invalid type \(type)"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ public struct Config: Codable, Equatable {
|
|||
}
|
||||
|
||||
extension Config.GenerationOptions {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
internal enum CodingKeys: String, CodingKey {
|
||||
case xcodeProjectName
|
||||
case organizationName
|
||||
case developmentRegion
|
||||
|
@ -115,6 +115,7 @@ extension Config.GenerationOptions {
|
|||
case lastXcodeUpgradeCheck
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
|
@ -130,30 +131,36 @@ extension Config.GenerationOptions {
|
|||
var associatedValues = try container.nestedUnkeyedContainer(forKey: .developmentRegion)
|
||||
let developmentRegion = try associatedValues.decode(String.self)
|
||||
self = .developmentRegion(developmentRegion)
|
||||
} else if container.allKeys.contains(.disableAutogeneratedSchemes), try container.decode(Bool.self, forKey: .disableAutogeneratedSchemes) {
|
||||
} else if container.allKeys.contains(.disableAutogeneratedSchemes),
|
||||
try container.decode(Bool.self, forKey: .disableAutogeneratedSchemes)
|
||||
{
|
||||
self = .disableAutogeneratedSchemes
|
||||
} else if container.allKeys.contains(.disableSynthesizedResourceAccessors),
|
||||
try container.decode(Bool.self, forKey: .disableSynthesizedResourceAccessors)
|
||||
try container.decode(Bool.self, forKey: .disableSynthesizedResourceAccessors)
|
||||
{
|
||||
self = .disableSynthesizedResourceAccessors
|
||||
} else if container.allKeys.contains(.disableShowEnvironmentVarsInScriptPhases),
|
||||
try container.decode(Bool.self, forKey: .disableShowEnvironmentVarsInScriptPhases)
|
||||
try container.decode(Bool.self, forKey: .disableShowEnvironmentVarsInScriptPhases)
|
||||
{
|
||||
self = .disableShowEnvironmentVarsInScriptPhases
|
||||
} else if container.allKeys.contains(.enableCodeCoverage) {
|
||||
let mode = try container.decode(CodeCoverageMode.self, forKey: .enableCodeCoverage)
|
||||
self = .enableCodeCoverage(mode)
|
||||
} else if container.allKeys.contains(.disablePackageVersionLocking), try container.decode(Bool.self, forKey: .disablePackageVersionLocking) {
|
||||
} else if container.allKeys.contains(.disablePackageVersionLocking),
|
||||
try container.decode(Bool.self, forKey: .disablePackageVersionLocking)
|
||||
{
|
||||
self = .disablePackageVersionLocking
|
||||
} else if container.allKeys.contains(.resolveDependenciesWithSystemScm),
|
||||
try container.decode(Bool.self, forKey: .resolveDependenciesWithSystemScm)
|
||||
try container.decode(Bool.self, forKey: .resolveDependenciesWithSystemScm)
|
||||
{
|
||||
self = .resolveDependenciesWithSystemScm
|
||||
} else if container.allKeys.contains(.disableBundleAccessors),
|
||||
try container.decode(Bool.self, forKey: .disableBundleAccessors)
|
||||
try container.decode(Bool.self, forKey: .disableBundleAccessors)
|
||||
{
|
||||
self = .disableBundleAccessors
|
||||
} else if container.allKeys.contains(.lastXcodeUpgradeCheck), try container.decodeNil(forKey: .lastXcodeUpgradeCheck) == false {
|
||||
} else if container.allKeys.contains(.lastXcodeUpgradeCheck),
|
||||
try container.decodeNil(forKey: .lastXcodeUpgradeCheck) == false
|
||||
{
|
||||
var associatedValues = try container.nestedUnkeyedContainer(forKey: .lastXcodeUpgradeCheck)
|
||||
let version = try associatedValues.decode(Version.self)
|
||||
self = .lastXcodeUpgradeCheck(version)
|
||||
|
@ -197,7 +204,7 @@ extension Config.GenerationOptions {
|
|||
}
|
||||
|
||||
extension Config.GenerationOptions.CodeCoverageMode {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
internal enum CodingKeys: String, CodingKey {
|
||||
case all
|
||||
case relevant
|
||||
case targets
|
||||
|
|
|
@ -25,14 +25,14 @@ public struct ConfigurationName: ExpressibleByStringLiteral, Codable, Equatable
|
|||
|
||||
// Defaults provided by Tuist
|
||||
|
||||
public extension ConfigurationName {
|
||||
extension ConfigurationName {
|
||||
/// Returns a configuration named "Debug"
|
||||
static var debug: ConfigurationName {
|
||||
public static var debug: ConfigurationName {
|
||||
ConfigurationName("Debug")
|
||||
}
|
||||
|
||||
// Returns a configuration named "Release"
|
||||
static var release: ConfigurationName {
|
||||
public static var release: ConfigurationName {
|
||||
ConfigurationName("Release")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ extension CarthageDependencies: ExpressibleByArrayLiteral {
|
|||
|
||||
// MARK: - CarthageDependencies.Dependency & CarthageDependencies.Requirement & CarthageDependencies.Options
|
||||
|
||||
public extension CarthageDependencies {
|
||||
extension CarthageDependencies {
|
||||
/// Specifies origin of Carthage dependency.
|
||||
enum Dependency: Codable, Equatable {
|
||||
public enum Dependency: Codable, Equatable {
|
||||
/// GitHub repositories (both GitHub.com and GitHub Enterprise).
|
||||
case github(path: String, requirement: Requirement)
|
||||
/// Other Git repositories.
|
||||
|
@ -34,7 +34,7 @@ public extension CarthageDependencies {
|
|||
}
|
||||
|
||||
/// Specifies version requirement for Carthage dependency.
|
||||
enum Requirement: Codable, Equatable {
|
||||
public enum Requirement: Codable, Equatable {
|
||||
case exact(Version)
|
||||
case upToNext(Version)
|
||||
case atLeast(Version)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Foundation
|
||||
|
||||
@dynamicMemberLookup
|
||||
public struct Environment {
|
||||
public enum Environment {
|
||||
public enum Value: Equatable {
|
||||
case boolean(Bool)
|
||||
case string(String)
|
||||
|
@ -26,12 +26,12 @@ public struct Environment {
|
|||
}
|
||||
}
|
||||
|
||||
public extension Optional where Wrapped == Environment.Value {
|
||||
extension Optional where Wrapped == Environment.Value {
|
||||
/// Retrieve the Environment value as a string or return the specified default string value
|
||||
/// - Parameters:
|
||||
/// - default: default String value to be returned
|
||||
/// - Returns: String
|
||||
func getString(default defaultString: String) -> String {
|
||||
public func getString(default defaultString: String) -> String {
|
||||
if case let .string(value) = self { return value }
|
||||
return defaultString
|
||||
}
|
||||
|
@ -40,15 +40,15 @@ public extension Optional where Wrapped == Environment.Value {
|
|||
/// - Parameters:
|
||||
/// - default: default Boolean value to be returned
|
||||
/// - Returns: Bool
|
||||
func getBoolean(default defaultBoolean: Bool) -> Bool {
|
||||
public func getBoolean(default defaultBoolean: Bool) -> Bool {
|
||||
if case let .boolean(value) = self { return value }
|
||||
return defaultBoolean
|
||||
}
|
||||
}
|
||||
|
||||
private extension String {
|
||||
extension String {
|
||||
// Taken from https://github.com/apple/swift/blob/88b093e9d77d6201935a2c2fb13f27d961836777/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L161
|
||||
func camelCaseToSnakeCase() -> String {
|
||||
fileprivate func camelCaseToSnakeCase() -> String {
|
||||
guard !isEmpty else { return self }
|
||||
|
||||
var words: [Range<String.Index>] = []
|
||||
|
@ -68,7 +68,8 @@ private extension String {
|
|||
|
||||
// Find next lowercase character
|
||||
searchRange = upperCaseRange.lowerBound ..< searchRange.upperBound
|
||||
guard let lowerCaseRange = rangeOfCharacter(from: CharacterSet.lowercaseLetters, options: [], range: searchRange) else {
|
||||
guard let lowerCaseRange = rangeOfCharacter(from: CharacterSet.lowercaseLetters, options: [], range: searchRange)
|
||||
else {
|
||||
// There are no more lower case letters. Just end here.
|
||||
wordStart = searchRange.lowerBound
|
||||
break
|
||||
|
|
|
@ -21,8 +21,8 @@ public struct LaunchArgument: Equatable, Codable {
|
|||
}
|
||||
}
|
||||
|
||||
internal extension Array where Element == LaunchArgument {
|
||||
init(launchArguments: [String: Bool]) {
|
||||
extension Array where Element == LaunchArgument {
|
||||
internal init(launchArguments: [String: Bool]) {
|
||||
self = launchArguments.map(LaunchArgument.init)
|
||||
.sorted { $0.name < $1.name }
|
||||
}
|
||||
|
|
|
@ -13,24 +13,24 @@ public struct SchemeLanguage: Codable, Equatable, ExpressibleByStringLiteral {
|
|||
}
|
||||
|
||||
// Pre-defined languages
|
||||
public extension SchemeLanguage {
|
||||
static var doubleLengthPseudoLanguage: SchemeLanguage {
|
||||
extension SchemeLanguage {
|
||||
public static var doubleLengthPseudoLanguage: SchemeLanguage {
|
||||
SchemeLanguage(identifier: "IDELaunchSchemeLanguageDoubleLocalizedStrings")
|
||||
}
|
||||
|
||||
static var rightToLeftPseudoLanguage: SchemeLanguage {
|
||||
public static var rightToLeftPseudoLanguage: SchemeLanguage {
|
||||
SchemeLanguage(identifier: "IDELaunchSchemeLanguageRightToLeftLayoutDirection")
|
||||
}
|
||||
|
||||
static var accentedPseudoLanguage: SchemeLanguage {
|
||||
public static var accentedPseudoLanguage: SchemeLanguage {
|
||||
SchemeLanguage(identifier: "IDELaunchSchemeLanguageAccentedLatin")
|
||||
}
|
||||
|
||||
static var boundedStringPseudoLanguage: SchemeLanguage {
|
||||
public static var boundedStringPseudoLanguage: SchemeLanguage {
|
||||
SchemeLanguage(identifier: "IDELaunchSchemeLanguageBoundedString")
|
||||
}
|
||||
|
||||
static var rightToLeftWithStringsPseudoLanguage: SchemeLanguage {
|
||||
public static var rightToLeftWithStringsPseudoLanguage: SchemeLanguage {
|
||||
SchemeLanguage(identifier: "IDELaunchSchemeLanguageRLO")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ public typealias SettingsDictionary = [String: SettingValue]
|
|||
|
||||
// MARK: - SettingValue
|
||||
|
||||
public enum SettingValue: ExpressibleByStringInterpolation, ExpressibleByArrayLiteral, ExpressibleByBooleanLiteral, Equatable, Codable {
|
||||
public enum SettingValue: ExpressibleByStringInterpolation, ExpressibleByArrayLiteral, ExpressibleByBooleanLiteral, Equatable,
|
||||
Codable
|
||||
{
|
||||
case string(String)
|
||||
case array([String])
|
||||
|
||||
|
@ -86,7 +88,9 @@ public struct Configuration: Equatable, Codable {
|
|||
/// - settings: The base build settings to apply
|
||||
/// - xcconfig: The xcconfig file to associate with this configuration
|
||||
/// - Returns: A debug `CustomConfiguration`
|
||||
public static func debug(name: ConfigurationName, settings: SettingsDictionary = [:], xcconfig: Path? = nil) -> Configuration {
|
||||
public static func debug(name: ConfigurationName, settings: SettingsDictionary = [:],
|
||||
xcconfig: Path? = nil) -> Configuration
|
||||
{
|
||||
return Configuration(
|
||||
name: name,
|
||||
variant: .debug,
|
||||
|
@ -102,7 +106,9 @@ public struct Configuration: Equatable, Codable {
|
|||
/// - settings: The base build settings to apply
|
||||
/// - xcconfig: The xcconfig file to associate with this configuration
|
||||
/// - Returns: A release `CustomConfiguration`
|
||||
public static func release(name: ConfigurationName, settings: SettingsDictionary = [:], xcconfig: Path? = nil) -> Configuration {
|
||||
public static func release(name: ConfigurationName, settings: SettingsDictionary = [:],
|
||||
xcconfig: Path? = nil) -> Configuration
|
||||
{
|
||||
return Configuration(
|
||||
name: name,
|
||||
variant: .release,
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import Foundation
|
||||
|
||||
public extension SettingsDictionary {
|
||||
mutating func merge(_ other: SettingsDictionary) {
|
||||
extension SettingsDictionary {
|
||||
public mutating func merge(_ other: SettingsDictionary) {
|
||||
merge(other) { $1 }
|
||||
}
|
||||
|
||||
func merging(_ other: SettingsDictionary) -> SettingsDictionary {
|
||||
public func merging(_ other: SettingsDictionary) -> SettingsDictionary {
|
||||
merging(other) { $1 }
|
||||
}
|
||||
}
|
||||
|
||||
private extension SettingValue {
|
||||
init(_ string: String) {
|
||||
extension SettingValue {
|
||||
fileprivate init(_ string: String) {
|
||||
self = .init(stringLiteral: string)
|
||||
}
|
||||
|
||||
init(_ bool: Bool) {
|
||||
fileprivate init(_ bool: Bool) {
|
||||
self = .init(booleanLiteral: bool)
|
||||
}
|
||||
}
|
||||
|
@ -31,11 +31,11 @@ public enum SwiftOptimizationLevel: String {
|
|||
case oSize = "-Osize"
|
||||
}
|
||||
|
||||
public extension SettingsDictionary {
|
||||
extension SettingsDictionary {
|
||||
// MARK: - Code signing
|
||||
|
||||
/// Sets `"CODE_SIGN_STYLE"` to `"Manual"`,` "CODE_SIGN_IDENTITY"` to `identity`, and `"PROVISIONING_PROFILE_SPECIFIER"` to `provisioningProfileSpecifier`
|
||||
func manualCodeSigning(identity: String? = nil, provisioningProfileSpecifier: String? = nil) -> SettingsDictionary {
|
||||
public func manualCodeSigning(identity: String? = nil, provisioningProfileSpecifier: String? = nil) -> SettingsDictionary {
|
||||
var manualCodeSigning: SettingsDictionary = ["CODE_SIGN_STYLE": "Manual"]
|
||||
manualCodeSigning["PROVISIONING_PROFILE_SPECIFIER"] = provisioningProfileSpecifier.map { SettingValue($0) }
|
||||
|
||||
|
@ -49,7 +49,7 @@ public extension SettingsDictionary {
|
|||
}
|
||||
|
||||
/// Sets `"CODE_SIGN_STYLE"` to `"Automatic"` and `"DEVELOPMENT_TEAM"` to `devTeam`
|
||||
func automaticCodeSigning(devTeam: String) -> SettingsDictionary {
|
||||
public func automaticCodeSigning(devTeam: String) -> SettingsDictionary {
|
||||
merging([
|
||||
"CODE_SIGN_STYLE": "Automatic",
|
||||
"DEVELOPMENT_TEAM": SettingValue(devTeam),
|
||||
|
@ -57,29 +57,29 @@ public extension SettingsDictionary {
|
|||
}
|
||||
|
||||
/// Sets `"CODE_SIGN_IDENTITY"` to `"Apple Development"`
|
||||
func codeSignIdentityAppleDevelopment() -> SettingsDictionary {
|
||||
public func codeSignIdentityAppleDevelopment() -> SettingsDictionary {
|
||||
codeSignIdentity("Apple Development")
|
||||
}
|
||||
|
||||
/// Sets `"CODE_SIGN_IDENTITY"` to `identity`
|
||||
func codeSignIdentity(_ identity: String) -> SettingsDictionary {
|
||||
public func codeSignIdentity(_ identity: String) -> SettingsDictionary {
|
||||
merging(["CODE_SIGN_IDENTITY": SettingValue(identity)])
|
||||
}
|
||||
|
||||
// MARK: - Versioning
|
||||
|
||||
/// Sets `"CURRENT_PROJECT_VERSION"` to `version`
|
||||
func currentProjectVersion(_ version: String) -> SettingsDictionary {
|
||||
public func currentProjectVersion(_ version: String) -> SettingsDictionary {
|
||||
merging(["CURRENT_PROJECT_VERSION": SettingValue(version)])
|
||||
}
|
||||
|
||||
/// Sets `"VERSIONING_SYSTEM"` to `"apple-generic"`
|
||||
func appleGenericVersioningSystem() -> SettingsDictionary {
|
||||
public func appleGenericVersioningSystem() -> SettingsDictionary {
|
||||
merging(["VERSIONING_SYSTEM": "apple-generic"])
|
||||
}
|
||||
|
||||
/// Sets "VERSION_INFO_STRING" to `version`. If `prefix` and `suffix` are not `nil`, they're used as `"VERSION_INFO_PREFIX"` and `"VERSION_INFO_SUFFIX"` respectively.
|
||||
func versionInfo(_ version: String, prefix: String? = nil, suffix: String? = nil) -> SettingsDictionary {
|
||||
public func versionInfo(_ version: String, prefix: String? = nil, suffix: String? = nil) -> SettingsDictionary {
|
||||
var versionSettings: SettingsDictionary = ["VERSION_INFO_STRING": SettingValue(version)]
|
||||
versionSettings["VERSION_INFO_PREFIX"] = prefix.map { SettingValue($0) }
|
||||
versionSettings["VERSION_INFO_SUFFIX"] = suffix.map { SettingValue($0) }
|
||||
|
@ -90,29 +90,29 @@ public extension SettingsDictionary {
|
|||
// MARK: - Swift Settings
|
||||
|
||||
/// Sets `"SWIFT_VERSION"` to `version`
|
||||
func swiftVersion(_ version: String) -> SettingsDictionary {
|
||||
public func swiftVersion(_ version: String) -> SettingsDictionary {
|
||||
merging(["SWIFT_VERSION": SettingValue(version)])
|
||||
}
|
||||
|
||||
/// Sets `"OTHER_SWIFT_FLAGS"` to `flags`
|
||||
func otherSwiftFlags(_ flags: String...) -> SettingsDictionary {
|
||||
public func otherSwiftFlags(_ flags: String...) -> SettingsDictionary {
|
||||
merging(["OTHER_SWIFT_FLAGS": SettingValue(flags.joined(separator: " "))])
|
||||
}
|
||||
|
||||
/// Sets `"SWIFT_COMPILATION_MODE"` to the available `SwiftCompilationMode` (`"singlefile"` or `"wholemodule"`)
|
||||
func swiftCompilationMode(_ mode: SwiftCompilationMode) -> SettingsDictionary {
|
||||
public func swiftCompilationMode(_ mode: SwiftCompilationMode) -> SettingsDictionary {
|
||||
merging(["SWIFT_COMPILATION_MODE": SettingValue(mode)])
|
||||
}
|
||||
|
||||
/// Sets `"SWIFT_OPTIMIZATION_LEVEL"` to the available `SwiftOptimizationLevel` (`"-O"`, `"-Onone"` or `"-Osize"`)
|
||||
func swiftOptimizationLevel(_ level: SwiftOptimizationLevel) -> SettingsDictionary {
|
||||
public func swiftOptimizationLevel(_ level: SwiftOptimizationLevel) -> SettingsDictionary {
|
||||
merging(["SWIFT_OPTIMIZATION_LEVEL": SettingValue(level)])
|
||||
}
|
||||
|
||||
// MARK: - Bitcode
|
||||
|
||||
/// Sets `"ENABLE_BITCODE"` to `"YES"` or `"NO"`
|
||||
func bitcodeEnabled(_ enabled: Bool) -> SettingsDictionary {
|
||||
public func bitcodeEnabled(_ enabled: Bool) -> SettingsDictionary {
|
||||
merging(["ENABLE_BITCODE": SettingValue(enabled)])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,12 +124,12 @@ public struct Template: Codable, Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
public extension Template.Item {
|
||||
extension Template.Item {
|
||||
/// - Parameters:
|
||||
/// - path: Path where to generate file
|
||||
/// - contents: String Contents
|
||||
/// - Returns: `Template.Item` that is `.string`
|
||||
static func string(path: String, contents: String) -> Template.Item {
|
||||
public static func string(path: String, contents: String) -> Template.Item {
|
||||
Template.Item(path: path, contents: .string(contents))
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ public extension Template.Item {
|
|||
/// - path: Path where to generate file
|
||||
/// - templatePath: Path of file where the template is defined
|
||||
/// - Returns: `Template.Item` that is `.file`
|
||||
static func file(path: String, templatePath: Path) -> Template.Item {
|
||||
public static func file(path: String, templatePath: Path) -> Template.Item {
|
||||
Template.Item(path: path, contents: .file(templatePath))
|
||||
}
|
||||
|
||||
|
@ -145,13 +145,13 @@ public extension Template.Item {
|
|||
/// - path: Path where will be copied the folder
|
||||
/// - sourcePath: Path of folder which will be copied
|
||||
/// - Returns: `Template.Item` that is `.directory`
|
||||
static func directory(path: String, sourcePath: Path) -> Template.Item {
|
||||
public static func directory(path: String, sourcePath: Path) -> Template.Item {
|
||||
Template.Item(path: path, contents: .directory(sourcePath))
|
||||
}
|
||||
}
|
||||
|
||||
public extension String.StringInterpolation {
|
||||
mutating func appendInterpolation(_ value: Template.Attribute) {
|
||||
extension String.StringInterpolation {
|
||||
public mutating func appendInterpolation(_ value: Template.Attribute) {
|
||||
switch value {
|
||||
case let .required(name), let .optional(name, default: _):
|
||||
appendInterpolation("{{ \(name) }}")
|
||||
|
|
|
@ -6,7 +6,12 @@ public struct TestableTarget: Equatable, Codable, ExpressibleByStringInterpolati
|
|||
public let isParallelizable: Bool
|
||||
public let isRandomExecutionOrdering: Bool
|
||||
|
||||
public init(target: TargetReference, skipped: Bool = false, parallelizable: Bool = false, randomExecutionOrdering: Bool = false) {
|
||||
public init(
|
||||
target: TargetReference,
|
||||
skipped: Bool = false,
|
||||
parallelizable: Bool = false,
|
||||
randomExecutionOrdering: Bool = false
|
||||
) {
|
||||
self.target = target
|
||||
isSkipped = skipped
|
||||
isParallelizable = parallelizable
|
||||
|
|
|
@ -90,12 +90,12 @@ extension Version: CustomStringConvertible {
|
|||
}
|
||||
}
|
||||
|
||||
public extension Version {
|
||||
extension Version {
|
||||
/// Create a version object from string.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - string: The string to parse.
|
||||
init?(string: String) {
|
||||
public init?(string: String) {
|
||||
let prereleaseStartIndex = string.firstIndex(of: "-")
|
||||
let metadataStartIndex = string.firstIndex(of: "+")
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ public struct CommandEvent: Codable, Equatable, AsyncQueueEvent {
|
|||
public let machineHardwareName: String
|
||||
public let isCI: Bool
|
||||
|
||||
public let id: UUID = UUID()
|
||||
public let id = UUID()
|
||||
public let date = Date()
|
||||
public let dispatcherId = TuistAnalyticsDispatcher.dispatcherId
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import TuistAsyncQueue
|
|||
import TuistGraph
|
||||
import TuistLoader
|
||||
|
||||
public final class TuistAnalytics {
|
||||
public enum TuistAnalytics {
|
||||
public static func bootstrap(config: Config) throws {
|
||||
AsyncQueue.sharedInstance.register(dispatcher: TuistAnalyticsDispatcher(cloud: config.cloud))
|
||||
AsyncQueue.sharedInstance.start() // Re-try to send all events that got persisted and haven't been sent yet
|
||||
|
|
|
@ -22,7 +22,11 @@ public struct TuistAnalyticsDispatcher: AsyncQueueDispatching {
|
|||
if let cloud = cloud {
|
||||
backends = [
|
||||
backbone,
|
||||
TuistAnalyticsCloudBackend(config: cloud, resourceFactory: CloudAnalyticsResourceFactory(cloudConfig: cloud), client: cloudClient),
|
||||
TuistAnalyticsCloudBackend(
|
||||
config: cloud,
|
||||
resourceFactory: CloudAnalyticsResourceFactory(cloudConfig: cloud),
|
||||
client: cloudClient
|
||||
),
|
||||
]
|
||||
} else {
|
||||
backends = [backbone]
|
||||
|
|
|
@ -14,14 +14,14 @@ public protocol AsyncQueuing {
|
|||
public class AsyncQueue: AsyncQueuing {
|
||||
// MARK: - Attributes
|
||||
|
||||
private let disposeBag: DisposeBag = DisposeBag()
|
||||
private let disposeBag = DisposeBag()
|
||||
private let queue: Queuing
|
||||
private let ciChecker: CIChecking
|
||||
private let persistor: AsyncQueuePersisting
|
||||
private var dispatchers: [String: AsyncQueueDispatching] = [:]
|
||||
private let persistedEventsSchedulerType: SchedulerType
|
||||
|
||||
public static let sharedInstance: AsyncQueue = AsyncQueue()
|
||||
public static let sharedInstance = AsyncQueue()
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ final class AsyncQueuePersistor: AsyncQueuePersisting {
|
|||
// MARK: - Attributes
|
||||
|
||||
let directory: AbsolutePath
|
||||
let jsonEncoder: JSONEncoder = JSONEncoder()
|
||||
let jsonEncoder = JSONEncoder()
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
|
@ -36,7 +36,7 @@ final class AsyncQueuePersistor: AsyncQueuePersisting {
|
|||
}
|
||||
|
||||
func write<T: AsyncQueueEvent>(event: T) -> Completable {
|
||||
Completable.create { (observer) -> Disposable in
|
||||
Completable.create { observer -> Disposable in
|
||||
let path = self.directory.appending(component: self.filename(event: event))
|
||||
do {
|
||||
try self.createDirectoryIfNeeded()
|
||||
|
@ -55,7 +55,7 @@ final class AsyncQueuePersistor: AsyncQueuePersisting {
|
|||
}
|
||||
|
||||
func delete(filename: String) -> Completable {
|
||||
Completable.create { (observer) -> Disposable in
|
||||
Completable.create { observer -> Disposable in
|
||||
let path = self.directory.appending(component: filename)
|
||||
guard FileHandler.shared.exists(path) else { return Disposables.create() }
|
||||
do {
|
||||
|
@ -69,15 +69,15 @@ final class AsyncQueuePersistor: AsyncQueuePersisting {
|
|||
}
|
||||
|
||||
func readAll() -> Single<[AsyncQueueEventTuple]> {
|
||||
Single.create { (observer) -> Disposable in
|
||||
Single.create { observer -> Disposable in
|
||||
let paths = FileHandler.shared.glob(self.directory, glob: "*.json")
|
||||
var events: [AsyncQueueEventTuple] = []
|
||||
paths.forEach { eventPath in
|
||||
let fileName = eventPath.basenameWithoutExt
|
||||
let components = fileName.split(separator: ".")
|
||||
guard components.count == 3,
|
||||
let timestamp = Double(components[0]),
|
||||
let id = UUID(uuidString: String(components[2]))
|
||||
let timestamp = Double(components[0]),
|
||||
let id = UUID(uuidString: String(components[2]))
|
||||
else {
|
||||
/// Changing the naming convention is a breaking change. When detected
|
||||
/// we delete the event.
|
||||
|
|
|
@ -43,7 +43,7 @@ public class MockAsyncQueueDispatcher: AsyncQueueDispatching {
|
|||
public var invokedDispatchPersistedCount = 0
|
||||
public var invokedDispatchPersistedCallBack: () -> Void = {}
|
||||
public var invokedDispatchPersistedDataParameter: Data?
|
||||
public var invokedDispatchPersistedParametersDataList = [Data]() // swiftlint:disable:this identifier_name
|
||||
public var invokedDispatchPersistedParametersDataList = [Data]()
|
||||
public var stubbedDispatchPersistedError: Error?
|
||||
|
||||
public func dispatchPersisted(data: Data, completion: @escaping () -> Void) throws {
|
||||
|
|
|
@ -7,7 +7,7 @@ public final class MockQueuer: Queuing {
|
|||
public var invokedAddOperation = false
|
||||
public var invokedAddOperationCount = 0
|
||||
public var invokedAddOperationParameterOperation: Operation?
|
||||
public var invokedAddOperationParametersOperationsList = [Operation]() // swiftlint:disable:this identifier_name
|
||||
public var invokedAddOperationParametersOperationsList = [Operation]()
|
||||
|
||||
public func addOperation(_ operation: Operation) {
|
||||
invokedAddOperation = true
|
||||
|
@ -25,7 +25,7 @@ public final class MockQueuer: Queuing {
|
|||
}
|
||||
|
||||
public var invokedWaitUntilAllOperationsAreFinished = false
|
||||
public var invokedWaitUntilAllOperationsAreFinishedCount = 0 // swiftlint:disable:this identifier_name
|
||||
public var invokedWaitUntilAllOperationsAreFinishedCount = 0
|
||||
|
||||
public func waitUntilAllOperationsAreFinished() {
|
||||
invokedWaitUntilAllOperationsAreFinished = true
|
||||
|
|
|
@ -55,7 +55,9 @@ public protocol BuildGraphInspecting {
|
|||
public final class BuildGraphInspector: BuildGraphInspecting {
|
||||
public init() {}
|
||||
|
||||
public func buildArguments(project: Project, target: Target, configuration: String?, skipSigning: Bool) -> [XcodeBuildArgument] {
|
||||
public func buildArguments(project: Project, target: Target, configuration: String?,
|
||||
skipSigning: Bool) -> [XcodeBuildArgument]
|
||||
{
|
||||
var arguments: [XcodeBuildArgument]
|
||||
if target.platform == .macOS {
|
||||
arguments = [.sdk(target.platform.xcodeDeviceSDK)]
|
||||
|
@ -68,7 +70,10 @@ public final class BuildGraphInspector: BuildGraphInspecting {
|
|||
if (target.settings ?? project.settings)?.configurations.first(where: { $0.key.name == configuration }) != nil {
|
||||
arguments.append(.configuration(configuration))
|
||||
} else {
|
||||
logger.warning("The scheme's targets don't have the given configuration \(configuration). Defaulting to the scheme's default.")
|
||||
logger
|
||||
.warning(
|
||||
"The scheme's targets don't have the given configuration \(configuration). Defaulting to the scheme's default."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,8 @@ public final class TargetBuilder: TargetBuilding {
|
|||
.last()
|
||||
|
||||
if let buildOutputPath = buildOutputPath {
|
||||
let configuration = configuration ?? target.project.settings.defaultDebugBuildConfiguration()?.name ?? BuildConfiguration.debug.name
|
||||
let configuration = configuration ?? target.project.settings.defaultDebugBuildConfiguration()?
|
||||
.name ?? BuildConfiguration.debug.name
|
||||
try copyBuildProducts(
|
||||
to: buildOutputPath,
|
||||
projectPath: workspacePath,
|
||||
|
|
|
@ -83,7 +83,8 @@ public final class TargetRunner: TargetRunning {
|
|||
) throws {
|
||||
try assertCanRunTarget(target.target)
|
||||
|
||||
let configuration = configuration ?? target.project.settings.defaultDebugBuildConfiguration()?.name ?? BuildConfiguration.debug.name
|
||||
let configuration = configuration ?? target.project.settings.defaultDebugBuildConfiguration()?.name ?? BuildConfiguration
|
||||
.debug.name
|
||||
let xcodeBuildDirectory = try xcodeProjectBuildDirectoryLocator.locate(
|
||||
platform: target.target.platform,
|
||||
projectPath: workspacePath,
|
||||
|
|
|
@ -142,10 +142,12 @@ public final class XcodeBuildController: XcodeBuildControlling {
|
|||
return run(command: command, isVerbose: environment.isVerbose)
|
||||
}
|
||||
|
||||
public func showBuildSettings(_ target: XcodeBuildTarget,
|
||||
scheme: String,
|
||||
configuration: String) -> Single<[String: XcodeBuildSettings]>
|
||||
{
|
||||
// swiftlint:disable:next function_body_length
|
||||
public func showBuildSettings(
|
||||
_ target: XcodeBuildTarget,
|
||||
scheme: String,
|
||||
configuration: String
|
||||
) -> Single<[String: XcodeBuildSettings]> {
|
||||
var command = ["/usr/bin/xcrun", "xcodebuild", "archive", "-showBuildSettings", "-skipUnavailableActions"]
|
||||
|
||||
// Configuration
|
||||
|
@ -167,13 +169,17 @@ public final class XcodeBuildController: XcodeBuildControlling {
|
|||
.timeout(DispatchTimeInterval.seconds(20), scheduler: ConcurrentDispatchQueueScheduler(queue: .global()))
|
||||
.retry(5)
|
||||
.flatMap { string -> Observable<XcodeBuildSettings> in
|
||||
Observable.create { (observer) -> Disposable in
|
||||
Observable.create { observer -> Disposable in
|
||||
var currentSettings: [String: String] = [:]
|
||||
var currentTarget: String?
|
||||
|
||||
let flushTarget = { () -> Void in
|
||||
if let currentTarget = currentTarget {
|
||||
let buildSettings = XcodeBuildSettings(currentSettings, target: currentTarget, configuration: configuration)
|
||||
let buildSettings = XcodeBuildSettings(
|
||||
currentSettings,
|
||||
target: currentTarget,
|
||||
configuration: configuration
|
||||
)
|
||||
observer.onNext(buildSettings)
|
||||
}
|
||||
|
||||
|
@ -182,7 +188,10 @@ public final class XcodeBuildController: XcodeBuildControlling {
|
|||
}
|
||||
|
||||
string.enumerateLines { line, _ in
|
||||
if let result = XcodeBuildController.targetSettingsRegex.firstMatch(in: line, range: NSRange(line.startIndex..., in: line)) {
|
||||
if let result = XcodeBuildController.targetSettingsRegex.firstMatch(
|
||||
in: line,
|
||||
range: NSRange(line.startIndex..., in: line)
|
||||
) {
|
||||
let targetRange = Range(result.range(at: 1), in: line)!
|
||||
|
||||
flushTarget()
|
||||
|
@ -205,7 +214,7 @@ public final class XcodeBuildController: XcodeBuildControlling {
|
|||
return Disposables.create()
|
||||
}
|
||||
}
|
||||
.reduce([String: XcodeBuildSettings](), accumulator: { (acc, buildSettings) -> [String: XcodeBuildSettings] in
|
||||
.reduce([String: XcodeBuildSettings](), accumulator: { acc, buildSettings -> [String: XcodeBuildSettings] in
|
||||
var acc = acc
|
||||
acc[buildSettings.target] = buildSettings
|
||||
return acc
|
||||
|
|
|
@ -37,7 +37,9 @@ public final class MockBuildGraphInspector: BuildGraphInspecting {
|
|||
}
|
||||
|
||||
public var buildArgumentsStub: ((Project, Target, String?, Bool) -> [XcodeBuildArgument])?
|
||||
public func buildArguments(project: Project, target: Target, configuration: String?, skipSigning: Bool) -> [XcodeBuildArgument] {
|
||||
public func buildArguments(project: Project, target: Target, configuration: String?,
|
||||
skipSigning: Bool) -> [XcodeBuildArgument]
|
||||
{
|
||||
if let buildArgumentsStub = buildArgumentsStub {
|
||||
return buildArgumentsStub(project, target, configuration, skipSigning)
|
||||
} else {
|
||||
|
|
|
@ -6,7 +6,10 @@ import TuistGraph
|
|||
public final class MockTargetRunner: TargetRunning {
|
||||
public init() {}
|
||||
|
||||
public var runTargetStub: ((GraphTarget, AbsolutePath, String, String?, Version?, Version?, String?, [String]) throws -> Void)?
|
||||
public var runTargetStub: (
|
||||
(GraphTarget, AbsolutePath, String, String?, Version?, Version?, String?, [String]) throws
|
||||
-> Void
|
||||
)?
|
||||
public func runTarget(
|
||||
_ target: GraphTarget,
|
||||
workspacePath: AbsolutePath,
|
||||
|
|
|
@ -25,11 +25,11 @@ public final class Cache: CacheStoring {
|
|||
|
||||
public func exists(name: String, hash: String) -> Single<Bool> {
|
||||
/// It calls exists sequentially until one of the storages returns true.
|
||||
return storages.reduce(Single.just(false)) { (result, next) -> Single<Bool> in
|
||||
return storages.reduce(Single.just(false)) { result, next -> Single<Bool> in
|
||||
result.flatMap { exists in
|
||||
guard !exists else { return result }
|
||||
return next.exists(name: name, hash: hash)
|
||||
}.catchError { (_) -> Single<Bool> in
|
||||
}.catchError { _ -> Single<Bool> in
|
||||
next.exists(name: name, hash: hash)
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public final class Cache: CacheStoring {
|
|||
|
||||
public func fetch(name: String, hash: String) -> Single<AbsolutePath> {
|
||||
return storages
|
||||
.reduce(nil) { (result, next) -> Single<AbsolutePath> in
|
||||
.reduce(nil) { result, next -> Single<AbsolutePath> in
|
||||
if let result = result {
|
||||
return result.catchError { _ in next.fetch(name: name, hash: hash) }
|
||||
} else {
|
||||
|
|
|
@ -39,14 +39,14 @@ public final class CacheLocalStorage: CacheStoring {
|
|||
// MARK: - CacheStoring
|
||||
|
||||
public func exists(name _: String, hash: String) -> Single<Bool> {
|
||||
Single.create { (completed) -> Disposable in
|
||||
Single.create { completed -> Disposable in
|
||||
completed(.success(self.lookupCompiledArtifact(directory: self.cacheDirectory.appending(component: hash)) != nil))
|
||||
return Disposables.create()
|
||||
}
|
||||
}
|
||||
|
||||
public func fetch(name _: String, hash: String) -> Single<AbsolutePath> {
|
||||
Single.create { (completed) -> Disposable in
|
||||
Single.create { completed -> Disposable in
|
||||
if let path = self.lookupCompiledArtifact(directory: self.cacheDirectory.appending(component: hash)) {
|
||||
completed(.success(path))
|
||||
} else {
|
||||
|
@ -57,7 +57,7 @@ public final class CacheLocalStorage: CacheStoring {
|
|||
}
|
||||
|
||||
public func store(name _: String, hash: String, paths: [AbsolutePath]) -> Completable {
|
||||
let copy = Completable.create { (completed) -> Disposable in
|
||||
let copy = Completable.create { completed -> Disposable in
|
||||
let hashFolder = self.cacheDirectory.appending(component: hash)
|
||||
|
||||
do {
|
||||
|
@ -94,7 +94,7 @@ public final class CacheLocalStorage: CacheStoring {
|
|||
}
|
||||
|
||||
fileprivate func createCacheDirectory() -> Completable {
|
||||
Completable.create { (completed) -> Disposable in
|
||||
Completable.create { completed -> Disposable in
|
||||
do {
|
||||
if !FileHandler.shared.exists(self.cacheDirectory) {
|
||||
try FileHandler.shared.createFolder(self.cacheDirectory)
|
||||
|
|
|
@ -34,7 +34,9 @@ public final class CacheRemoteStorage: CacheStoring {
|
|||
|
||||
// MARK: - Init
|
||||
|
||||
public convenience init(cloudConfig: Cloud, cloudClient: CloudClienting, cacheDirectoriesProvider: CacheDirectoriesProviding) {
|
||||
public convenience init(cloudConfig: Cloud, cloudClient: CloudClienting,
|
||||
cacheDirectoriesProvider: CacheDirectoriesProviding)
|
||||
{
|
||||
self.init(
|
||||
cloudClient: cloudClient,
|
||||
fileArchiverFactory: FileArchivingFactory(),
|
||||
|
@ -115,7 +117,7 @@ public final class CacheRemoteStorage: CacheStoring {
|
|||
|
||||
return cloudClient
|
||||
.request(storeResource)
|
||||
.map { (responseTuple) -> URL in responseTuple.object.data.url }
|
||||
.map { responseTuple -> URL in responseTuple.object.data.url }
|
||||
.flatMapCompletable { (url: URL) in
|
||||
let deleteCompletable = self.deleteZipArchiveCompletable(archiver: archiver)
|
||||
return self.fileClient.upload(file: destinationZipPath, hash: hash, to: url)
|
||||
|
|
|
@ -52,16 +52,20 @@ public final class DependenciesContentHasher: DependenciesContentHashing {
|
|||
// MARK: - DependenciesContentHashing
|
||||
|
||||
public func hash(graphTarget: GraphTarget, hashedTargets: inout [GraphHashedTarget: String]) throws -> String {
|
||||
let hashes = try graphTarget.target.dependencies.map { try hash(graphTarget: graphTarget, dependency: $0, hashedTargets: &hashedTargets) }
|
||||
let hashes = try graphTarget.target.dependencies
|
||||
.map { try hash(graphTarget: graphTarget, dependency: $0, hashedTargets: &hashedTargets) }
|
||||
return hashes.compactMap { $0 }.joined()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func hash(graphTarget: GraphTarget, dependency: TargetDependency, hashedTargets: inout [GraphHashedTarget: String]) throws -> String {
|
||||
private func hash(graphTarget: GraphTarget, dependency: TargetDependency,
|
||||
hashedTargets: inout [GraphHashedTarget: String]) throws -> String
|
||||
{
|
||||
switch dependency {
|
||||
case let .target(targetName):
|
||||
guard let dependencyHash = hashedTargets[GraphHashedTarget(projectPath: graphTarget.path, targetName: targetName)] else {
|
||||
guard let dependencyHash = hashedTargets[GraphHashedTarget(projectPath: graphTarget.path, targetName: targetName)]
|
||||
else {
|
||||
throw DependenciesContentHasherError.missingTargetHash(
|
||||
sourceTargetName: graphTarget.target.name,
|
||||
dependencyProjectPath: graphTarget.path,
|
||||
|
|
|
@ -17,13 +17,13 @@ public protocol GraphContentHashing {
|
|||
) throws -> [GraphTarget: String]
|
||||
}
|
||||
|
||||
public extension GraphContentHashing {
|
||||
extension GraphContentHashing {
|
||||
/// Hashes graph
|
||||
/// - Parameters:
|
||||
/// - graph: Graph to hash
|
||||
/// - filter: If `true`, `TargetNode` is hashed, otherwise it is skipped
|
||||
/// - additionalStrings: Additional strings to be used when hashing graph
|
||||
func contentHashes(
|
||||
public func contentHashes(
|
||||
for graph: Graph,
|
||||
filter: (GraphTarget) -> Bool = { _ in true },
|
||||
additionalStrings: [String] = []
|
||||
|
|
|
@ -6,7 +6,8 @@ import TuistSupport
|
|||
|
||||
public protocol TargetContentHashing {
|
||||
func contentHash(for target: GraphTarget, hashedTargets: inout [GraphHashedTarget: String]) throws -> String
|
||||
func contentHash(for target: GraphTarget, hashedTargets: inout [GraphHashedTarget: String], additionalStrings: [String]) throws -> String
|
||||
func contentHash(for target: GraphTarget, hashedTargets: inout [GraphHashedTarget: String],
|
||||
additionalStrings: [String]) throws -> String
|
||||
}
|
||||
|
||||
/// `TargetContentHasher`
|
||||
|
|
|
@ -32,11 +32,15 @@ public final class TargetScriptsContentHasher: TargetScriptsContentHashing {
|
|||
pathsToHash.append(contentsOf: script.outputPaths)
|
||||
pathsToHash.append(contentsOf: script.outputFileListPaths)
|
||||
let fileHashes = try pathsToHash.map { try contentHasher.hash(path: $0) }
|
||||
stringsToHash.append(contentsOf: fileHashes +
|
||||
[script.name,
|
||||
script.tool ?? "", // TODO: don't default to ""
|
||||
script.order.rawValue] +
|
||||
script.arguments)
|
||||
stringsToHash.append(
|
||||
contentsOf: fileHashes +
|
||||
[
|
||||
script.name,
|
||||
script.tool ?? "", // TODO: don't default to ""
|
||||
script.order.rawValue,
|
||||
] +
|
||||
script.arguments
|
||||
)
|
||||
}
|
||||
return try contentHasher.hash(stringsToHash)
|
||||
}
|
||||
|
|
|
@ -20,9 +20,11 @@ public final class CacheGraphLinter: CacheGraphLinting {
|
|||
let targetsWithScripts = targets.filter { $0.target.scripts.count != 0 }
|
||||
if !targetsWithScripts.isEmpty {
|
||||
let message: Logger.Message = """
|
||||
The following targets contain scripts that might introduce non-cacheable side-effects: \(targetsWithScripts.map(\.target.name).joined(separator: ", ")).
|
||||
The following targets contain scripts that might introduce non-cacheable side-effects: \(targetsWithScripts
|
||||
.map(\.target.name).joined(separator: ", ")).
|
||||
Note that a side-effect is an action that affects the target built products based on a given input (e.g. Xcode build variable).
|
||||
These warnings can be ignored when the scripts do not have side effects. Please report eventual use cases to the community forum \(Constants.communityURL).
|
||||
These warnings can be ignored when the scripts do not have side effects. Please report eventual use cases to the community forum \(Constants
|
||||
.communityURL).
|
||||
"""
|
||||
logger.warning(message)
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ public final class TargetsToCacheBinariesGraphMapper: GraphMapping {
|
|||
}
|
||||
|
||||
private func hashes(graph: Graph) -> Single<[GraphTarget: String]> {
|
||||
Single.create { (observer) -> Disposable in
|
||||
Single.create { observer -> Disposable in
|
||||
do {
|
||||
let hashes = try self.cacheGraphContentHasher.contentHashes(
|
||||
for: graph,
|
||||
|
@ -149,7 +149,7 @@ public final class TargetsToCacheBinariesGraphMapper: GraphMapping {
|
|||
.zip(
|
||||
hashes.map(context: .concurrent) { target, hash in
|
||||
self.cache.exists(name: target.target.name, hash: hash)
|
||||
.flatMap { (exists) -> Single<(target: GraphTarget, path: AbsolutePath?)> in
|
||||
.flatMap { exists -> Single<(target: GraphTarget, path: AbsolutePath?)> in
|
||||
guard exists else { return Single.just((target: target, path: nil)) }
|
||||
return self.cache.fetch(name: target.target.name, hash: hash).map { (target: target, path: $0) }
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ public final class TreeShakePrunedTargetsGraphMapper: GraphMapping {
|
|||
public init() {}
|
||||
|
||||
public func map(graph: Graph) throws -> (Graph, [SideEffectDescriptor]) {
|
||||
let sourceTargets: Set<TargetReference> = Set(graph.targets.flatMap { (projectPath, targets) -> [TargetReference] in
|
||||
let sourceTargets: Set<TargetReference> = Set(graph.targets.flatMap { projectPath, targets -> [TargetReference] in
|
||||
guard graph.projects[projectPath] != nil else { return [] }
|
||||
return targets.compactMap { (_, target) -> TargetReference? in
|
||||
return targets.compactMap { _, target -> TargetReference? in
|
||||
if target.prune { return nil }
|
||||
return TargetReference(projectPath: projectPath, name: target.name)
|
||||
}
|
||||
|
@ -64,8 +64,10 @@ public final class TreeShakePrunedTargetsGraphMapper: GraphMapping {
|
|||
return workspace
|
||||
}
|
||||
|
||||
fileprivate func treeShake(targets: [Target], path: AbsolutePath, graph: Graph, sourceTargets: Set<TargetReference>) -> [Target] {
|
||||
targets.compactMap { (target) -> Target? in
|
||||
fileprivate func treeShake(targets: [Target], path: AbsolutePath, graph: Graph,
|
||||
sourceTargets: Set<TargetReference>) -> [Target]
|
||||
{
|
||||
targets.compactMap { target -> Target? in
|
||||
guard let target = graph.targets[path, default: [:]][target.name] else { return nil }
|
||||
let targetReference = TargetReference(projectPath: path, name: target.name)
|
||||
guard sourceTargets.contains(targetReference) else { return nil }
|
||||
|
|
|
@ -114,10 +114,15 @@ public final class CacheFrameworkBuilder: CacheArtifactBuilding {
|
|||
case .macOS: return .just("platform=OS X,arch=x86_64")
|
||||
}
|
||||
|
||||
return simulatorController.findAvailableDevice(platform: mappedPlatform, version: version, minVersion: nil, deviceName: deviceName)
|
||||
.flatMap { (deviceAndRuntime) -> Single<String> in
|
||||
.just("id=\(deviceAndRuntime.device.udid)")
|
||||
}
|
||||
return simulatorController.findAvailableDevice(
|
||||
platform: mappedPlatform,
|
||||
version: version,
|
||||
minVersion: nil,
|
||||
deviceName: deviceName
|
||||
)
|
||||
.flatMap { deviceAndRuntime -> Single<String> in
|
||||
.just("id=\(deviceAndRuntime.device.udid)")
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func xcodebuild(projectTarget: XcodeBuildTarget,
|
||||
|
|
|
@ -77,7 +77,10 @@ public final class CacheXCFrameworkBuilder: CacheArtifactBuilding {
|
|||
let xcframeworkPath = outputDirectory.appending(component: "\(productName).xcframework")
|
||||
try buildXCFramework(frameworks: frameworkpaths, output: xcframeworkPath)
|
||||
|
||||
try FileHandler.shared.move(from: xcframeworkPath, to: outputDirectory.appending(component: xcframeworkPath.basename))
|
||||
try FileHandler.shared.move(
|
||||
from: xcframeworkPath,
|
||||
to: outputDirectory.appending(component: xcframeworkPath.basename)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,13 @@ public final class MockCacheArtifactBuilder: CacheArtifactBuilding {
|
|||
public var invokedBuildSchemeProject = false
|
||||
public var invokedBuildSchemeProjectCount = 0
|
||||
// swiftlint:disable:next large_tuple
|
||||
public var invokedBuildSchemeProjectParameters: (scheme: Scheme, projectTarget: XcodeBuildTarget, outputDirectory: AbsolutePath)?
|
||||
public var invokedBuildchemeProjectParametersList = [(scheme: Scheme, projectTarget: XcodeBuildTarget, outputDirectory: AbsolutePath)]()
|
||||
public var invokedBuildSchemeProjectParameters: (
|
||||
scheme: Scheme,
|
||||
projectTarget: XcodeBuildTarget,
|
||||
outputDirectory: AbsolutePath
|
||||
)?
|
||||
public var invokedBuildchemeProjectParametersList =
|
||||
[(scheme: Scheme, projectTarget: XcodeBuildTarget, outputDirectory: AbsolutePath)]()
|
||||
public var stubbedBuildSchemeProjectError: Error?
|
||||
public func build(
|
||||
scheme: Scheme,
|
||||
|
|
|
@ -21,7 +21,9 @@ public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
|||
parseError: { _, _ in CloudEmptyResponseError() }
|
||||
)
|
||||
|
||||
public func existsResource(name: String, hash: String) throws -> HTTPResource<CloudResponse<CloudEmptyResponse>, CloudEmptyResponseError> {
|
||||
public func existsResource(name: String,
|
||||
hash: String) throws -> HTTPResource<CloudResponse<CloudEmptyResponse>, CloudEmptyResponseError>
|
||||
{
|
||||
invokedExistsResource = true
|
||||
invokedExistsResourceCount += 1
|
||||
invokedExistsResourceParameters = (name, hash, ())
|
||||
|
@ -56,7 +58,12 @@ public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
|||
|
||||
public var invokedStoreResource = false
|
||||
public var invokedStoreResourceCount = 0
|
||||
public var invokedStoreResourceParameters: (name: String, hash: String, contentMD5: String)? // swiftlint:disable:this large_tuple
|
||||
// swiftlint:disable:next large_tuple
|
||||
public var invokedStoreResourceParameters: (
|
||||
name: String,
|
||||
hash: String,
|
||||
contentMD5: String
|
||||
)?
|
||||
public var invokedStoreResourceParametersList = [(name: String, hash: String, contentMD5: String)]()
|
||||
public var stubbedStoreResourceError: Error?
|
||||
public var stubbedStoreResourceResult: CloudCacheResource = HTTPResource(
|
||||
|
@ -78,8 +85,12 @@ public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
|||
|
||||
public var invokedVerifyUploadResource = false
|
||||
public var invokedVerifyUploadResourceCount = 0
|
||||
public var invokedVerifyUploadResourceParameters: (name: String, hash: String, contentMD5: String)? // swiftlint:disable:this large_tuple
|
||||
// swiftlint:disable:next identifier_name
|
||||
// swiftlint:disable:next large_tuple
|
||||
public var invokedVerifyUploadResourceParameters: (
|
||||
name: String,
|
||||
hash: String,
|
||||
contentMD5: String
|
||||
)?
|
||||
public var invokedVerifyUploadResourceParametersList = [(name: String, hash: String, contentMD5: String)]()
|
||||
public var stubbedVerifyUploadResourceError: Error?
|
||||
public var stubbedVerifyUploadResourceResult: CloudVerifyUploadResource = HTTPResource(
|
||||
|
|
|
@ -6,7 +6,10 @@ import TuistGraph
|
|||
public final class MockCacheGraphContentHasher: CacheGraphContentHashing {
|
||||
public init() {}
|
||||
|
||||
public var contentHashesStub: ((Graph, TuistGraph.Cache.Profile, CacheOutputType, Set<String>) throws -> [GraphTarget: String])?
|
||||
public var contentHashesStub: (
|
||||
(Graph, TuistGraph.Cache.Profile, CacheOutputType, Set<String>) throws
|
||||
-> [GraphTarget: String]
|
||||
)?
|
||||
public func contentHashes(
|
||||
for graph: Graph,
|
||||
cacheProfile: TuistGraph.Cache.Profile,
|
||||
|
|
|
@ -13,7 +13,11 @@ public class CloudClient: CloudClienting {
|
|||
private var noRedirectDelegate: NoRedirectDelegate? // swiftlint:disable:this weak_delegate
|
||||
lazy var requestDispatcher: HTTPRequestDispatching = {
|
||||
noRedirectDelegate = NoRedirectDelegate()
|
||||
return HTTPRequestDispatcher(session: URLSession(configuration: .default, delegate: noRedirectDelegate, delegateQueue: nil))
|
||||
return HTTPRequestDispatcher(session: URLSession(
|
||||
configuration: .default,
|
||||
delegate: noRedirectDelegate,
|
||||
delegateQueue: nil
|
||||
))
|
||||
}()
|
||||
|
||||
// MARK: - Init
|
||||
|
@ -25,7 +29,7 @@ public class CloudClient: CloudClienting {
|
|||
// MARK: - Public
|
||||
|
||||
public func request<T, E>(_ resource: HTTPResource<T, E>) -> Single<(object: T, response: HTTPURLResponse)> {
|
||||
Single<HTTPResource<T, E>>.create { (observer) -> Disposable in
|
||||
Single<HTTPResource<T, E>>.create { observer -> Disposable in
|
||||
do {
|
||||
observer(.success(try self.resourceWithHeaders(resource)))
|
||||
} catch {
|
||||
|
@ -38,7 +42,7 @@ public class CloudClient: CloudClienting {
|
|||
// MARK: - Fileprivate
|
||||
|
||||
private func resourceWithHeaders<T, E>(_ resource: HTTPResource<T, E>) throws -> HTTPResource<T, E> {
|
||||
try resource.mappingRequest { (request) -> URLRequest in
|
||||
try resource.mappingRequest { request -> URLRequest in
|
||||
var request = request
|
||||
if request.allHTTPHeaderFields == nil { request.allHTTPHeaderFields = [:] }
|
||||
request.allHTTPHeaderFields?["Content-Type"] = "application/json;"
|
||||
|
|
|
@ -2,8 +2,8 @@ import Foundation
|
|||
import RxSwift
|
||||
import TuistSupport
|
||||
|
||||
public extension Observable where Element == SystemEvent<XcodeBuildOutput> {
|
||||
func printFormattedOutput() -> Observable<SystemEvent<XcodeBuildOutput>> {
|
||||
extension Observable where Element == SystemEvent<XcodeBuildOutput> {
|
||||
public func printFormattedOutput() -> Observable<SystemEvent<XcodeBuildOutput>> {
|
||||
`do`(onNext: { event in
|
||||
switch event {
|
||||
case let .standardError(error):
|
||||
|
@ -14,7 +14,7 @@ public extension Observable where Element == SystemEvent<XcodeBuildOutput> {
|
|||
})
|
||||
}
|
||||
|
||||
func printRawErrors() -> Observable<SystemEvent<XcodeBuildOutput>> {
|
||||
public func printRawErrors() -> Observable<SystemEvent<XcodeBuildOutput>> {
|
||||
`do`(onNext: { event in
|
||||
switch event {
|
||||
case let .standardError(error):
|
||||
|
|
|
@ -10,7 +10,8 @@ public protocol CacheDirectoriesProviding {
|
|||
|
||||
public final class CacheDirectoriesProvider: CacheDirectoriesProviding {
|
||||
public let cacheDirectory: AbsolutePath
|
||||
private static let defaultDirectory = AbsolutePath(URL(fileURLWithPath: NSHomeDirectory()).path).appending(component: ".tuist")
|
||||
private static let defaultDirectory = AbsolutePath(URL(fileURLWithPath: NSHomeDirectory()).path)
|
||||
.appending(component: ".tuist")
|
||||
|
||||
public init(config: Config?) {
|
||||
if let cacheDirectory = config?.cache?.path {
|
||||
|
|
|
@ -130,7 +130,7 @@ public final class GraphLoader: GraphLoading {
|
|||
throw GraphLoadingError.missingProject(path)
|
||||
}
|
||||
guard let referencedTargetProject = cache.allTargets[path],
|
||||
let target = referencedTargetProject[name]
|
||||
let target = referencedTargetProject[name]
|
||||
else {
|
||||
throw GraphLoadingError.targetNotFound(name, path)
|
||||
}
|
||||
|
@ -281,7 +281,12 @@ public final class GraphLoader: GraphLoading {
|
|||
status: SDKStatus,
|
||||
source: SDKSource) throws -> GraphDependency
|
||||
{
|
||||
let metadata = try systemFrameworkMetadataProvider.loadMetadata(sdkName: name, status: status, platform: platform, source: source)
|
||||
let metadata = try systemFrameworkMetadataProvider.loadMetadata(
|
||||
sdkName: name,
|
||||
status: status,
|
||||
platform: platform,
|
||||
source: source
|
||||
)
|
||||
return .sdk(name: metadata.name, path: metadata.path, status: metadata.status, source: metadata.source)
|
||||
}
|
||||
|
||||
|
@ -354,8 +359,8 @@ public final class GraphLoader: GraphLoading {
|
|||
}
|
||||
}
|
||||
|
||||
private extension Package {
|
||||
var name: String {
|
||||
extension Package {
|
||||
fileprivate var name: String {
|
||||
switch self {
|
||||
case let .local(path: path):
|
||||
return path.pathString
|
||||
|
|
|
@ -36,7 +36,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
}
|
||||
|
||||
public func allTargets() -> Set<GraphTarget> {
|
||||
Set(projects.flatMap { (projectPath, project) -> [GraphTarget] in
|
||||
Set(projects.flatMap { projectPath, project -> [GraphTarget] in
|
||||
let targets = graph.targets[projectPath, default: [:]]
|
||||
return targets.values.map { target in
|
||||
GraphTarget(path: projectPath, target: target, project: project)
|
||||
|
@ -96,7 +96,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
let targetDependencies = dependencies
|
||||
.compactMap(\.targetDependency)
|
||||
|
||||
return Set(targetDependencies.flatMap { (dependencyName, dependencyPath) -> [GraphTarget] in
|
||||
return Set(targetDependencies.flatMap { dependencyName, dependencyPath -> [GraphTarget] in
|
||||
guard
|
||||
let projectDependencies = graph.targets[dependencyPath],
|
||||
let dependencyTarget = projectDependencies[dependencyName],
|
||||
|
@ -115,9 +115,9 @@ public class GraphTraverser: GraphTraversing {
|
|||
let localTargetDependencies = dependencies
|
||||
.compactMap(\.targetDependency)
|
||||
.filter { $0.path == path }
|
||||
return Set(localTargetDependencies.flatMap { (dependencyName, dependencyPath) -> [GraphTarget] in
|
||||
return Set(localTargetDependencies.flatMap { dependencyName, dependencyPath -> [GraphTarget] in
|
||||
guard let projectDependencies = graph.targets[dependencyPath],
|
||||
let dependencyTarget = projectDependencies[dependencyName]
|
||||
let dependencyTarget = projectDependencies[dependencyName]
|
||||
else {
|
||||
return []
|
||||
}
|
||||
|
@ -144,10 +144,14 @@ public class GraphTraverser: GraphTraversing {
|
|||
public func testTargetsDependingOn(path: AbsolutePath, name: String) -> Set<GraphTarget> {
|
||||
guard let project = graph.projects[path] else { return Set() }
|
||||
|
||||
return Set(graph.targets[path]?.values
|
||||
.filter { $0.product.testsBundle }
|
||||
.filter { graph.dependencies[.target(name: $0.name, path: path)]?.contains(.target(name: name, path: path)) == true }
|
||||
.map { GraphTarget(path: path, target: $0, project: project) } ?? [])
|
||||
return Set(
|
||||
graph.targets[path]?.values
|
||||
.filter { $0.product.testsBundle }
|
||||
.filter {
|
||||
graph.dependencies[.target(name: $0.name, path: path)]?.contains(.target(name: name, path: path)) == true
|
||||
}
|
||||
.map { GraphTarget(path: path, target: $0, project: project) } ?? []
|
||||
)
|
||||
}
|
||||
|
||||
public func target(from dependency: GraphDependency) -> GraphTarget? {
|
||||
|
@ -163,8 +167,10 @@ public class GraphTraverser: GraphTraversing {
|
|||
let validProducts: [Product] = [
|
||||
.appExtension, .stickerPackExtension, .watch2Extension, .tvTopShelfExtension, .messagesExtension,
|
||||
]
|
||||
return Set(directLocalTargetDependencies(path: path, name: name)
|
||||
.filter { validProducts.contains($0.target.product) })
|
||||
return Set(
|
||||
directLocalTargetDependencies(path: path, name: name)
|
||||
.filter { validProducts.contains($0.target.product) }
|
||||
)
|
||||
}
|
||||
|
||||
public func appClipDependencies(path: AbsolutePath, name: String) -> GraphTarget? {
|
||||
|
@ -173,21 +179,29 @@ public class GraphTraverser: GraphTraversing {
|
|||
}
|
||||
|
||||
public func directStaticDependencies(path: AbsolutePath, name: String) -> Set<GraphDependencyReference> {
|
||||
Set(graph.dependencies[.target(name: name, path: path)]?
|
||||
.compactMap { (dependency: GraphDependency) -> (path: AbsolutePath, name: String)? in
|
||||
guard case let GraphDependency.target(name, path) = dependency else {
|
||||
return nil
|
||||
Set(
|
||||
graph.dependencies[.target(name: name, path: path)]?
|
||||
.compactMap { (dependency: GraphDependency) -> (path: AbsolutePath, name: String)? in
|
||||
guard case let GraphDependency.target(name, path) = dependency else {
|
||||
return nil
|
||||
}
|
||||
return (path, name)
|
||||
}
|
||||
return (path, name)
|
||||
}
|
||||
.compactMap { graph.targets[$0.path]?[$0.name] }
|
||||
.filter { $0.product.isStatic }
|
||||
.map { .product(target: $0.name, productName: $0.productNameWithExtension, platformFilter: $0.targetDependencyBuildFilesPlatformFilter) }
|
||||
?? [])
|
||||
.compactMap { graph.targets[$0.path]?[$0.name] }
|
||||
.filter { $0.product.isStatic }
|
||||
.map {
|
||||
.product(
|
||||
target: $0.name,
|
||||
productName: $0.productNameWithExtension,
|
||||
platformFilter: $0.targetDependencyBuildFilesPlatformFilter
|
||||
)
|
||||
}
|
||||
?? []
|
||||
)
|
||||
}
|
||||
|
||||
public func embeddableFrameworks(path: AbsolutePath, name: String) -> Set<GraphDependencyReference> {
|
||||
guard let target = self.target(path: path, name: name), canEmbedProducts(target: target.target) else { return Set() }
|
||||
guard let target = target(path: path, name: name), canEmbedProducts(target: target.target) else { return Set() }
|
||||
|
||||
var references: Set<GraphDependencyReference> = Set([])
|
||||
|
||||
|
@ -237,14 +251,14 @@ public class GraphTraverser: GraphTraversing {
|
|||
name: String,
|
||||
shouldExcludeHostAppDependencies: Bool
|
||||
) throws -> Set<GraphDependencyReference> {
|
||||
guard let target = self.target(path: path, name: name) else { return Set() }
|
||||
guard let target = target(path: path, name: name) else { return Set() }
|
||||
|
||||
var references = Set<GraphDependencyReference>()
|
||||
|
||||
// System libraries and frameworks
|
||||
if target.target.canLinkStaticProducts() {
|
||||
let transitiveSystemLibraries = transitiveStaticTargets(from: .target(name: name, path: path))
|
||||
.flatMap { (dependency) -> [GraphDependencyReference] in
|
||||
.flatMap { dependency -> [GraphDependencyReference] in
|
||||
let dependencies = self.graph.dependencies[dependency, default: []]
|
||||
return dependencies.compactMap { dependencyDependency -> GraphDependencyReference? in
|
||||
guard case let GraphDependency.sdk(_, path, status, source) = dependencyDependency else { return nil }
|
||||
|
@ -299,16 +313,16 @@ public class GraphTraverser: GraphTraversing {
|
|||
// however, for search paths it's fine to keep them included
|
||||
let hostApplicationStaticTargets: Set<GraphDependency>
|
||||
if target.target.product == .unitTests, shouldExcludeHostAppDependencies,
|
||||
let hostApp = hostApplication(path: path, name: name)
|
||||
let hostApp = hostApplication(path: path, name: name)
|
||||
{
|
||||
hostApplicationStaticTargets = transitiveStaticDependencies(from: .target(name: hostApp.target.name, path: hostApp.project.path))
|
||||
hostApplicationStaticTargets =
|
||||
transitiveStaticDependencies(from: .target(name: hostApp.target.name, path: hostApp.project.path))
|
||||
} else {
|
||||
hostApplicationStaticTargets = Set()
|
||||
}
|
||||
|
||||
let transitiveStaticTargetReferences = transitiveStaticTargets
|
||||
|
||||
// swiftlint:disable:next identifier_name
|
||||
let staticDependenciesDynamicLibrariesAndFrameworks = transitiveStaticTargets.flatMap { dependency in
|
||||
self.graph.dependencies[dependency, default: []]
|
||||
.lazy
|
||||
|
@ -316,16 +330,17 @@ public class GraphTraverser: GraphTraversing {
|
|||
.filter(isDependencyDynamicTarget)
|
||||
}
|
||||
|
||||
// swiftlint:disable:next identifier_name
|
||||
let staticDependenciesPrecompiledLibrariesAndFrameworks = transitiveStaticTargets.flatMap { dependency in
|
||||
self.graph.dependencies[dependency, default: []]
|
||||
.lazy
|
||||
.filter(\.isPrecompiled)
|
||||
}
|
||||
|
||||
let allDependencies = (transitiveStaticTargetReferences
|
||||
+ staticDependenciesDynamicLibrariesAndFrameworks
|
||||
+ staticDependenciesPrecompiledLibrariesAndFrameworks)
|
||||
let allDependencies = (
|
||||
transitiveStaticTargetReferences
|
||||
+ staticDependenciesDynamicLibrariesAndFrameworks
|
||||
+ staticDependenciesPrecompiledLibrariesAndFrameworks
|
||||
)
|
||||
|
||||
references.formUnion(
|
||||
allDependencies
|
||||
|
@ -346,7 +361,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
}
|
||||
|
||||
public func copyProductDependencies(path: AbsolutePath, name: String) -> Set<GraphDependencyReference> {
|
||||
guard let target = self.target(path: path, name: name) else { return Set() }
|
||||
guard let target = target(path: path, name: name) else { return Set() }
|
||||
|
||||
var dependencies = Set<GraphDependencyReference>()
|
||||
|
||||
|
@ -388,9 +403,9 @@ public class GraphTraverser: GraphTraversing {
|
|||
|
||||
public func runPathSearchPaths(path: AbsolutePath, name: String) -> Set<AbsolutePath> {
|
||||
guard let target = target(path: path, name: name),
|
||||
canEmbedProducts(target: target.target),
|
||||
target.target.product == .unitTests,
|
||||
hostApplication(path: path, name: name) == nil
|
||||
canEmbedProducts(target: target.target),
|
||||
target.target.product == .unitTests,
|
||||
hostApplication(path: path, name: name) == nil
|
||||
else {
|
||||
return Set()
|
||||
}
|
||||
|
@ -425,7 +440,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
guard let targets = graph.targets[path] else { return nil }
|
||||
guard let project = graph.projects[path] else { return nil }
|
||||
|
||||
return targets.values.compactMap { (target) -> GraphTarget? in
|
||||
return targets.values.compactMap { target -> GraphTarget? in
|
||||
let dependencies = self.graph.dependencies[.target(name: target.name, path: path), default: Set()]
|
||||
let dependsOnTarget = dependencies.contains(where: { dependency in
|
||||
// swiftlint:disable:next identifier_name
|
||||
|
@ -576,7 +591,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
|
||||
func isDependencyStaticTarget(dependency: GraphDependency) -> Bool {
|
||||
guard case let GraphDependency.target(name, path) = dependency,
|
||||
let target = self.target(path: path, name: name) else { return false }
|
||||
let target = target(path: path, name: name) else { return false }
|
||||
return target.target.product.isStatic
|
||||
}
|
||||
|
||||
|
@ -589,7 +604,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
case .bundle: return false
|
||||
case .packageProduct: return false
|
||||
case let .target(name, path):
|
||||
guard let target = self.target(path: path, name: name) else { return false }
|
||||
guard let target = target(path: path, name: name) else { return false }
|
||||
return target.target.product.isStatic
|
||||
case .sdk: return false
|
||||
}
|
||||
|
@ -597,13 +612,13 @@ public class GraphTraverser: GraphTraversing {
|
|||
|
||||
func isDependencyDynamicLibrary(dependency: GraphDependency) -> Bool {
|
||||
guard case let GraphDependency.target(name, path) = dependency,
|
||||
let target = self.target(path: path, name: name) else { return false }
|
||||
let target = target(path: path, name: name) else { return false }
|
||||
return target.target.product == .dynamicLibrary
|
||||
}
|
||||
|
||||
func isDependencyFramework(dependency: GraphDependency) -> Bool {
|
||||
guard case let GraphDependency.target(name, path) = dependency,
|
||||
let target = self.target(path: path, name: name) else { return false }
|
||||
let target = target(path: path, name: name) else { return false }
|
||||
return target.target.product == .framework
|
||||
}
|
||||
|
||||
|
@ -615,7 +630,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
case .bundle: return false
|
||||
case .packageProduct: return false
|
||||
case let .target(name, path):
|
||||
guard let target = self.target(path: path, name: name) else { return false }
|
||||
guard let target = target(path: path, name: name) else { return false }
|
||||
return target.target.product.isDynamic
|
||||
case .sdk: return false
|
||||
}
|
||||
|
@ -636,13 +651,13 @@ public class GraphTraverser: GraphTraversing {
|
|||
|
||||
func canDependencyEmbedProducts(dependency: GraphDependency) -> Bool {
|
||||
guard case let GraphDependency.target(name, path) = dependency,
|
||||
let target = self.target(path: path, name: name) else { return false }
|
||||
let target = target(path: path, name: name) else { return false }
|
||||
return canEmbedProducts(target: target.target)
|
||||
}
|
||||
|
||||
func canDependencyLinkStaticProducts(dependency: GraphDependency) -> Bool {
|
||||
guard case let GraphDependency.target(name, path) = dependency,
|
||||
let target = self.target(path: path, name: name) else { return false }
|
||||
let target = target(path: path, name: name) else { return false }
|
||||
return target.target.canLinkStaticProducts()
|
||||
}
|
||||
|
||||
|
@ -692,7 +707,7 @@ public class GraphTraverser: GraphTraversing {
|
|||
source: source
|
||||
)
|
||||
case let .target(name, path):
|
||||
guard let target = self.target(path: path, name: name) else { return nil }
|
||||
guard let target = target(path: path, name: name) else { return nil }
|
||||
return .product(
|
||||
target: target.target.name,
|
||||
productName: target.target.productNameWithExtension,
|
||||
|
|
|
@ -8,7 +8,7 @@ extension Project {
|
|||
/// - Parameter graph: Dependencies graph.
|
||||
/// - Returns: Sorted targets.
|
||||
public func sortedTargetsForProjectScheme(graph: Graph) -> [Target] {
|
||||
targets.sorted { (first, second) -> Bool in
|
||||
targets.sorted { first, second -> Bool in
|
||||
// First criteria: Test bundles at the end
|
||||
if first.product.testsBundle, !second.product.testsBundle {
|
||||
return false
|
||||
|
|
|
@ -18,6 +18,6 @@ extension Scheme {
|
|||
]
|
||||
|
||||
let targets = targetSources.compactMap { $0 }.flatMap { $0 }.uniqued()
|
||||
return targets.sorted { ($0.name < $1.name) }
|
||||
return targets.sorted { $0.name < $1.name }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@ public enum TargetError: FatalError, Equatable {
|
|||
public var description: String {
|
||||
switch self {
|
||||
case let .invalidSourcesGlob(targetName: targetName, invalidGlobs: invalidGlobs):
|
||||
return "The target \(targetName) has the following invalid source files globs:\n" + invalidGlobs.invalidGlobsDescription
|
||||
return "The target \(targetName) has the following invalid source files globs:\n" + invalidGlobs
|
||||
.invalidGlobsDescription
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,8 +172,8 @@ public protocol GraphTraversing {
|
|||
func dependsOnXCTest(path: AbsolutePath, name: String) -> Bool
|
||||
}
|
||||
|
||||
public extension GraphTraversing {
|
||||
func apps() -> Set<GraphTarget> {
|
||||
extension GraphTraversing {
|
||||
public func apps() -> Set<GraphTarget> {
|
||||
targets(product: .app)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,11 @@ public class PrecompiledMetadataProvider: PrecompiledMetadataProviding {
|
|||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable:next large_tuple
|
||||
private func readMetadatasFromFatHeader(binary: FileHandle, binaryPath: AbsolutePath) throws -> [(BinaryArchitecture, BinaryLinking, UUID?)] {
|
||||
private func readMetadatasFromFatHeader(
|
||||
binary: FileHandle,
|
||||
binaryPath: AbsolutePath
|
||||
// swiftlint:disable:next large_tuple
|
||||
) throws -> [(BinaryArchitecture, BinaryLinking, UUID?)] {
|
||||
let currentOffset = binary.currentOffset
|
||||
let magic: UInt32 = binary.read()
|
||||
binary.seek(to: currentOffset)
|
||||
|
@ -262,18 +265,18 @@ public class PrecompiledMetadataProvider: PrecompiledMetadataProviding {
|
|||
}
|
||||
}
|
||||
|
||||
private extension FileHandle {
|
||||
var currentOffset: UInt64 { offsetInFile }
|
||||
extension FileHandle {
|
||||
fileprivate var currentOffset: UInt64 { offsetInFile }
|
||||
|
||||
func seek(to offset: UInt64) {
|
||||
fileprivate func seek(to offset: UInt64) {
|
||||
seek(toFileOffset: offset)
|
||||
}
|
||||
|
||||
func read<T>() -> T {
|
||||
fileprivate func read<T>() -> T {
|
||||
readData(ofLength: MemoryLayout<T>.size).withUnsafeBytes { $0.load(as: T.self) }
|
||||
}
|
||||
|
||||
func readString(ofLength length: Int) -> String? {
|
||||
fileprivate func readString(ofLength length: Int) -> String? {
|
||||
let sizeData = readData(ofLength: length)
|
||||
return String(data: sizeData, encoding: .ascii)
|
||||
}
|
||||
|
|
|
@ -44,10 +44,12 @@ extension SystemFrameworkMetadataProviding {
|
|||
public final class SystemFrameworkMetadataProvider: SystemFrameworkMetadataProviding {
|
||||
public init() {}
|
||||
|
||||
public func loadMetadata(sdkName: String, status: SDKStatus, platform: Platform, source: SDKSource) throws -> SystemFrameworkMetadata {
|
||||
public func loadMetadata(sdkName: String, status: SDKStatus, platform: Platform,
|
||||
source: SDKSource) throws -> SystemFrameworkMetadata
|
||||
{
|
||||
let sdkNamePath = AbsolutePath("/\(sdkName)")
|
||||
guard let sdkExtension = sdkNamePath.extension,
|
||||
let sdkType = SDKType(rawValue: sdkExtension)
|
||||
let sdkType = SDKType(rawValue: sdkExtension)
|
||||
else {
|
||||
throw SystemFrameworkMetadataProviderError.unsupportedSDK(name: sdkName)
|
||||
}
|
||||
|
|
|
@ -93,13 +93,20 @@ public final class XCFrameworkMetadataProvider: PrecompiledMetadataProvider, XCF
|
|||
|
||||
guard let library = libraries.first(where: {
|
||||
let hasValidArchitectures = !$0.architectures.filter(archs.contains).isEmpty
|
||||
guard hasValidArchitectures, let binaryPath = try? path(for: $0, binaryName: binaryName, xcframeworkPath: xcframeworkPath) else {
|
||||
guard hasValidArchitectures, let binaryPath = try? path(
|
||||
for: $0,
|
||||
binaryName: binaryName,
|
||||
xcframeworkPath: xcframeworkPath
|
||||
) else {
|
||||
return false
|
||||
}
|
||||
guard FileHandler.shared.exists(binaryPath) else {
|
||||
// The missing slice relative to the XCFramework folder. e.g ios-x86_64-simulator/Alamofire.framework/Alamofire
|
||||
let relativeArchitectureBinaryPath = binaryPath.components.suffix(3).joined(separator: "/")
|
||||
logger.warning("\(xcframeworkPath.basename) is missing architecture \(relativeArchitectureBinaryPath) defined in the Info.plist")
|
||||
logger
|
||||
.warning(
|
||||
"\(xcframeworkPath.basename) is missing architecture \(relativeArchitectureBinaryPath) defined in the Info.plist"
|
||||
)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
@ -110,7 +117,9 @@ public final class XCFrameworkMetadataProvider: PrecompiledMetadataProvider, XCF
|
|||
return try path(for: library, binaryName: binaryName, xcframeworkPath: xcframeworkPath)
|
||||
}
|
||||
|
||||
private func path(for library: XCFrameworkInfoPlist.Library, binaryName: String, xcframeworkPath: AbsolutePath) throws -> AbsolutePath {
|
||||
private func path(for library: XCFrameworkInfoPlist.Library, binaryName: String,
|
||||
xcframeworkPath: AbsolutePath) throws -> AbsolutePath
|
||||
{
|
||||
let binaryPath: AbsolutePath
|
||||
|
||||
switch library.path.extension {
|
||||
|
@ -122,7 +131,10 @@ public final class XCFrameworkMetadataProvider: PrecompiledMetadataProvider, XCF
|
|||
binaryPath = AbsolutePath(library.identifier, relativeTo: xcframeworkPath)
|
||||
.appending(RelativePath(library.path.pathString))
|
||||
default:
|
||||
throw XCFrameworkMetadataProviderError.fileTypeNotRecognised(file: library.path, frameworkName: xcframeworkPath.basename)
|
||||
throw XCFrameworkMetadataProviderError.fileTypeNotRecognised(
|
||||
file: library.path,
|
||||
frameworkName: xcframeworkPath.basename
|
||||
)
|
||||
}
|
||||
return binaryPath
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ public struct LintingIssue: CustomStringConvertible, Equatable {
|
|||
|
||||
// MARK: - Array Extension (Linting issues)
|
||||
|
||||
public extension Array where Element == LintingIssue {
|
||||
func printAndThrowIfNeeded() throws {
|
||||
extension Array where Element == LintingIssue {
|
||||
public func printAndThrowIfNeeded() throws {
|
||||
if count == 0 { return }
|
||||
|
||||
let errorIssues = filter { $0.severity == .error }
|
||||
|
|
|
@ -104,13 +104,13 @@ public final class SimulatorController: SimulatorControlling {
|
|||
let data = output.standardOutput.data(using: .utf8)!
|
||||
let json = try JSONSerialization.jsonObject(with: data, options: [])
|
||||
guard let dictionary = json as? [String: Any],
|
||||
let devicesJSON = dictionary["devices"] as? [String: [[String: Any]]]
|
||||
let devicesJSON = dictionary["devices"] as? [String: [[String: Any]]]
|
||||
else {
|
||||
return .just([])
|
||||
}
|
||||
|
||||
let devices = try devicesJSON.flatMap { (runtimeIdentifier, devicesJSON) -> [SimulatorDevice] in
|
||||
try devicesJSON.map { (deviceJSON) -> SimulatorDevice in
|
||||
let devices = try devicesJSON.flatMap { runtimeIdentifier, devicesJSON -> [SimulatorDevice] in
|
||||
try devicesJSON.map { deviceJSON -> SimulatorDevice in
|
||||
var deviceJSON = deviceJSON
|
||||
deviceJSON["runtimeIdentifier"] = runtimeIdentifier
|
||||
let deviceJSONData = try JSONSerialization.data(withJSONObject: deviceJSON, options: [])
|
||||
|
@ -135,7 +135,7 @@ public final class SimulatorController: SimulatorControlling {
|
|||
let data = output.standardOutput.data(using: .utf8)!
|
||||
let json = try JSONSerialization.jsonObject(with: data, options: [])
|
||||
guard let dictionary = json as? [String: Any],
|
||||
let runtimesJSON = dictionary["runtimes"] as? [Any]
|
||||
let runtimesJSON = dictionary["runtimes"] as? [Any]
|
||||
else {
|
||||
return .just([])
|
||||
}
|
||||
|
@ -151,11 +151,11 @@ public final class SimulatorController: SimulatorControlling {
|
|||
|
||||
public func devicesAndRuntimes() -> Single<[SimulatorDeviceAndRuntime]> {
|
||||
runtimes()
|
||||
.flatMap { (runtimes) -> Single<([SimulatorDevice], [SimulatorRuntime])> in
|
||||
.flatMap { runtimes -> Single<([SimulatorDevice], [SimulatorRuntime])> in
|
||||
self.devices().map { ($0, runtimes) }
|
||||
}
|
||||
.map { (input) -> [SimulatorDeviceAndRuntime] in
|
||||
input.0.compactMap { (device) -> SimulatorDeviceAndRuntime? in
|
||||
.map { input -> [SimulatorDeviceAndRuntime] in
|
||||
input.0.compactMap { device -> SimulatorDeviceAndRuntime? in
|
||||
guard let runtime = input.1.first(where: { $0.identifier == device.runtimeIdentifier }) else { return nil }
|
||||
return SimulatorDeviceAndRuntime(device: device, runtime: runtime)
|
||||
}
|
||||
|
@ -226,22 +226,22 @@ public final class SimulatorController: SimulatorControlling {
|
|||
minVersion: nil,
|
||||
deviceName: deviceName
|
||||
)
|
||||
.flatMap { (deviceAndRuntime) -> Single<String> in
|
||||
.flatMap { deviceAndRuntime -> Single<String> in
|
||||
.just("id=\(deviceAndRuntime.device.udid)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension SimulatorControlling {
|
||||
func findAvailableDevice(platform: Platform) -> Single<SimulatorDeviceAndRuntime> {
|
||||
extension SimulatorControlling {
|
||||
public func findAvailableDevice(platform: Platform) -> Single<SimulatorDeviceAndRuntime> {
|
||||
self.findAvailableDevice(platform: platform, version: nil, minVersion: nil, deviceName: nil)
|
||||
}
|
||||
}
|
||||
|
||||
private extension SimulatorDevice {
|
||||
extension SimulatorDevice {
|
||||
/// Attempts to boot the simulator.
|
||||
/// - returns: The `SimulatorDevice` with updated `isShutdown` field.
|
||||
func booted() throws -> Self {
|
||||
fileprivate func booted() throws -> Self {
|
||||
guard isShutdown else { return self }
|
||||
try System.shared.run(["/usr/bin/xcrun", "simctl", "boot", udid])
|
||||
return SimulatorDevice(
|
||||
|
|
|
@ -72,7 +72,8 @@ public final class BinaryLocator: BinaryLocating {
|
|||
.removingLastComponent()
|
||||
.appending(RelativePath("projects/cocoapods-interactor/bin/cocoapods-interactor"))
|
||||
#else
|
||||
let path = AbsolutePath(Bundle(for: BinaryLocator.self).bundleURL.path).appending(RelativePath("cocoapods-interactor/bin/cocoapods-interactor"))
|
||||
let path = AbsolutePath(Bundle(for: BinaryLocator.self).bundleURL.path)
|
||||
.appending(RelativePath("cocoapods-interactor/bin/cocoapods-interactor"))
|
||||
#endif
|
||||
guard FileHandler.shared.exists(path) else {
|
||||
throw BinaryLocatorError.cocoapodsInteractorNotFound
|
||||
|
|
|
@ -15,11 +15,15 @@ final class MockXcodeBuildController: XcodeBuildControlling {
|
|||
if let buildStub = buildStub {
|
||||
return buildStub(target, scheme, clean, arguments)
|
||||
} else {
|
||||
return Observable.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to build"))
|
||||
return Observable
|
||||
.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to build"))
|
||||
}
|
||||
}
|
||||
|
||||
var testStub: ((XcodeBuildTarget, String, Bool, XcodeBuildDestination, AbsolutePath?, AbsolutePath?, [XcodeBuildArgument]) -> Observable<SystemEvent<XcodeBuildOutput>>)? // swiftlint:disable:this line_length
|
||||
var testStub: (
|
||||
(XcodeBuildTarget, String, Bool, XcodeBuildDestination, AbsolutePath?, AbsolutePath?, [XcodeBuildArgument])
|
||||
-> Observable<SystemEvent<XcodeBuildOutput>>
|
||||
)?
|
||||
func test(
|
||||
_ target: XcodeBuildTarget,
|
||||
scheme: String,
|
||||
|
@ -32,11 +36,15 @@ final class MockXcodeBuildController: XcodeBuildControlling {
|
|||
if let testStub = testStub {
|
||||
return testStub(target, scheme, clean, destination, derivedDataPath, resultBundlePath, arguments)
|
||||
} else {
|
||||
return Observable.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to test"))
|
||||
return Observable
|
||||
.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to test"))
|
||||
}
|
||||
}
|
||||
|
||||
var archiveStub: ((XcodeBuildTarget, String, Bool, AbsolutePath, [XcodeBuildArgument]) -> Observable<SystemEvent<XcodeBuildOutput>>)?
|
||||
var archiveStub: (
|
||||
(XcodeBuildTarget, String, Bool, AbsolutePath, [XcodeBuildArgument])
|
||||
-> Observable<SystemEvent<XcodeBuildOutput>>
|
||||
)?
|
||||
func archive(_ target: XcodeBuildTarget,
|
||||
scheme: String,
|
||||
clean: Bool,
|
||||
|
@ -46,7 +54,8 @@ final class MockXcodeBuildController: XcodeBuildControlling {
|
|||
if let archiveStub = archiveStub {
|
||||
return archiveStub(target, scheme, clean, archivePath, arguments)
|
||||
} else {
|
||||
return Observable.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to archive"))
|
||||
return Observable
|
||||
.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to archive"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,16 +64,28 @@ final class MockXcodeBuildController: XcodeBuildControlling {
|
|||
if let createXCFrameworkStub = createXCFrameworkStub {
|
||||
return createXCFrameworkStub(frameworks, output)
|
||||
} else {
|
||||
return Observable.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to createXCFramework"))
|
||||
return Observable
|
||||
.error(
|
||||
TestError(
|
||||
"\(String(describing: MockXcodeBuildController.self)) received an unexpected call to createXCFramework"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var showBuildSettingsStub: ((XcodeBuildTarget, String, String) -> Single<[String: XcodeBuildSettings]>)?
|
||||
func showBuildSettings(_ target: XcodeBuildTarget, scheme: String, configuration: String) -> Single<[String: XcodeBuildSettings]> {
|
||||
func showBuildSettings(_ target: XcodeBuildTarget, scheme: String,
|
||||
configuration: String) -> Single<[String: XcodeBuildSettings]>
|
||||
{
|
||||
if let showBuildSettingsStub = showBuildSettingsStub {
|
||||
return showBuildSettingsStub(target, scheme, configuration)
|
||||
} else {
|
||||
return Single.error(TestError("\(String(describing: MockXcodeBuildController.self)) received an unexpected call to showBuildSettings"))
|
||||
return Single
|
||||
.error(
|
||||
TestError(
|
||||
"\(String(describing: MockXcodeBuildController.self)) received an unexpected call to showBuildSettings"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import Foundation
|
||||
@testable import TuistCore
|
||||
|
||||
public extension CloudResponseError.Error {
|
||||
static func test(code: String = "Code", message: String = "Message") -> CloudResponseError.Error {
|
||||
extension CloudResponseError.Error {
|
||||
public static func test(code: String = "Code", message: String = "Message") -> CloudResponseError.Error {
|
||||
.init(code: code, message: message)
|
||||
}
|
||||
}
|
||||
|
||||
public extension CloudResponseError {
|
||||
static func test(status: String = "Error status", errors: [Error]? = [.test()]) -> CloudResponseError {
|
||||
extension CloudResponseError {
|
||||
public static func test(status: String = "Error status", errors: [Error]? = [.test()]) -> CloudResponseError {
|
||||
.init(status: status, errors: errors)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,12 @@ public final class MockCloudClient: CloudClienting {
|
|||
return Single.error(error)
|
||||
} else {
|
||||
let objectCandidate = stubbedObjectPerURLRequest[urlRequest] ?? stubbedObject
|
||||
guard let object = objectCandidate as? T else { fatalError("This function input parameter type should be the same as the one provided in this object's initializer.\nReceived type: \(String(describing: objectCandidate.self))\nExpected type: \(T.self)") }
|
||||
guard let object = objectCandidate as? T
|
||||
else {
|
||||
fatalError(
|
||||
"This function input parameter type should be the same as the one provided in this object's initializer.\nReceived type: \(String(describing: objectCandidate.self))\nExpected type: \(T.self)"
|
||||
)
|
||||
}
|
||||
let responseCandidate = stubbedResponsePerURLRequest[urlRequest] ?? stubbedResponse
|
||||
return Single.just((object, responseCandidate!))
|
||||
}
|
||||
|
|
|
@ -4,14 +4,16 @@ import TuistCore
|
|||
import TuistSupportTesting
|
||||
import XCTest
|
||||
|
||||
public extension TuistTestCase {
|
||||
extension TuistTestCase {
|
||||
// MARK: - XCTAssertions
|
||||
|
||||
/// Fails the test if the list of linting issues doesn't contain the given linting issue.
|
||||
/// - Parameters:
|
||||
/// - issues: List of issues in which the issue will be checked.
|
||||
/// - issue: Issue to be checked in the list. If it doesn't exist, the test will fail.
|
||||
func XCTContainsLintingIssue(_ issues: [LintingIssue], _ issue: LintingIssue, file: StaticString = #file, line: UInt = #line) {
|
||||
public func XCTContainsLintingIssue(_ issues: [LintingIssue], _ issue: LintingIssue, file: StaticString = #file,
|
||||
line: UInt = #line)
|
||||
{
|
||||
if !issues.contains(issue) {
|
||||
XCTFail("The list doesn't contain the issue '\(issue)' and it should", file: file, line: line)
|
||||
}
|
||||
|
@ -21,7 +23,12 @@ public extension TuistTestCase {
|
|||
/// - Parameters:
|
||||
/// - issues: List of issues in which the issue will be checked.
|
||||
/// - issue: Issue to be checked in the list. If it doesn't exist, the test will fail.
|
||||
func XCTDoesNotContainLintingIssue(_ issues: [LintingIssue], _ issue: LintingIssue, file: StaticString = #file, line: UInt = #line) {
|
||||
public func XCTDoesNotContainLintingIssue(
|
||||
_ issues: [LintingIssue],
|
||||
_ issue: LintingIssue,
|
||||
file: StaticString = #file,
|
||||
line: UInt = #line
|
||||
) {
|
||||
if issues.contains(issue) {
|
||||
XCTFail("The list contains the issue '\(issue)' and it shouldn't", file: file, line: line)
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ import TSCBasic
|
|||
import TuistCore
|
||||
import TuistGraph
|
||||
|
||||
public extension GraphDependencyReference {
|
||||
static func testFramework(
|
||||
extension GraphDependencyReference {
|
||||
public static func testFramework(
|
||||
path: AbsolutePath = "/frameworks/tuist.framework",
|
||||
binaryPath: AbsolutePath = "/frameworks/tuist.framework/tuist",
|
||||
isCarthage: Bool = false,
|
||||
|
@ -26,7 +26,7 @@ public extension GraphDependencyReference {
|
|||
)
|
||||
}
|
||||
|
||||
static func testXCFramework(
|
||||
public static func testXCFramework(
|
||||
path: AbsolutePath = "/frameworks/tuist.xcframework",
|
||||
infoPlist: XCFrameworkInfoPlist = .test(),
|
||||
primaryBinaryPath: AbsolutePath = "/frameworks/tuist.xcframework/ios-arm64/tuist",
|
||||
|
@ -41,10 +41,10 @@ public extension GraphDependencyReference {
|
|||
)
|
||||
}
|
||||
|
||||
static func testLibrary(path: AbsolutePath = "/libraries/library.a",
|
||||
linking: BinaryLinking = .static,
|
||||
architectures: [BinaryArchitecture] = [BinaryArchitecture.arm64],
|
||||
product: Product = .staticLibrary) -> GraphDependencyReference
|
||||
public static func testLibrary(path: AbsolutePath = "/libraries/library.a",
|
||||
linking: BinaryLinking = .static,
|
||||
architectures: [BinaryArchitecture] = [BinaryArchitecture.arm64],
|
||||
product: Product = .staticLibrary) -> GraphDependencyReference
|
||||
{
|
||||
GraphDependencyReference.library(
|
||||
path: path,
|
||||
|
@ -54,9 +54,9 @@ public extension GraphDependencyReference {
|
|||
)
|
||||
}
|
||||
|
||||
static func testSDK(path: AbsolutePath = "/path/CoreData.framework",
|
||||
status: SDKStatus = .required,
|
||||
source: SDKSource = .system) -> GraphDependencyReference
|
||||
public static func testSDK(path: AbsolutePath = "/path/CoreData.framework",
|
||||
status: SDKStatus = .required,
|
||||
source: SDKSource = .system) -> GraphDependencyReference
|
||||
{
|
||||
GraphDependencyReference.sdk(
|
||||
path: path,
|
||||
|
@ -65,9 +65,9 @@ public extension GraphDependencyReference {
|
|||
)
|
||||
}
|
||||
|
||||
static func testProduct(target: String = "Target",
|
||||
productName: String = "Target.framework",
|
||||
platformFilter: BuildFilePlatformFilter = .ios) -> GraphDependencyReference
|
||||
public static func testProduct(target: String = "Target",
|
||||
productName: String = "Target.framework",
|
||||
platformFilter: BuildFilePlatformFilter = .ios) -> GraphDependencyReference
|
||||
{
|
||||
GraphDependencyReference.product(
|
||||
target: target,
|
||||
|
|
|
@ -3,8 +3,8 @@ import TSCBasic
|
|||
import TuistGraph
|
||||
@testable import TuistCore
|
||||
|
||||
public extension WorkspaceWithProjects {
|
||||
static func test(
|
||||
extension WorkspaceWithProjects {
|
||||
public static func test(
|
||||
workspace: Workspace = .test(),
|
||||
projects: [Project] = [.test()]
|
||||
) -> WorkspaceWithProjects {
|
||||
|
|
|
@ -180,7 +180,8 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
var invokedTestTargetsDependingOn = false
|
||||
var invokedTestTargetsDependingOnCount = 0
|
||||
var invokedTestTargetsDependingOnParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedTestTargetsDependingOnParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedTestTargetsDependingOnParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedTestTargetsDependingOnResult: Set<GraphTarget>! = []
|
||||
|
||||
func testTargetsDependingOn(path: AbsolutePath, name: String) -> Set<GraphTarget> {
|
||||
|
@ -193,10 +194,14 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
|
||||
var invokedDirectLocalTargetDependencies = false
|
||||
|
||||
var invokedDirectLocalTargetDependenciesCount = 0 // swiftlint:disable:this identifier_name
|
||||
var invokedDirectLocalTargetDependenciesParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedDirectLocalTargetDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var stubbedDirectLocalTargetDependenciesResult: Set<GraphTarget>! = [] // swiftlint:disable:this identifier_name
|
||||
var invokedDirectLocalTargetDependenciesCount = 0
|
||||
var invokedDirectLocalTargetDependenciesParameters: (
|
||||
path: AbsolutePath,
|
||||
name: String
|
||||
)?
|
||||
var invokedDirectLocalTargetDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedDirectLocalTargetDependenciesResult: Set<GraphTarget>! = []
|
||||
|
||||
func directLocalTargetDependencies(path: AbsolutePath, name: String) -> Set<GraphTarget> {
|
||||
invokedDirectLocalTargetDependencies = true
|
||||
|
@ -208,8 +213,9 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
|
||||
var invokedDirectTargetDependencies = false
|
||||
var invokedDirectTargetDependenciesCount = 0
|
||||
var invokedDirectTargetDependenciesParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedDirectTargetDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedDirectTargetDependenciesParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedDirectTargetDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedDirectTargetDependenciesResult: Set<GraphTarget>! = []
|
||||
|
||||
func directTargetDependencies(path: AbsolutePath, name: String) -> Set<GraphTarget> {
|
||||
|
@ -222,8 +228,9 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
|
||||
var invokedAppExtensionDependencies = false
|
||||
var invokedAppExtensionDependenciesCount = 0
|
||||
var invokedAppExtensionDependenciesParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedAppExtensionDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedAppExtensionDependenciesParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedAppExtensionDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedAppExtensionDependenciesResult: Set<GraphTarget>! = []
|
||||
|
||||
func appExtensionDependencies(path: AbsolutePath, name: String) -> Set<GraphTarget> {
|
||||
|
@ -236,8 +243,9 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
|
||||
var invokedResourceBundleDependencies = false
|
||||
var invokedResourceBundleDependenciesCount = 0
|
||||
var invokedResourceBundleDependenciesParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedResourceBundleDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedResourceBundleDependenciesParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedResourceBundleDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedResourceBundleDependenciesResult: Set<GraphDependencyReference>! = []
|
||||
|
||||
func resourceBundleDependencies(path: AbsolutePath, name: String) -> Set<GraphDependencyReference> {
|
||||
|
@ -250,8 +258,9 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
|
||||
var invokedDirectStaticDependencies = false
|
||||
var invokedDirectStaticDependenciesCount = 0
|
||||
var invokedDirectStaticDependenciesParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedDirectStaticDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedDirectStaticDependenciesParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedDirectStaticDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedDirectStaticDependenciesResult: Set<GraphDependencyReference>! = []
|
||||
|
||||
func directStaticDependencies(path: AbsolutePath, name: String) -> Set<GraphDependencyReference> {
|
||||
|
@ -279,7 +288,8 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
var invokedEmbeddableFrameworks = false
|
||||
var invokedEmbeddableFrameworksCount = 0
|
||||
var invokedEmbeddableFrameworksParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedEmbeddableFrameworksParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedEmbeddableFrameworksParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedEmbeddableFrameworksResult: Set<GraphDependencyReference>! = []
|
||||
|
||||
func embeddableFrameworks(path: AbsolutePath, name: String) -> Set<GraphDependencyReference> {
|
||||
|
@ -293,7 +303,8 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
var invokedLinkableDependencies = false
|
||||
var invokedLinkableDependenciesCount = 0
|
||||
var invokedLinkableDependenciesParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedLinkableDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedLinkableDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedLinkableDependenciesError: Error?
|
||||
var stubbedLinkableDependenciesResult: Set<GraphDependencyReference>! = []
|
||||
|
||||
|
@ -310,8 +321,9 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
|
||||
var invokedSearchablePathDependencies = false
|
||||
var invokedSearchablePathDependenciesCount = 0
|
||||
var invokedSearchablePathDependenciesParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedSearchablePathDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedSearchablePathDependenciesParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedSearchablePathDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedSearchablePathDependenciesError: Error?
|
||||
var stubbedSearchablePathDependenciesResult: Set<GraphDependencyReference>! = []
|
||||
|
||||
|
@ -329,7 +341,8 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
var invokedCopyProductDependencies = false
|
||||
var invokedCopyProductDependenciesCount = 0
|
||||
var invokedCopyProductDependenciesParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedCopyProductDependenciesParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedCopyProductDependenciesParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedCopyProductDependenciesResult: Set<GraphDependencyReference>! = []
|
||||
|
||||
func copyProductDependencies(path: AbsolutePath, name: String) -> Set<GraphDependencyReference> {
|
||||
|
@ -341,10 +354,14 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
}
|
||||
|
||||
var invokedLibrariesPublicHeadersFolders = false
|
||||
var invokedLibrariesPublicHeadersFoldersCount = 0 // swiftlint:disable:this identifier_name
|
||||
var invokedLibrariesPublicHeadersFoldersParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedLibrariesPublicHeadersFoldersParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var stubbedLibrariesPublicHeadersFoldersResult: Set<AbsolutePath>! = [] // swiftlint:disable:this identifier_name
|
||||
var invokedLibrariesPublicHeadersFoldersCount = 0
|
||||
var invokedLibrariesPublicHeadersFoldersParameters: (
|
||||
path: AbsolutePath,
|
||||
name: String
|
||||
)?
|
||||
var invokedLibrariesPublicHeadersFoldersParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedLibrariesPublicHeadersFoldersResult: Set<AbsolutePath>! = []
|
||||
|
||||
func librariesPublicHeadersFolders(path: AbsolutePath, name: String) -> Set<AbsolutePath> {
|
||||
invokedLibrariesPublicHeadersFolders = true
|
||||
|
@ -357,7 +374,8 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
var invokedLibrariesSearchPaths = false
|
||||
var invokedLibrariesSearchPathsCount = 0
|
||||
var invokedLibrariesSearchPathsParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedLibrariesSearchPathsParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedLibrariesSearchPathsParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedLibrariesSearchPathsResult: Set<AbsolutePath>! = []
|
||||
|
||||
func librariesSearchPaths(path: AbsolutePath, name: String) -> Set<AbsolutePath> {
|
||||
|
@ -370,8 +388,9 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
|
||||
var invokedLibrariesSwiftIncludePaths = false
|
||||
var invokedLibrariesSwiftIncludePathsCount = 0
|
||||
var invokedLibrariesSwiftIncludePathsParameters: (path: AbsolutePath, name: String)? // swiftlint:disable:this identifier_name
|
||||
var invokedLibrariesSwiftIncludePathsParametersList = [(path: AbsolutePath, name: String)]() // swiftlint:disable:this identifier_name
|
||||
var invokedLibrariesSwiftIncludePathsParameters: (path: AbsolutePath, name: String)?
|
||||
var invokedLibrariesSwiftIncludePathsParametersList =
|
||||
[(path: AbsolutePath, name: String)]()
|
||||
var stubbedLibrariesSwiftIncludePathsResult: Set<AbsolutePath>! = []
|
||||
|
||||
func librariesSwiftIncludePaths(path: AbsolutePath, name: String) -> Set<AbsolutePath> {
|
||||
|
@ -413,7 +432,7 @@ final class MockGraphTraverser: GraphTraversing {
|
|||
var invokedAllProjectDependencies = false
|
||||
var invokedAllProjectDependenciesCount = 0
|
||||
var invokedAllProjectDependenciesParameters: (path: AbsolutePath, Void)?
|
||||
var invokedAllProjectDependenciesParametersList = [(path: AbsolutePath, Void)]() // swiftlint:disable:this identifier_name
|
||||
var invokedAllProjectDependenciesParametersList = [(path: AbsolutePath, Void)]()
|
||||
var stubbedAllProjectDependenciesError: Error?
|
||||
var stubbedAllProjectDependenciesResult: Set<GraphDependencyReference>! = []
|
||||
|
||||
|
|
|
@ -3,16 +3,17 @@ import TSCBasic
|
|||
@testable import TuistCore
|
||||
|
||||
extension SimulatorDevice {
|
||||
static func test(dataPath: AbsolutePath = "/Library/Developer/CoreSimulator/Devices/3A8C9673-C1FD-4E33-8EFA-AEEBF43161CC/data",
|
||||
logPath: AbsolutePath = "/Library/Logs/CoreSimulator/3A8C9673-C1FD-4E33-8EFA-AEEBF43161CC",
|
||||
udid: String = "3A8C9673-C1FD-4E33-8EFA-AEEBF43161CC",
|
||||
isAvailable: Bool = true,
|
||||
deviceTypeIdentifier: String = "com.apple.CoreSimulator.SimDeviceType.iPad-Air--3rd-generation-",
|
||||
state: String = "Shutdown",
|
||||
name: String = "iPad Air (3rd generation)",
|
||||
availabilityError: String? = nil,
|
||||
runtimeIdentifier: String = "com.apple.CoreSimulator.SimRuntime.iOS-13-5") -> SimulatorDevice
|
||||
{
|
||||
static func test(
|
||||
dataPath: AbsolutePath = "/Library/Developer/CoreSimulator/Devices/3A8C9673-C1FD-4E33-8EFA-AEEBF43161CC/data",
|
||||
logPath: AbsolutePath = "/Library/Logs/CoreSimulator/3A8C9673-C1FD-4E33-8EFA-AEEBF43161CC",
|
||||
udid: String = "3A8C9673-C1FD-4E33-8EFA-AEEBF43161CC",
|
||||
isAvailable: Bool = true,
|
||||
deviceTypeIdentifier: String = "com.apple.CoreSimulator.SimDeviceType.iPad-Air--3rd-generation-",
|
||||
state: String = "Shutdown",
|
||||
name: String = "iPad Air (3rd generation)",
|
||||
availabilityError: String? = nil,
|
||||
runtimeIdentifier: String = "com.apple.CoreSimulator.SimRuntime.iOS-13-5"
|
||||
) -> SimulatorDevice {
|
||||
SimulatorDevice(
|
||||
dataPath: dataPath,
|
||||
logPath: logPath,
|
||||
|
|
|
@ -3,16 +3,18 @@ import TSCBasic
|
|||
@testable import TuistCore
|
||||
|
||||
extension SimulatorRuntime {
|
||||
// swiftlint:disable:next line_length
|
||||
static func test(bundlePath: AbsolutePath = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime",
|
||||
buildVersion: String = "17F61",
|
||||
// swiftlint:disable:next line_length
|
||||
runtimeRoot: AbsolutePath = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot",
|
||||
identifier: String = "com.apple.CoreSimulator.SimRuntime.iOS-13-5",
|
||||
version: SimulatorRuntimeVersion = "13.5",
|
||||
isAvailable: Bool = true,
|
||||
name: String = "iOS 13.5") -> SimulatorRuntime
|
||||
{
|
||||
static func test(
|
||||
bundlePath: AbsolutePath =
|
||||
"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime",
|
||||
buildVersion: String = "17F61",
|
||||
runtimeRoot: AbsolutePath =
|
||||
// swiftlint:disable:next line_length
|
||||
"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot",
|
||||
identifier: String = "com.apple.CoreSimulator.SimRuntime.iOS-13-5",
|
||||
version: SimulatorRuntimeVersion = "13.5",
|
||||
isAvailable: Bool = true,
|
||||
name: String = "iOS 13.5"
|
||||
) -> SimulatorRuntime {
|
||||
SimulatorRuntime(
|
||||
bundlePath: bundlePath,
|
||||
buildVersion: buildVersion,
|
||||
|
|
|
@ -39,7 +39,8 @@ enum CarthageControllerError: FatalError, Equatable {
|
|||
"""
|
||||
case let .xcframeworksProductionNotSupported(installedVersion):
|
||||
return """
|
||||
The version of Carthage installed in your environment (\(installedVersion.description)) doesn't suppport production of XCFrameworks.
|
||||
The version of Carthage installed in your environment (\(installedVersion
|
||||
.description)) doesn't suppport production of XCFrameworks.
|
||||
You have to update the tool to at least 0.37.0 version.
|
||||
"""
|
||||
}
|
||||
|
|
|
@ -177,7 +177,9 @@ public final class DependenciesController: DependenciesControlling {
|
|||
try carthageInteractor.clean(dependenciesDirectory: dependenciesDirectory)
|
||||
}
|
||||
|
||||
if let swiftPackageManagerDependencies = dependencies.swiftPackageManager, !swiftPackageManagerDependencies.packages.isEmpty {
|
||||
if let swiftPackageManagerDependencies = dependencies.swiftPackageManager,
|
||||
!swiftPackageManagerDependencies.packages.isEmpty
|
||||
{
|
||||
let swiftPackageManagerDependenciesGraph = try swiftPackageManagerInteractor.install(
|
||||
dependenciesDirectory: dependenciesDirectory,
|
||||
dependencies: swiftPackageManagerDependencies,
|
||||
|
|
|
@ -78,7 +78,10 @@ public final class DependenciesGraphController: DependenciesGraphControlling {
|
|||
do {
|
||||
return try JSONDecoder().decode(TuistGraph.DependenciesGraph.self, from: graphData)
|
||||
} catch {
|
||||
logger.debug("Failed to load dependencies graph, running `tuist dependencies fetch` should solve the problem.\nError: \(error)")
|
||||
logger
|
||||
.debug(
|
||||
"Failed to load dependencies graph, running `tuist dependencies fetch` should solve the problem.\nError: \(error)"
|
||||
)
|
||||
throw DependenciesGraphControllerError.failedToDecodeDependenciesGraph
|
||||
}
|
||||
}
|
||||
|
|
|
@ -297,7 +297,8 @@ extension PackageInfo.Target.Dependency: Decodable {
|
|||
init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
guard let key = values.allKeys.first(where: values.contains) else {
|
||||
throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key"))
|
||||
throw DecodingError
|
||||
.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key"))
|
||||
}
|
||||
|
||||
var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key)
|
||||
|
@ -331,7 +332,8 @@ extension PackageInfo.Product.ProductType: Decodable {
|
|||
init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
guard let key = values.allKeys.first(where: values.contains) else {
|
||||
throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key"))
|
||||
throw DecodingError
|
||||
.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key"))
|
||||
}
|
||||
switch key {
|
||||
case .library:
|
||||
|
|
|
@ -96,7 +96,10 @@ public final class SwiftPackageManagerInteractor: SwiftPackageManagerInteracting
|
|||
if shouldUpdate {
|
||||
try swiftPackageManagerController.update(at: pathsProvider.destinationSwiftPackageManagerDirectory, printOutput: true)
|
||||
} else {
|
||||
try swiftPackageManagerController.resolve(at: pathsProvider.destinationSwiftPackageManagerDirectory, printOutput: true)
|
||||
try swiftPackageManagerController.resolve(
|
||||
at: pathsProvider.destinationSwiftPackageManagerDirectory,
|
||||
printOutput: true
|
||||
)
|
||||
}
|
||||
|
||||
try saveDependencies(
|
||||
|
|
|
@ -16,7 +16,11 @@ enum PackageInfoMapperError: FatalError, Equatable {
|
|||
case minDeploymentTargetParsingFailed(ProjectDescription.Platform)
|
||||
|
||||
/// Thrown when no supported platforms are found for a package.
|
||||
case noSupportedPlatforms(name: String, configured: Set<ProjectDescription.Platform>, package: Set<ProjectDescription.Platform>)
|
||||
case noSupportedPlatforms(
|
||||
name: String,
|
||||
configured: Set<ProjectDescription.Platform>,
|
||||
package: Set<ProjectDescription.Platform>
|
||||
)
|
||||
|
||||
/// Thrown when `PackageInfo.Target.Dependency.byName` dependency cannot be resolved.
|
||||
case unknownByNameDependency(String)
|
||||
|
@ -31,7 +35,10 @@ enum PackageInfoMapperError: FatalError, Equatable {
|
|||
case unknownProductTarget(package: String, product: String, target: String)
|
||||
|
||||
/// Thrown when unsupported `PackageInfo.Target.TargetBuildSettingDescription` `Tool`/`SettingName` pair is found.
|
||||
case unsupportedSetting(PackageInfo.Target.TargetBuildSettingDescription.Tool, PackageInfo.Target.TargetBuildSettingDescription.SettingName)
|
||||
case unsupportedSetting(
|
||||
PackageInfo.Target.TargetBuildSettingDescription.Tool,
|
||||
PackageInfo.Target.TargetBuildSettingDescription.SettingName
|
||||
)
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
|
@ -164,7 +171,10 @@ public final class PackageInfoMapper: PackageInfoMapping {
|
|||
result[target.name] = Path(packageToFolder[packageInfo.key]!.appending(RelativePath(path)).pathString)
|
||||
} else {
|
||||
// remote binaries are checked out by SPM in artifacts/<Package>/<Target>.xcframework
|
||||
result[target.name] = Path(artifactsFolderForPackage.appending(component: "\(target.name).xcframework").pathString)
|
||||
result[target.name] = Path(
|
||||
artifactsFolderForPackage.appending(component: "\(target.name).xcframework")
|
||||
.pathString
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,37 +204,44 @@ public final class PackageInfoMapper: PackageInfoMapping {
|
|||
}
|
||||
}
|
||||
|
||||
let resolvedDependencies: [String: [ResolvedDependency]] = try packageInfos.values.reduce(into: [:]) { result, packageInfo in
|
||||
try packageInfo.targets
|
||||
.filter { targetToProducts[$0.name] != nil }
|
||||
.forEach { target in
|
||||
guard result[target.name] == nil else { return }
|
||||
result[target.name] = try ResolvedDependency.from(
|
||||
dependencies: target.dependencies,
|
||||
packageInfo: packageInfo,
|
||||
packageInfos: packageInfos,
|
||||
productToPackage: productToPackage,
|
||||
targetDependencyToFramework: targetDependencyToFramework
|
||||
)
|
||||
}
|
||||
}
|
||||
let resolvedDependencies: [String: [ResolvedDependency]] = try packageInfos.values
|
||||
.reduce(into: [:]) { result, packageInfo in
|
||||
try packageInfo.targets
|
||||
.filter { targetToProducts[$0.name] != nil }
|
||||
.forEach { target in
|
||||
guard result[target.name] == nil else { return }
|
||||
result[target.name] = try ResolvedDependency.from(
|
||||
dependencies: target.dependencies,
|
||||
packageInfo: packageInfo,
|
||||
packageInfos: packageInfos,
|
||||
productToPackage: productToPackage,
|
||||
targetDependencyToFramework: targetDependencyToFramework
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let externalDependencies: [String: [ProjectDescription.TargetDependency]] = try packageInfos.reduce(into: [:]) { result, packageInfo in
|
||||
try packageInfo.value.products.forEach { product in
|
||||
result[product.name] = try product.targets.flatMap { target in
|
||||
try ResolvedDependency.fromTarget(name: target, targetDependencyToFramework: targetDependencyToFramework).map {
|
||||
switch $0 {
|
||||
case let .xcframework(path):
|
||||
return .xcframework(path: path)
|
||||
case let .target(name):
|
||||
return .project(target: name, path: Path(packageToFolder[packageInfo.key]!.pathString))
|
||||
case .externalTarget:
|
||||
throw PackageInfoMapperError.unknownProductTarget(package: packageInfo.key, product: product.name, target: target)
|
||||
}
|
||||
let externalDependencies: [String: [ProjectDescription.TargetDependency]] = try packageInfos
|
||||
.reduce(into: [:]) { result, packageInfo in
|
||||
try packageInfo.value.products.forEach { product in
|
||||
result[product.name] = try product.targets.flatMap { target in
|
||||
try ResolvedDependency.fromTarget(name: target, targetDependencyToFramework: targetDependencyToFramework)
|
||||
.map {
|
||||
switch $0 {
|
||||
case let .xcframework(path):
|
||||
return .xcframework(path: path)
|
||||
case let .target(name):
|
||||
return .project(target: name, path: Path(packageToFolder[packageInfo.key]!.pathString))
|
||||
case .externalTarget:
|
||||
throw PackageInfoMapperError.unknownProductTarget(
|
||||
package: packageInfo.key,
|
||||
product: product.name,
|
||||
target: target
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let targetToPlatforms: [String: ProjectDescription.Platform] = try packageInfos.reduce(into: [:]) { result, packageInfo in
|
||||
try packageInfo.value.targets.forEach { target in
|
||||
|
@ -334,7 +351,8 @@ extension ProjectDescription.Target {
|
|||
return nil
|
||||
}
|
||||
|
||||
guard let product = ProjectDescription.Product.from(name: target.name, products: products, productTypes: productTypes) else {
|
||||
guard let product = ProjectDescription.Product.from(name: target.name, products: products, productTypes: productTypes)
|
||||
else {
|
||||
logger.debug("Target \(target.name) ignored by product type")
|
||||
return nil
|
||||
}
|
||||
|
@ -399,7 +417,10 @@ extension ProjectDescription.Platform {
|
|||
packageName: String
|
||||
) throws -> Self {
|
||||
let configuredPlatforms = Set(configured.map(\.descriptionPlatform))
|
||||
let packagePlatforms = Set(package.isEmpty ? ProjectDescription.Platform.allCases : try package.map { try $0.descriptionPlatform() })
|
||||
let packagePlatforms = Set(
|
||||
package.isEmpty ? ProjectDescription.Platform.allCases : try package
|
||||
.map { try $0.descriptionPlatform() }
|
||||
)
|
||||
let validPlatforms = configuredPlatforms.intersection(packagePlatforms)
|
||||
|
||||
if validPlatforms.contains(.iOS) {
|
||||
|
@ -583,7 +604,8 @@ extension ProjectDescription.Headers {
|
|||
// https://github.com/apple/swift-package-manager/blob/9b9bed7eaf0f38eeccd0d8ca06ae08f6689d1c3f/Sources/Xcodeproj/pbxproj.swift#L588-L609
|
||||
switch moduleMapType {
|
||||
case .header, .nestedHeader:
|
||||
let publicHeaders = FileHandler.shared.filesAndDirectoriesContained(in: publicHeadersPath)!.filter { $0.extension == "h" }
|
||||
let publicHeaders = FileHandler.shared.filesAndDirectoriesContained(in: publicHeadersPath)!
|
||||
.filter { $0.extension == "h" }
|
||||
return Headers(public: ProjectDescription.FileList(globs: publicHeaders.map { Path($0.pathString) }))
|
||||
case .none, .custom, .directory:
|
||||
return nil
|
||||
|
@ -697,7 +719,9 @@ extension ProjectDescription.Settings {
|
|||
|
||||
if !defines.isEmpty {
|
||||
let sortedDefines = defines.sorted { $0.key < $1.key }
|
||||
settingsDictionary["GCC_PREPROCESSOR_DEFINITIONS"] = .array(["$(inherited)"] + sortedDefines.map { key, value in "\(key)=\(value)" })
|
||||
settingsDictionary["GCC_PREPROCESSOR_DEFINITIONS"] = .array(["$(inherited)"] + sortedDefines.map { key, value in
|
||||
"\(key)=\(value)"
|
||||
})
|
||||
}
|
||||
|
||||
if !swiftDefines.isEmpty {
|
||||
|
@ -721,7 +745,8 @@ extension ProjectDescription.Settings {
|
|||
}
|
||||
|
||||
if let settingsToOverride = targetSettings[target.name] {
|
||||
let projectDescriptionSettingsToOverride = ProjectDescription.SettingsDictionary.from(settingsDictionary: settingsToOverride)
|
||||
let projectDescriptionSettingsToOverride = ProjectDescription.SettingsDictionary
|
||||
.from(settingsDictionary: settingsToOverride)
|
||||
settingsDictionary.merge(projectDescriptionSettingsToOverride)
|
||||
}
|
||||
|
||||
|
@ -758,7 +783,7 @@ extension ProjectDescription.Settings {
|
|||
return packageInfo.targets
|
||||
.filter { $0.name == target }
|
||||
.map {
|
||||
return PackageTarget(package: package, target: $0)
|
||||
PackageTarget(package: package, target: $0)
|
||||
}
|
||||
case .xcframework:
|
||||
return []
|
||||
|
@ -942,11 +967,11 @@ extension PackageInfo {
|
|||
) -> ProjectDescription.Settings? {
|
||||
var settingsDictionary: ProjectDescription.SettingsDictionary = [:]
|
||||
|
||||
if let cLanguageStandard = self.cLanguageStandard {
|
||||
if let cLanguageStandard = cLanguageStandard {
|
||||
settingsDictionary["GCC_C_LANGUAGE_STANDARD"] = .string(cLanguageStandard)
|
||||
}
|
||||
|
||||
if let cxxLanguageStandard = self.cxxLanguageStandard {
|
||||
if let cxxLanguageStandard = cxxLanguageStandard {
|
||||
settingsDictionary["CLANG_CXX_LANGUAGE_STANDARD"] = .string(cxxLanguageStandard)
|
||||
}
|
||||
|
||||
|
@ -1023,7 +1048,9 @@ extension PackageInfoMapper {
|
|||
if packageInfo.targets.contains(where: { $0.name == name }) {
|
||||
return Self.fromTarget(name: name, targetDependencyToFramework: targetDependencyToFramework)
|
||||
} else {
|
||||
guard let packageNameAndInfo = packageInfos.first(where: { $0.value.products.contains { $0.name == name } }) else {
|
||||
guard let packageNameAndInfo = packageInfos
|
||||
.first(where: { $0.value.products.contains { $0.name == name } })
|
||||
else {
|
||||
throw PackageInfoMapperError.unknownByNameDependency(name)
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ public final class SwiftPackageManagerGraphGenerator: SwiftPackageManagerGraphGe
|
|||
let checkoutsFolder = path.appending(component: "checkouts")
|
||||
let workspacePath = path.appending(component: "workspace-state.json")
|
||||
|
||||
let workspaceState = try JSONDecoder().decode(SwiftPackageManagerWorkspaceState.self, from: try FileHandler.shared.readFile(workspacePath))
|
||||
let workspaceState = try JSONDecoder()
|
||||
.decode(SwiftPackageManagerWorkspaceState.self, from: try FileHandler.shared.readFile(workspacePath))
|
||||
let packageInfos: [(name: String, folder: AbsolutePath, info: PackageInfo)]
|
||||
packageInfos = try workspaceState.object.dependencies.map(context: .concurrent) { dependency in
|
||||
let name = dependency.packageRef.name
|
||||
|
@ -140,6 +141,9 @@ public final class SwiftPackageManagerGraphGenerator: SwiftPackageManagerGraphGe
|
|||
result[Path(packageInfo.folder.pathString)] = manifest
|
||||
}
|
||||
|
||||
return DependenciesGraph(externalDependencies: preprocessInfo.productToExternalDependencies, externalProjects: externalProjects)
|
||||
return DependenciesGraph(
|
||||
externalDependencies: preprocessInfo.productToExternalDependencies,
|
||||
externalProjects: externalProjects
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,9 @@ public protocol SwiftPackageManagerModuleMapGenerating {
|
|||
public final class SwiftPackageManagerModuleMapGenerator: SwiftPackageManagerModuleMapGenerating {
|
||||
public init() {}
|
||||
|
||||
public func generate(moduleName: String, publicHeadersPath: AbsolutePath) throws -> (type: ModuleMapType, path: AbsolutePath?) {
|
||||
public func generate(moduleName: String,
|
||||
publicHeadersPath: AbsolutePath) throws -> (type: ModuleMapType, path: AbsolutePath?)
|
||||
{
|
||||
let umbrellaHeaderPath = publicHeadersPath.appending(component: moduleName + ".h")
|
||||
let nestedUmbrellaHeaderPath = publicHeadersPath.appending(component: moduleName).appending(component: moduleName + ".h")
|
||||
|
||||
|
@ -77,9 +79,9 @@ public final class SwiftPackageManagerModuleMapGenerator: SwiftPackageManagerMod
|
|||
if publicHeadersFolderContent.contains(publicHeadersPath.appending(moduleMapPath)) {
|
||||
return publicHeadersPath.appending(moduleMapPath)
|
||||
} else if publicHeadersFolderContent.count == 1,
|
||||
let nestedHeadersPath = publicHeadersFolderContent.first,
|
||||
FileHandler.shared.isFolder(nestedHeadersPath),
|
||||
FileHandler.shared.exists(nestedHeadersPath.appending(moduleMapPath))
|
||||
let nestedHeadersPath = publicHeadersFolderContent.first,
|
||||
FileHandler.shared.isFolder(nestedHeadersPath),
|
||||
FileHandler.shared.exists(nestedHeadersPath.appending(moduleMapPath))
|
||||
{
|
||||
return nestedHeadersPath.appending(moduleMapPath)
|
||||
} else {
|
||||
|
|
|
@ -10,7 +10,10 @@ public final class MockCarthageInteractor: CarthageInteracting {
|
|||
public init() {}
|
||||
|
||||
var invokedInstall = false
|
||||
var installStub: ((AbsolutePath, TuistGraph.CarthageDependencies, Set<TuistGraph.Platform>, Bool) throws -> TuistCore.DependenciesGraph)?
|
||||
var installStub: (
|
||||
(AbsolutePath, TuistGraph.CarthageDependencies, Set<TuistGraph.Platform>, Bool) throws -> TuistCore
|
||||
.DependenciesGraph
|
||||
)?
|
||||
|
||||
public func install(
|
||||
dependenciesDirectory: AbsolutePath,
|
||||
|
|
|
@ -4,9 +4,9 @@ import TSCBasic
|
|||
import TuistCore
|
||||
import TuistDependencies
|
||||
|
||||
public extension TuistCore.DependenciesGraph {
|
||||
extension TuistCore.DependenciesGraph {
|
||||
/// A snapshot of `graph.json` file.
|
||||
static var testJson: String {
|
||||
public static var testJson: String {
|
||||
"""
|
||||
{
|
||||
"externalDependencies" : {
|
||||
|
@ -22,14 +22,14 @@ public extension TuistCore.DependenciesGraph {
|
|||
"""
|
||||
}
|
||||
|
||||
static func test(
|
||||
public static func test(
|
||||
externalDependencies: [String: [TargetDependency]] = [:],
|
||||
externalProjects: [Path: Project] = [:]
|
||||
) -> Self {
|
||||
return .init(externalDependencies: externalDependencies, externalProjects: externalProjects)
|
||||
}
|
||||
|
||||
static func testXCFramework(
|
||||
public static func testXCFramework(
|
||||
name: String = "Test",
|
||||
path: Path = Path(AbsolutePath.root.appending(RelativePath("Test.xcframework")).pathString)
|
||||
) -> Self {
|
||||
|
@ -42,7 +42,7 @@ public extension TuistCore.DependenciesGraph {
|
|||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
static func test(spmFolder: Path, packageFolder: Path) -> Self {
|
||||
public static func test(spmFolder: Path, packageFolder: Path) -> Self {
|
||||
return .init(
|
||||
externalDependencies: [
|
||||
"Tuist": [.project(target: "Tuist", path: packageFolder)],
|
||||
|
@ -78,11 +78,20 @@ public extension TuistCore.DependenciesGraph {
|
|||
],
|
||||
dependencies: [
|
||||
.target(name: "TuistKit"),
|
||||
.project(target: "ALibrary", path: Self.packageFolder(spmFolder: spmFolder, packageName: "ADependency")),
|
||||
.project(target: "ALibraryUtils", path: Self.packageFolder(spmFolder: spmFolder, packageName: "ADependency")),
|
||||
.project(
|
||||
target: "ALibrary",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "ADependency")
|
||||
),
|
||||
.project(
|
||||
target: "ALibraryUtils",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "ADependency")
|
||||
),
|
||||
],
|
||||
settings: Self.spmSettings(with: [
|
||||
"HEADER_SEARCH_PATHS": ["$(SRCROOT)/customPath/cSearchPath", "$(SRCROOT)/customPath/cxxSearchPath"],
|
||||
"HEADER_SEARCH_PATHS": [
|
||||
"$(SRCROOT)/customPath/cSearchPath",
|
||||
"$(SRCROOT)/customPath/cxxSearchPath",
|
||||
],
|
||||
"OTHER_CFLAGS": ["CUSTOM_C_FLAG"],
|
||||
"OTHER_CPLUSPLUSFLAGS": ["CUSTOM_CXX_FLAG"],
|
||||
"OTHER_SWIFT_FLAGS": ["CUSTOM_SWIFT_FLAG1", "CUSTOM_SWIFT_FLAG2"],
|
||||
|
@ -101,7 +110,10 @@ public extension TuistCore.DependenciesGraph {
|
|||
"\(packageFolder.pathString)/Sources/TuistKit/**",
|
||||
],
|
||||
dependencies: [
|
||||
.project(target: "AnotherLibrary", path: Self.packageFolder(spmFolder: spmFolder, packageName: "another-dependency")),
|
||||
.project(
|
||||
target: "AnotherLibrary",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "another-dependency")
|
||||
),
|
||||
],
|
||||
settings: Self.spmSettings()
|
||||
),
|
||||
|
@ -112,7 +124,7 @@ public extension TuistCore.DependenciesGraph {
|
|||
)
|
||||
}
|
||||
|
||||
static func aDependency(spmFolder: Path) -> Self {
|
||||
public static func aDependency(spmFolder: Path) -> Self {
|
||||
let packageFolder = Self.packageFolder(spmFolder: spmFolder, packageName: "ADependency")
|
||||
return .init(
|
||||
externalDependencies: [
|
||||
|
@ -159,7 +171,7 @@ public extension TuistCore.DependenciesGraph {
|
|||
)
|
||||
}
|
||||
|
||||
static func anotherDependency(spmFolder: Path) -> Self {
|
||||
public static func anotherDependency(spmFolder: Path) -> Self {
|
||||
let packageFolder = Self.packageFolder(spmFolder: spmFolder, packageName: "another-dependency")
|
||||
return .init(
|
||||
externalDependencies: [
|
||||
|
@ -190,7 +202,7 @@ public extension TuistCore.DependenciesGraph {
|
|||
)
|
||||
}
|
||||
|
||||
static func alamofire(spmFolder: Path) -> Self {
|
||||
public static func alamofire(spmFolder: Path) -> Self {
|
||||
let packageFolder = Self.packageFolder(spmFolder: spmFolder, packageName: "Alamofire")
|
||||
return .init(
|
||||
externalDependencies: [
|
||||
|
@ -226,7 +238,7 @@ public extension TuistCore.DependenciesGraph {
|
|||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
static func googleAppMeasurement(spmFolder: Path) -> Self {
|
||||
public static func googleAppMeasurement(spmFolder: Path) -> Self {
|
||||
let packageFolder = Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleAppMeasurement")
|
||||
let artifactsFolder = Self.artifactsFolder(spmFolder: spmFolder, packageName: "GoogleAppMeasurement")
|
||||
|
||||
|
@ -263,9 +275,18 @@ public extension TuistCore.DependenciesGraph {
|
|||
target: "GULAppDelegateSwizzler",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(target: "GULMethodSwizzler", path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")),
|
||||
.project(target: "GULNSData", path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")),
|
||||
.project(target: "GULNetwork", path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")),
|
||||
.project(
|
||||
target: "GULMethodSwizzler",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(
|
||||
target: "GULNSData",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(
|
||||
target: "GULNetwork",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(target: "nanopb", path: Self.packageFolder(spmFolder: spmFolder, packageName: "nanopb")),
|
||||
.sdk(name: "libsqlite3.tbd", status: .required),
|
||||
.sdk(name: "libc++.tbd", status: .required),
|
||||
|
@ -285,14 +306,25 @@ public extension TuistCore.DependenciesGraph {
|
|||
"\(packageFolder.pathString)/GoogleAppMeasurementWithoutAdIdSupportWrapper/**",
|
||||
],
|
||||
dependencies: [
|
||||
.xcframework(path: "\(artifactsFolder.pathString)/GoogleAppMeasurementWithoutAdIdSupport.xcframework"),
|
||||
.xcframework(
|
||||
path: "\(artifactsFolder.pathString)/GoogleAppMeasurementWithoutAdIdSupport.xcframework"
|
||||
),
|
||||
.project(
|
||||
target: "GULAppDelegateSwizzler",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(target: "GULMethodSwizzler", path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")),
|
||||
.project(target: "GULNSData", path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")),
|
||||
.project(target: "GULNetwork", path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")),
|
||||
.project(
|
||||
target: "GULMethodSwizzler",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(
|
||||
target: "GULNSData",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(
|
||||
target: "GULNetwork",
|
||||
path: Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
),
|
||||
.project(target: "nanopb", path: Self.packageFolder(spmFolder: spmFolder, packageName: "nanopb")),
|
||||
.sdk(name: "libsqlite3.tbd", status: .required),
|
||||
.sdk(name: "libc++.tbd", status: .required),
|
||||
|
@ -309,7 +341,7 @@ public extension TuistCore.DependenciesGraph {
|
|||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
static func googleUtilities(spmFolder: Path, customProductTypes: [String: Product] = [:]) -> Self {
|
||||
public static func googleUtilities(spmFolder: Path, customProductTypes: [String: Product] = [:]) -> Self {
|
||||
let packageFolder = Self.packageFolder(spmFolder: spmFolder, packageName: "GoogleUtilities")
|
||||
return .init(
|
||||
externalDependencies: [
|
||||
|
@ -377,7 +409,7 @@ public extension TuistCore.DependenciesGraph {
|
|||
)
|
||||
}
|
||||
|
||||
static func nanopb(spmFolder: Path) -> Self {
|
||||
public static func nanopb(spmFolder: Path) -> Self {
|
||||
let packageFolder = Self.packageFolder(spmFolder: spmFolder, packageName: "nanopb")
|
||||
return .init(
|
||||
externalDependencies: [
|
||||
|
@ -442,13 +474,17 @@ extension DependenciesGraph {
|
|||
}
|
||||
|
||||
if case let .array(cDefinitions) = settingsDictionary["GCC_PREPROCESSOR_DEFINITIONS"] {
|
||||
settingsDictionary["GCC_PREPROCESSOR_DEFINITIONS"] = .array(["$(inherited)"] + (cDefinitions + ["SWIFT_PACKAGE=1"]).sorted())
|
||||
settingsDictionary["GCC_PREPROCESSOR_DEFINITIONS"] = .array(
|
||||
["$(inherited)"] + (cDefinitions + ["SWIFT_PACKAGE=1"])
|
||||
.sorted()
|
||||
)
|
||||
} else {
|
||||
settingsDictionary["GCC_PREPROCESSOR_DEFINITIONS"] = .array(["$(inherited)", "SWIFT_PACKAGE=1"])
|
||||
}
|
||||
|
||||
if case let .array(swiftDefinitions) = settingsDictionary["SWIFT_ACTIVE_COMPILATION_CONDITIONS"] {
|
||||
settingsDictionary["SWIFT_ACTIVE_COMPILATION_CONDITIONS"] = .array(["$(inherited)"] + ["SWIFT_PACKAGE"] + swiftDefinitions)
|
||||
settingsDictionary["SWIFT_ACTIVE_COMPILATION_CONDITIONS"] =
|
||||
.array(["$(inherited)"] + ["SWIFT_PACKAGE"] + swiftDefinitions)
|
||||
} else {
|
||||
settingsDictionary["SWIFT_ACTIVE_COMPILATION_CONDITIONS"] = .array(["$(inherited)"] + ["SWIFT_PACKAGE"])
|
||||
}
|
||||
|
|
|
@ -293,7 +293,11 @@ extension PackageInfo {
|
|||
],
|
||||
dependencies: [
|
||||
.target(name: "TuistKit", condition: nil),
|
||||
.product(name: "ALibrary", package: "a-dependency", condition: .init(platformNames: ["ios"], config: nil)),
|
||||
.product(
|
||||
name: "ALibrary",
|
||||
package: "a-dependency",
|
||||
condition: .init(platformNames: ["ios"], config: nil)
|
||||
),
|
||||
],
|
||||
publicHeadersPath: "custom/Public/Headers/Path",
|
||||
type: .regular,
|
||||
|
@ -302,12 +306,27 @@ extension PackageInfo {
|
|||
.init(tool: .cxx, name: .headerSearchPath, condition: nil, value: ["cxxSearchPath"]),
|
||||
.init(tool: .c, name: .unsafeFlags, condition: nil, value: ["CUSTOM_C_FLAG"]),
|
||||
.init(tool: .cxx, name: .unsafeFlags, condition: nil, value: ["CUSTOM_CXX_FLAG"]),
|
||||
.init(tool: .swift, name: .unsafeFlags, condition: nil, value: ["CUSTOM_SWIFT_FLAG1", "CUSTOM_SWIFT_FLAG2"]),
|
||||
.init(
|
||||
tool: .swift,
|
||||
name: .unsafeFlags,
|
||||
condition: nil,
|
||||
value: ["CUSTOM_SWIFT_FLAG1", "CUSTOM_SWIFT_FLAG2"]
|
||||
),
|
||||
.init(tool: .c, name: .define, condition: nil, value: ["C_DEFINE=C_VALUE"]),
|
||||
.init(tool: .cxx, name: .define, condition: nil, value: ["CXX_DEFINE=CXX_VALUE"]),
|
||||
.init(tool: .swift, name: .define, condition: nil, value: ["SWIFT_DEFINE"]),
|
||||
.init(tool: .linker, name: .linkedFramework, condition: .init(platformNames: ["watchos"], config: nil), value: ["WatchKit"]),
|
||||
.init(tool: .swift, name: .define, condition: .init(platformNames: ["tvos"], config: nil), value: ["SWIFT_TVOS_DEFINE"]),
|
||||
.init(
|
||||
tool: .linker,
|
||||
name: .linkedFramework,
|
||||
condition: .init(platformNames: ["watchos"], config: nil),
|
||||
value: ["WatchKit"]
|
||||
),
|
||||
.init(
|
||||
tool: .swift,
|
||||
name: .define,
|
||||
condition: .init(platformNames: ["tvos"], config: nil),
|
||||
value: ["SWIFT_TVOS_DEFINE"]
|
||||
),
|
||||
],
|
||||
checksum: nil
|
||||
),
|
||||
|
|
|
@ -36,6 +36,13 @@ public final class MockSwiftPackageManagerController: SwiftPackageManagerControl
|
|||
public func loadPackageInfo(at path: AbsolutePath) throws -> PackageInfo {
|
||||
invokedLoadPackageInfo = true
|
||||
return try loadPackageInfoStub?(path)
|
||||
?? .init(products: [], targets: [], platforms: [], cLanguageStandard: nil, cxxLanguageStandard: nil, swiftLanguageVersions: nil)
|
||||
?? .init(
|
||||
products: [],
|
||||
targets: [],
|
||||
platforms: [],
|
||||
cLanguageStandard: nil,
|
||||
cxxLanguageStandard: nil,
|
||||
swiftLanguageVersions: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class VersionProvider: VersionProviding {
|
|||
|
||||
func versions() -> AnyPublisher<[Version], Error> {
|
||||
return requestDispatcher.dispatch(resource: changelogResource())
|
||||
.flatMapLatest { (content, _) -> AnyPublisher<[Version], Error> in
|
||||
.flatMapLatest { content, _ -> AnyPublisher<[Version], Error> in
|
||||
do {
|
||||
let versions = try self.parseVersionsFromChangelog(content)
|
||||
return AnyPublisher(value: versions)
|
||||
|
|
|
@ -144,9 +144,9 @@ final class BuildPhaseGenerator: BuildPhaseGenerating {
|
|||
name: script.name,
|
||||
inputPaths: script.inputPaths.map { $0.relative(to: sourceRootPath).pathString },
|
||||
outputPaths: script.outputPaths.map { $0.relative(to: sourceRootPath).pathString },
|
||||
inputFileListPaths: script.inputFileListPaths.map { $0.relative(to: sourceRootPath).pathString }, // swiftlint:disable:this line_length
|
||||
inputFileListPaths: script.inputFileListPaths.map { $0.relative(to: sourceRootPath).pathString },
|
||||
|
||||
outputFileListPaths: script.outputFileListPaths.map { $0.relative(to: sourceRootPath).pathString }, // swiftlint:disable:this line_length
|
||||
outputFileListPaths: script.outputFileListPaths.map { $0.relative(to: sourceRootPath).pathString },
|
||||
|
||||
shellPath: script.shellPath,
|
||||
shellScript: script.shellScript(sourceRootPath: sourceRootPath),
|
||||
|
|
|
@ -200,9 +200,13 @@ final class ConfigGenerator: ConfigGenerating {
|
|||
project: project
|
||||
)
|
||||
) { $1 }
|
||||
settings.merge(testBundleTargetDerivedSettings(target: target, graphTraverser: graphTraverser, projectPath: project.path)) { $1 }
|
||||
settings
|
||||
.merge(testBundleTargetDerivedSettings(target: target, graphTraverser: graphTraverser, projectPath: project.path)) {
|
||||
$1
|
||||
}
|
||||
settings.merge(deploymentTargetDerivedSettings(target: target)) { $1 }
|
||||
settings.merge(watchTargetDerivedSettings(target: target, graphTraverser: graphTraverser, projectPath: project.path)) { $1 }
|
||||
settings
|
||||
.merge(watchTargetDerivedSettings(target: target, graphTraverser: graphTraverser, projectPath: project.path)) { $1 }
|
||||
}
|
||||
|
||||
private func generalTargetDerivedSettings(
|
||||
|
|
|
@ -516,8 +516,8 @@ final class LinkGenerator: LinkGenerating {
|
|||
}
|
||||
}
|
||||
|
||||
private extension XCBuildConfiguration {
|
||||
func append(setting name: String, value: String) {
|
||||
extension XCBuildConfiguration {
|
||||
fileprivate func append(setting name: String, value: String) {
|
||||
guard !value.isEmpty else {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -90,7 +90,11 @@ final class ProjectDescriptorGenerator: ProjectDescriptorGenerating {
|
|||
groups: groups,
|
||||
pbxproj: pbxproj
|
||||
)
|
||||
let configurationList = try configGenerator.generateProjectConfig(project: project, pbxproj: pbxproj, fileElements: fileElements)
|
||||
let configurationList = try configGenerator.generateProjectConfig(
|
||||
project: project,
|
||||
pbxproj: pbxproj,
|
||||
fileElements: fileElements
|
||||
)
|
||||
let pbxProject = try generatePbxproject(
|
||||
project: project,
|
||||
projectFileElements: fileElements,
|
||||
|
|
|
@ -60,7 +60,7 @@ class ProjectFileElements {
|
|||
let projectFileElements = projectFiles(project: project)
|
||||
files.formUnion(projectFileElements)
|
||||
|
||||
let sortedFiles = files.sorted { (one, two) -> Bool in
|
||||
let sortedFiles = files.sorted { one, two -> Bool in
|
||||
one.path < two.path
|
||||
}
|
||||
|
||||
|
@ -509,7 +509,12 @@ class ProjectFileElements {
|
|||
pbxproj: PBXProj)
|
||||
{
|
||||
let lastKnownFileType = fileAbsolutePath.extension.flatMap { Xcode.filetype(extension: $0) }
|
||||
let file = PBXFileReference(sourceTree: .group, name: name, lastKnownFileType: lastKnownFileType, path: fileRelativePath.pathString)
|
||||
let file = PBXFileReference(
|
||||
sourceTree: .group,
|
||||
name: name,
|
||||
lastKnownFileType: lastKnownFileType,
|
||||
path: fileRelativePath.pathString
|
||||
)
|
||||
pbxproj.add(object: file)
|
||||
toGroup.children.append(file)
|
||||
elements[fileAbsolutePath] = file
|
||||
|
|
|
@ -35,7 +35,7 @@ protocol SchemeDescriptorsGenerating {
|
|||
|
||||
// swiftlint:disable:next type_body_length
|
||||
final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
||||
private struct Constants {
|
||||
private enum Constants {
|
||||
/// Default last upgrade version for generated schemes.
|
||||
static let defaultLastUpgradeVersion = "1010"
|
||||
|
||||
|
@ -211,7 +211,10 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
|
||||
try buildAction.targets.forEach { buildActionTarget in
|
||||
guard
|
||||
let buildActionGraphTarget = graphTraverser.target(path: buildActionTarget.projectPath, name: buildActionTarget.name),
|
||||
let buildActionGraphTarget = graphTraverser.target(
|
||||
path: buildActionTarget.projectPath,
|
||||
name: buildActionTarget.name
|
||||
),
|
||||
let buildableReference = try createBuildableReference(
|
||||
graphTarget: buildActionGraphTarget,
|
||||
graphTraverser: graphTraverser,
|
||||
|
@ -225,11 +228,21 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
}
|
||||
|
||||
preActions = try buildAction.preActions.map {
|
||||
try schemeExecutionAction(action: $0, graphTraverser: graphTraverser, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||
try schemeExecutionAction(
|
||||
action: $0,
|
||||
graphTraverser: graphTraverser,
|
||||
generatedProjects: generatedProjects,
|
||||
rootPath: rootPath
|
||||
)
|
||||
}
|
||||
|
||||
postActions = try buildAction.postActions.map {
|
||||
try schemeExecutionAction(action: $0, graphTraverser: graphTraverser, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||
try schemeExecutionAction(
|
||||
action: $0,
|
||||
graphTraverser: graphTraverser,
|
||||
generatedProjects: generatedProjects,
|
||||
rootPath: rootPath
|
||||
)
|
||||
}
|
||||
|
||||
return XCScheme.BuildAction(
|
||||
|
@ -271,7 +284,10 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
|
||||
try testAction.targets.forEach { testableTarget in
|
||||
guard
|
||||
let testableGraphTarget = graphTraverser.target(path: testableTarget.target.projectPath, name: testableTarget.target.name),
|
||||
let testableGraphTarget = graphTraverser.target(
|
||||
path: testableTarget.target.projectPath,
|
||||
name: testableTarget.target.name
|
||||
),
|
||||
let reference = try createBuildableReference(
|
||||
graphTarget: testableGraphTarget,
|
||||
graphTraverser: graphTraverser,
|
||||
|
@ -311,20 +327,24 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
environments = environmentVariables(arguments.environment)
|
||||
}
|
||||
|
||||
let codeCoverageTargets = try testAction.codeCoverageTargets.compactMap { (target: TargetReference) -> XCScheme.BuildableReference? in
|
||||
guard let graphTarget = graphTraverser.target(path: target.projectPath, name: target.name) else { return nil }
|
||||
return try testCoverageTargetReferences(
|
||||
graphTarget: graphTarget,
|
||||
graphTraverser: graphTraverser,
|
||||
generatedProjects: generatedProjects,
|
||||
rootPath: rootPath
|
||||
)
|
||||
}
|
||||
let codeCoverageTargets = try testAction.codeCoverageTargets
|
||||
.compactMap { (target: TargetReference) -> XCScheme.BuildableReference? in
|
||||
guard let graphTarget = graphTraverser.target(path: target.projectPath, name: target.name) else { return nil }
|
||||
return try testCoverageTargetReferences(
|
||||
graphTarget: graphTarget,
|
||||
graphTraverser: graphTraverser,
|
||||
generatedProjects: generatedProjects,
|
||||
rootPath: rootPath
|
||||
)
|
||||
}
|
||||
|
||||
var macroExpansion: XCScheme.BuildableReference?
|
||||
if let expandVariableFromTarget = testAction.expandVariableFromTarget {
|
||||
guard
|
||||
let graphTarget = graphTraverser.target(path: expandVariableFromTarget.projectPath, name: expandVariableFromTarget.name)
|
||||
let graphTarget = graphTraverser.target(
|
||||
path: expandVariableFromTarget.projectPath,
|
||||
name: expandVariableFromTarget.name
|
||||
)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
@ -398,7 +418,10 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
) else { return nil }
|
||||
|
||||
if graphTarget.target.product.runnable {
|
||||
buildableProductRunnable = XCScheme.BuildableProductRunnable(buildableReference: buildableReference, runnableDebuggingMode: "0")
|
||||
buildableProductRunnable = XCScheme.BuildableProductRunnable(
|
||||
buildableReference: buildableReference,
|
||||
runnableDebuggingMode: "0"
|
||||
)
|
||||
} else {
|
||||
macroExpansion = buildableReference
|
||||
}
|
||||
|
@ -504,12 +527,16 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
var macroExpansion: XCScheme.BuildableReference?
|
||||
|
||||
if graphTarget.target.product.runnable {
|
||||
buildableProductRunnable = XCScheme.BuildableProductRunnable(buildableReference: buildableReference, runnableDebuggingMode: "0")
|
||||
buildableProductRunnable = XCScheme.BuildableProductRunnable(
|
||||
buildableReference: buildableReference,
|
||||
runnableDebuggingMode: "0"
|
||||
)
|
||||
} else {
|
||||
macroExpansion = buildableReference
|
||||
}
|
||||
|
||||
let buildConfiguration = scheme.profileAction?.configurationName ?? defaultReleaseBuildConfigurationName(in: graphTarget.project)
|
||||
let buildConfiguration = scheme.profileAction?
|
||||
.configurationName ?? defaultReleaseBuildConfigurationName(in: graphTarget.project)
|
||||
return XCScheme.ProfileAction(
|
||||
buildableProductRunnable: buildableProductRunnable,
|
||||
buildConfiguration: buildConfiguration,
|
||||
|
@ -534,7 +561,7 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
generatedProjects _: [AbsolutePath: GeneratedProject]) throws -> XCScheme.AnalyzeAction?
|
||||
{
|
||||
guard let target = defaultTargetReference(scheme: scheme),
|
||||
let graphTarget = graphTraverser.target(path: target.projectPath, name: target.name) else { return nil }
|
||||
let graphTarget = graphTraverser.target(path: target.projectPath, name: target.name) else { return nil }
|
||||
|
||||
let buildConfiguration = scheme.analyzeAction?.configurationName ?? graphTarget.project.defaultDebugBuildConfigurationName
|
||||
return XCScheme.AnalyzeAction(buildConfiguration: buildConfiguration)
|
||||
|
@ -554,18 +581,28 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.ArchiveAction?
|
||||
{
|
||||
guard let target = defaultTargetReference(scheme: scheme),
|
||||
let graphTarget = graphTraverser.target(path: target.projectPath, name: target.name) else { return nil }
|
||||
let graphTarget = graphTraverser.target(path: target.projectPath, name: target.name) else { return nil }
|
||||
|
||||
guard let archiveAction = scheme.archiveAction else {
|
||||
return defaultSchemeArchiveAction(for: graphTarget.project)
|
||||
}
|
||||
|
||||
let preActions = try archiveAction.preActions.map {
|
||||
try schemeExecutionAction(action: $0, graphTraverser: graphTraverser, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||
try schemeExecutionAction(
|
||||
action: $0,
|
||||
graphTraverser: graphTraverser,
|
||||
generatedProjects: generatedProjects,
|
||||
rootPath: rootPath
|
||||
)
|
||||
}
|
||||
|
||||
let postActions = try archiveAction.postActions.map {
|
||||
try schemeExecutionAction(action: $0, graphTraverser: graphTraverser, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||
try schemeExecutionAction(
|
||||
action: $0,
|
||||
graphTraverser: graphTraverser,
|
||||
generatedProjects: generatedProjects,
|
||||
rootPath: rootPath
|
||||
)
|
||||
}
|
||||
|
||||
return XCScheme.ArchiveAction(
|
||||
|
@ -656,13 +693,15 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
/// - graph: Tuist graph.
|
||||
/// - rootPath: Path to the project or workspace.
|
||||
/// - generatedProjects: Project paths mapped to generated projects.
|
||||
private func createBuildableReference(graphTarget: GraphTarget,
|
||||
graphTraverser: GraphTraversing,
|
||||
rootPath: AbsolutePath,
|
||||
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.BuildableReference?
|
||||
{
|
||||
private func createBuildableReference(
|
||||
graphTarget: GraphTarget,
|
||||
graphTraverser: GraphTraversing,
|
||||
rootPath: AbsolutePath,
|
||||
generatedProjects: [AbsolutePath: GeneratedProject]
|
||||
) throws -> XCScheme.BuildableReference? {
|
||||
let projectPath = graphTarget.project.xcodeProjPath
|
||||
guard let target = graphTraverser.target(path: graphTarget.project.path, name: graphTarget.target.name) else { return nil }
|
||||
guard let target = graphTraverser.target(path: graphTarget.project.path, name: graphTarget.target.name)
|
||||
else { return nil }
|
||||
guard let generatedProject = generatedProjects[projectPath] else { return nil }
|
||||
guard let pbxTarget = generatedProject.targets[graphTarget.target.name] else { return nil }
|
||||
let relativeXcodeProjectPath = resolveRelativeProjectPath(
|
||||
|
@ -791,7 +830,7 @@ final class SchemeDescriptorsGenerator: SchemeDescriptorsGenerating {
|
|||
|
||||
private func isSchemeForAppExtension(scheme: Scheme, graphTraverser: GraphTraversing) -> Bool? {
|
||||
guard let defaultTarget = defaultTargetReference(scheme: scheme),
|
||||
let graphTarget = graphTraverser.target(path: defaultTarget.projectPath, name: defaultTarget.name)
|
||||
let graphTarget = graphTraverser.target(path: defaultTarget.projectPath, name: defaultTarget.name)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ public protocol GraphToGraphVizMapping {
|
|||
///
|
||||
/// - Parameter graph: Graph to be converted into a GraphViz.Graph.
|
||||
/// - Returns: The GraphViz.Graph representation.
|
||||
func map(graph: TuistGraph.Graph, skipTestTargets: Bool, skipExternalDependencies: Bool, targetsToFilter: [String]) -> GraphViz.Graph
|
||||
func map(graph: TuistGraph.Graph, skipTestTargets: Bool, skipExternalDependencies: Bool, targetsToFilter: [String])
|
||||
-> GraphViz.Graph
|
||||
}
|
||||
|
||||
public final class GraphToGraphVizMapper: GraphToGraphVizMapping {
|
||||
|
@ -20,7 +21,9 @@ public final class GraphToGraphVizMapper: GraphToGraphVizMapping {
|
|||
///
|
||||
/// - Parameter graph: Graph to be converted into a GraphViz.Graph.
|
||||
/// - Returns: The GraphViz.Graph representation.
|
||||
public func map(graph: TuistGraph.Graph, skipTestTargets: Bool, skipExternalDependencies: Bool, targetsToFilter: [String]) -> GraphViz.Graph {
|
||||
public func map(graph: TuistGraph.Graph, skipTestTargets: Bool, skipExternalDependencies: Bool,
|
||||
targetsToFilter: [String]) -> GraphViz.Graph
|
||||
{
|
||||
var nodes: [GraphViz.Node] = []
|
||||
var dependencies: [GraphViz.Edge] = []
|
||||
var graphVizGraph = GraphViz.Graph(directed: true)
|
||||
|
@ -79,8 +82,8 @@ public final class GraphToGraphVizMapper: GraphToGraphVizMapping {
|
|||
}
|
||||
}
|
||||
|
||||
private extension GraphDependency {
|
||||
var isExternal: Bool {
|
||||
extension GraphDependency {
|
||||
fileprivate var isExternal: Bool {
|
||||
switch self {
|
||||
case .target:
|
||||
return false
|
||||
|
@ -89,7 +92,7 @@ private extension GraphDependency {
|
|||
}
|
||||
}
|
||||
|
||||
var name: String {
|
||||
fileprivate var name: String {
|
||||
switch self {
|
||||
case let .target(name: name, path: _):
|
||||
return name
|
||||
|
|
|
@ -48,7 +48,8 @@ public class EnvironmentLinter: EnvironmentLinting {
|
|||
|
||||
if !compatibleVersions.contains(version) {
|
||||
let versions = compatibleVersions.joined(separator: ", ")
|
||||
let message = "The project, which only supports the versions of Xcode \(versions), is not compatible with your selected version of Xcode, \(version)"
|
||||
let message =
|
||||
"The project, which only supports the versions of Xcode \(versions), is not compatible with your selected version of Xcode, \(version)"
|
||||
return [LintingIssue(reason: message, severity: .error)]
|
||||
} else {
|
||||
return []
|
||||
|
|
|
@ -53,7 +53,10 @@ public class GraphLinter: GraphLinting {
|
|||
switch mode {
|
||||
case .none, .all: return []
|
||||
case .relevant:
|
||||
let targets = graphTraverser.workspace.codeCoverageTargets(mode: mode, projects: Array(graphTraverser.projects.values))
|
||||
let targets = graphTraverser.workspace.codeCoverageTargets(
|
||||
mode: mode,
|
||||
projects: Array(graphTraverser.projects.values)
|
||||
)
|
||||
|
||||
if targets.isEmpty {
|
||||
return [
|
||||
|
@ -90,8 +93,8 @@ public class GraphLinter: GraphLinting {
|
|||
|
||||
func lintDependencies(graphTraverser: GraphTraversing) -> [LintingIssue] {
|
||||
var issues: [LintingIssue] = []
|
||||
let dependencyIssues = graphTraverser.dependencies.flatMap { (fromDependency, toDependencies) -> [LintingIssue] in
|
||||
toDependencies.flatMap { (toDependency) -> [LintingIssue] in
|
||||
let dependencyIssues = graphTraverser.dependencies.flatMap { fromDependency, toDependencies -> [LintingIssue] in
|
||||
toDependencies.flatMap { toDependency -> [LintingIssue] in
|
||||
guard case let GraphDependency.target(fromTargetName, fromTargetPath) = fromDependency else { return [] }
|
||||
guard case let GraphDependency.target(toTargetName, toTargetPath) = toDependency else { return [] }
|
||||
guard let fromTarget = graphTraverser.target(path: fromTargetPath, name: fromTargetName) else { return [] }
|
||||
|
@ -122,14 +125,16 @@ public class GraphLinter: GraphLinting {
|
|||
)
|
||||
|
||||
if !GraphLinter.validLinks.keys.contains(fromTarget) {
|
||||
let reason = "Target \(from.target.name) has a platform '\(from.target.platform)' and product '\(from.target.product)' invalid or not supported yet."
|
||||
let reason =
|
||||
"Target \(from.target.name) has a platform '\(from.target.platform)' and product '\(from.target.product)' invalid or not supported yet."
|
||||
let issue = LintingIssue(reason: reason, severity: .error)
|
||||
issues.append(issue)
|
||||
}
|
||||
let supportedTargets = GraphLinter.validLinks[fromTarget]
|
||||
|
||||
if supportedTargets == nil || supportedTargets?.contains(toTarget) == false {
|
||||
let reason = "Target \(from.target.name) has a dependency with target \(to.target.name) of type \(to.target.product) for platform '\(to.target.platform)' which is invalid or not supported yet."
|
||||
let reason =
|
||||
"Target \(from.target.name) has a dependency with target \(to.target.name) of type \(to.target.product) for platform '\(to.target.platform)' which is invalid or not supported yet."
|
||||
let issue = LintingIssue(reason: reason, severity: .error)
|
||||
issues.append(issue)
|
||||
}
|
||||
|
@ -155,7 +160,8 @@ public class GraphLinter: GraphLinting {
|
|||
return mismatchingBuildConfigurations.map {
|
||||
let expectedConfigurations = knownConfigurations.sorted()
|
||||
let configurations = $0.buildConfigurations.sorted()
|
||||
let reason = "The project '\($0.name)' has missing or mismatching configurations. It has \(configurations), other projects have \(expectedConfigurations)"
|
||||
let reason =
|
||||
"The project '\($0.name)' has missing or mismatching configurations. It has \(configurations), other projects have \(expectedConfigurations)"
|
||||
return LintingIssue(
|
||||
reason: reason,
|
||||
severity: .warning
|
||||
|
@ -178,7 +184,8 @@ public class GraphLinter: GraphLinting {
|
|||
}
|
||||
|
||||
if version.major < 11 {
|
||||
let reason = "The project contains package dependencies but the selected version of Xcode is not compatible. Need at least 11 but got \(version)"
|
||||
let reason =
|
||||
"The project contains package dependencies but the selected version of Xcode is not compatible. Need at least 11 but got \(version)"
|
||||
return [LintingIssue(reason: reason, severity: .error)]
|
||||
}
|
||||
|
||||
|
@ -226,8 +233,11 @@ public class GraphLinter: GraphLinting {
|
|||
|
||||
return watchApps.flatMap { watchApp -> [LintingIssue] in
|
||||
let watchAppIssues = lint(watchApp: watchApp, parentApp: app)
|
||||
let watchExtensions = graphTraverser.directLocalTargetDependencies(path: watchApp.path, name: watchApp.target.name)
|
||||
.filter { $0.target.product == .watch2Extension }
|
||||
let watchExtensions = graphTraverser.directLocalTargetDependencies(
|
||||
path: watchApp.path,
|
||||
name: watchApp.target.name
|
||||
)
|
||||
.filter { $0.target.product == .watch2Extension }
|
||||
|
||||
let watchExtensionIssues = watchExtensions.flatMap { watchExtension in
|
||||
lint(watchExtension: watchExtension, parentWatchApp: watchApp)
|
||||
|
@ -243,7 +253,9 @@ public class GraphLinter: GraphLinting {
|
|||
guard watchApp.target.bundleId.hasPrefix(parentApp.target.bundleId) else {
|
||||
return [
|
||||
LintingIssue(reason: """
|
||||
Watch app '\(watchApp.target.name)' bundleId: \(watchApp.target.bundleId) isn't prefixed with its parent's app '\(parentApp.target.bundleId)' bundleId '\(parentApp.target.bundleId)'
|
||||
Watch app '\(watchApp.target.name)' bundleId: \(watchApp.target
|
||||
.bundleId) isn't prefixed with its parent's app '\(parentApp.target.bundleId)' bundleId '\(parentApp.target
|
||||
.bundleId)'
|
||||
""", severity: .error),
|
||||
]
|
||||
}
|
||||
|
@ -254,7 +266,9 @@ public class GraphLinter: GraphLinting {
|
|||
guard watchExtension.target.bundleId.hasPrefix(parentWatchApp.target.bundleId) else {
|
||||
return [
|
||||
LintingIssue(reason: """
|
||||
Watch extension '\(watchExtension.target.name)' bundleId: \(watchExtension.target.bundleId) isn't prefixed with its parent's watch app '\(parentWatchApp.target.bundleId)' bundleId '\(parentWatchApp.target.bundleId)'
|
||||
Watch extension '\(watchExtension.target.name)' bundleId: \(watchExtension.target
|
||||
.bundleId) isn't prefixed with its parent's watch app '\(parentWatchApp.target
|
||||
.bundleId)' bundleId '\(parentWatchApp.target.bundleId)'
|
||||
""", severity: .error),
|
||||
]
|
||||
}
|
||||
|
@ -267,16 +281,26 @@ public class GraphLinter: GraphLinting {
|
|||
if !appClip.target.bundleId.hasPrefix(parentApp.target.bundleId) {
|
||||
foundIssues.append(
|
||||
LintingIssue(reason: """
|
||||
AppClip '\(appClip.target.name)' bundleId: \(appClip.target.bundleId) isn't prefixed with its parent's app '\(parentApp.target.name)' bundleId '\(parentApp.target.bundleId)'
|
||||
""", severity: .error))
|
||||
AppClip '\(appClip.target.name)' bundleId: \(appClip.target
|
||||
.bundleId) isn't prefixed with its parent's app '\(parentApp.target.name)' bundleId '\(parentApp.target
|
||||
.bundleId)'
|
||||
""", severity: .error)
|
||||
)
|
||||
}
|
||||
|
||||
if let entitlements = appClip.target.entitlements {
|
||||
if !FileHandler.shared.exists(entitlements) {
|
||||
foundIssues.append(LintingIssue(reason: "The entitlements at path '\(entitlements)' referenced by target does not exist", severity: .error))
|
||||
foundIssues
|
||||
.append(LintingIssue(
|
||||
reason: "The entitlements at path '\(entitlements)' referenced by target does not exist",
|
||||
severity: .error
|
||||
))
|
||||
}
|
||||
} else {
|
||||
foundIssues.append(LintingIssue(reason: "An AppClip '\(appClip.target.name)' requires its Parent Application Identifiers Entitlement to be set", severity: .error))
|
||||
foundIssues.append(LintingIssue(
|
||||
reason: "An AppClip '\(appClip.target.name)' requires its Parent Application Identifiers Entitlement to be set",
|
||||
severity: .error
|
||||
))
|
||||
}
|
||||
|
||||
return foundIssues
|
||||
|
@ -317,7 +341,8 @@ public class GraphLinter: GraphLinting {
|
|||
return nil
|
||||
}
|
||||
|
||||
let reason = "The bundle identifier '\(bundleIdKey.bundleId)' is being used by multiple targets: \(targetNames.sorted().listed())."
|
||||
let reason =
|
||||
"The bundle identifier '\(bundleIdKey.bundleId)' is being used by multiple targets: \(targetNames.sorted().listed())."
|
||||
return LintingIssue(reason: reason, severity: .warning)
|
||||
}.sorted(by: { $0.reason < $1.reason })
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@ class SchemeLinter: SchemeLinting {
|
|||
}
|
||||
}
|
||||
|
||||
private extension SchemeLinter {
|
||||
func lintReferencedBuildConfigurations(schemes: [Scheme], settings: Settings) -> [LintingIssue] {
|
||||
extension SchemeLinter {
|
||||
fileprivate func lintReferencedBuildConfigurations(schemes: [Scheme], settings: Settings) -> [LintingIssue] {
|
||||
let buildConfigurations = Array(settings.configurations.keys)
|
||||
return schemes.flatMap { lintScheme(scheme: $0, buildConfigurations: buildConfigurations) }
|
||||
}
|
||||
|
||||
func lintScheme(scheme: Scheme, buildConfigurations: [BuildConfiguration]) -> [LintingIssue] {
|
||||
fileprivate func lintScheme(scheme: Scheme, buildConfigurations: [BuildConfiguration]) -> [LintingIssue] {
|
||||
var issues: [LintingIssue] = []
|
||||
let buildConfigurationNames = buildConfigurations.map(\.name)
|
||||
|
||||
|
@ -39,13 +39,14 @@ private extension SchemeLinter {
|
|||
}
|
||||
|
||||
if let storeKitPath = runAction.options.storeKitConfigurationPath,
|
||||
!FileHandler.shared.exists(storeKitPath)
|
||||
!FileHandler.shared.exists(storeKitPath)
|
||||
{
|
||||
issues.append(
|
||||
LintingIssue(
|
||||
reason: "StoreKit configuration file not found at path \(storeKitPath.pathString)",
|
||||
severity: .error
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,18 +74,19 @@ private extension SchemeLinter {
|
|||
return issues
|
||||
}
|
||||
|
||||
func missingBuildConfigurationIssue(buildConfigurationName: String, actionDescription: String) -> LintingIssue {
|
||||
let reason = "The build configuration '\(buildConfigurationName)' specified in \(actionDescription) isn't defined in the project."
|
||||
fileprivate func missingBuildConfigurationIssue(buildConfigurationName: String, actionDescription: String) -> LintingIssue {
|
||||
let reason =
|
||||
"The build configuration '\(buildConfigurationName)' specified in \(actionDescription) isn't defined in the project."
|
||||
return LintingIssue(reason: reason, severity: .error)
|
||||
}
|
||||
|
||||
func lintExpandVariableTarget(schemes: [Scheme], targets: [Target]) -> [LintingIssue] {
|
||||
fileprivate func lintExpandVariableTarget(schemes: [Scheme], targets: [Target]) -> [LintingIssue] {
|
||||
let targetNames = targets.map(\.name)
|
||||
var issues: [LintingIssue] = []
|
||||
|
||||
for scheme in schemes {
|
||||
if let testAction = scheme.testAction,
|
||||
let target = testAction.expandVariableFromTarget
|
||||
let target = testAction.expandVariableFromTarget
|
||||
{
|
||||
if !targetNames.contains(target.name) {
|
||||
issues.append(missingExpandVariablesTargetIssue(missingTargetName: target.name, schemaName: scheme.name))
|
||||
|
@ -94,7 +96,7 @@ private extension SchemeLinter {
|
|||
return issues
|
||||
}
|
||||
|
||||
func lintCodeCoverageTargets(schemes: [Scheme], targets: [Target]) -> [LintingIssue] {
|
||||
fileprivate func lintCodeCoverageTargets(schemes: [Scheme], targets: [Target]) -> [LintingIssue] {
|
||||
let targetNames = targets.map(\.name)
|
||||
var issues: [LintingIssue] = []
|
||||
|
||||
|
@ -109,26 +111,31 @@ private extension SchemeLinter {
|
|||
return issues
|
||||
}
|
||||
|
||||
func missingCodeCoverageTargetIssue(missingTargetName: String, schemaName: String) -> LintingIssue {
|
||||
let reason = "The target '\(missingTargetName)' specified in \(schemaName) code coverage targets list isn't defined in the project."
|
||||
fileprivate func missingCodeCoverageTargetIssue(missingTargetName: String, schemaName: String) -> LintingIssue {
|
||||
let reason =
|
||||
"The target '\(missingTargetName)' specified in \(schemaName) code coverage targets list isn't defined in the project."
|
||||
return LintingIssue(reason: reason, severity: .error)
|
||||
}
|
||||
|
||||
func missingExpandVariablesTargetIssue(missingTargetName: String, schemaName: String) -> LintingIssue {
|
||||
let reason = "The target '\(missingTargetName)' specified in \(schemaName) expandVariableFromTarget isn't defined in the project."
|
||||
fileprivate func missingExpandVariablesTargetIssue(missingTargetName: String, schemaName: String) -> LintingIssue {
|
||||
let reason =
|
||||
"The target '\(missingTargetName)' specified in \(schemaName) expandVariableFromTarget isn't defined in the project."
|
||||
return LintingIssue(reason: reason, severity: .error)
|
||||
}
|
||||
|
||||
func projectSchemeCantReferenceRemoteTargets(schemes: [Scheme], project: Project) -> [LintingIssue] {
|
||||
fileprivate func projectSchemeCantReferenceRemoteTargets(schemes: [Scheme], project: Project) -> [LintingIssue] {
|
||||
schemes.flatMap { projectSchemeCantReferenceRemoteTargets(scheme: $0, project: project) }
|
||||
}
|
||||
|
||||
func projectSchemeCantReferenceRemoteTargets(scheme: Scheme, project: Project) -> [LintingIssue] {
|
||||
fileprivate func projectSchemeCantReferenceRemoteTargets(scheme: Scheme, project: Project) -> [LintingIssue] {
|
||||
var issues: [LintingIssue] = []
|
||||
|
||||
scheme.targetDependencies().forEach {
|
||||
if $0.projectPath != project.path {
|
||||
issues.append(.init(reason: "The target '\($0.name)' specified in scheme '\(scheme.name)' is not defined in the project named '\(project.name)'. Consider using a workspace scheme instead to reference a target in another project.", severity: .error))
|
||||
issues.append(.init(
|
||||
reason: "The target '\($0.name)' specified in scheme '\(scheme.name)' is not defined in the project named '\(project.name)'. Consider using a workspace scheme instead to reference a target in another project.",
|
||||
severity: .error
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,14 +51,20 @@ final class SettingsLinter: SettingsLinting {
|
|||
|
||||
private func lintNonEmptyConfig(project: Project) -> [LintingIssue] {
|
||||
guard !project.settings.configurations.isEmpty else {
|
||||
return [LintingIssue(reason: "The project at path \(project.path.pathString) has no configurations", severity: .error)]
|
||||
return [LintingIssue(
|
||||
reason: "The project at path \(project.path.pathString) has no configurations",
|
||||
severity: .error
|
||||
)]
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// TODO_MAJOR_CHANGE: Merge deploymentTarget and platform arguments together.
|
||||
private func lint(platform: Platform, isCompatibleWith deploymentTarget: DeploymentTarget) -> [LintingIssue] {
|
||||
let issue = LintingIssue(reason: "Found an inconsistency between a platform `\(platform.caseValue)` and deployment target `\(deploymentTarget.platform)`", severity: .error)
|
||||
let issue = LintingIssue(
|
||||
reason: "Found an inconsistency between a platform `\(platform.caseValue)` and deployment target `\(deploymentTarget.platform)`",
|
||||
severity: .error
|
||||
)
|
||||
|
||||
switch deploymentTarget {
|
||||
case .iOS: if platform != .iOS { return [issue] }
|
||||
|
|
|
@ -80,8 +80,8 @@ class StaticProductsGraphLinter: StaticProductsGraphLinting {
|
|||
|
||||
// Linking node case
|
||||
guard case let GraphDependency.target(targetName, targetPath) = dependency,
|
||||
let dependencyTarget = graphTraverser.target(path: targetPath, name: targetName),
|
||||
dependencyTarget.target.canLinkStaticProducts()
|
||||
let dependencyTarget = graphTraverser.target(path: targetPath, name: targetName),
|
||||
dependencyTarget.target.canLinkStaticProducts()
|
||||
else {
|
||||
return results
|
||||
}
|
||||
|
@ -106,12 +106,12 @@ class StaticProductsGraphLinter: StaticProductsGraphLinting {
|
|||
// during generation - as such those shouldn't be flagged
|
||||
//
|
||||
// reference: https://github.com/tuist/tuist/pull/664
|
||||
let apps: Set<GraphDependency> = linkedBy.filter { (dependency) -> Bool in
|
||||
let apps: Set<GraphDependency> = linkedBy.filter { dependency -> Bool in
|
||||
guard case let GraphDependency.target(targetName, targetPath) = dependency else { return false }
|
||||
guard let target = graphTraverser.target(path: targetPath, name: targetName) else { return false }
|
||||
return target.target.product == .app
|
||||
}
|
||||
let hostedTestBundles = linkedBy.filter { (dependency) -> Bool in
|
||||
let hostedTestBundles = linkedBy.filter { dependency -> Bool in
|
||||
guard case let GraphDependency.target(targetName, targetPath) = dependency else { return false }
|
||||
guard let target = graphTraverser.target(path: targetPath, name: targetName) else { return false }
|
||||
|
||||
|
@ -198,7 +198,8 @@ class StaticProductsGraphLinter: StaticProductsGraphLinting {
|
|||
private func lintIssue(from warning: StaticDependencyWarning) -> LintingIssue {
|
||||
let names = warning.linkingDependencies.map(\.description).listed()
|
||||
return LintingIssue(
|
||||
reason: "\(warning.staticProduct) has been linked from \(names), it is a static product so may introduce unwanted side effects.".uppercasingFirst,
|
||||
reason: "\(warning.staticProduct) has been linked from \(names), it is a static product so may introduce unwanted side effects."
|
||||
.uppercasingFirst,
|
||||
severity: .warning
|
||||
)
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ class TargetLinter: TargetLinting {
|
|||
allowed.formUnion(CharacterSet(charactersIn: "-."))
|
||||
|
||||
if !bundleIdentifier.unicodeScalars.allSatisfy({ allowed.contains($0) }) {
|
||||
let reason = "Invalid bundle identifier '\(bundleIdentifier)'. This string must be a uniform type identifier (UTI) that contains only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.) characters."
|
||||
let reason =
|
||||
"Invalid bundle identifier '\(bundleIdentifier)'. This string must be a uniform type identifier (UTI) that contains only alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.) characters."
|
||||
|
||||
return [LintingIssue(reason: reason, severity: .error)]
|
||||
}
|
||||
|
@ -72,7 +73,8 @@ class TargetLinter: TargetLinting {
|
|||
let allowed = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_")
|
||||
|
||||
if target.productName.unicodeScalars.allSatisfy(allowed.contains) == false {
|
||||
let reason = "Invalid product name '\(target.productName)'. This string must contain only alphanumeric (A-Z,a-z,0-9) and underscore (_) characters."
|
||||
let reason =
|
||||
"Invalid product name '\(target.productName)'. This string must contain only alphanumeric (A-Z,a-z,0-9) and underscore (_) characters."
|
||||
|
||||
return [LintingIssue(reason: reason, severity: .warning)]
|
||||
}
|
||||
|
@ -91,7 +93,10 @@ class TargetLinter: TargetLinting {
|
|||
if hasNoSources, hasNoDependencies, hasNoScripts {
|
||||
return [LintingIssue(reason: "The target \(target.name) doesn't contain source files.", severity: .warning)]
|
||||
} else if !supportsSources, !sources.isEmpty {
|
||||
return [LintingIssue(reason: "Target \(target.name) cannot contain sources. \(target.platform) \(target.product) targets don't support source files", severity: .error)]
|
||||
return [LintingIssue(
|
||||
reason: "Target \(target.name) cannot contain sources. \(target.platform) \(target.product) targets don't support source files",
|
||||
severity: .error
|
||||
)]
|
||||
}
|
||||
|
||||
return []
|
||||
|
@ -131,12 +136,13 @@ class TargetLinter: TargetLinting {
|
|||
}
|
||||
|
||||
private func validateCoreDataModelVersionsExist(target: Target) -> [LintingIssue] {
|
||||
target.coreDataModels.compactMap { (coreDataModel) -> LintingIssue? in
|
||||
target.coreDataModels.compactMap { coreDataModel -> LintingIssue? in
|
||||
let versionFileName = "\(coreDataModel.currentVersion).xcdatamodel"
|
||||
let versionPath = coreDataModel.path.appending(component: versionFileName)
|
||||
|
||||
if !FileHandler.shared.exists(versionPath) {
|
||||
let reason = "The default version of the Core Data model at path \(coreDataModel.path.pathString), \(coreDataModel.currentVersion), does not exist. There should be a file at \(versionPath.pathString)"
|
||||
let reason =
|
||||
"The default version of the Core Data model at path \(coreDataModel.path.pathString), \(coreDataModel.currentVersion), does not exist. There should be a file at \(versionPath.pathString)"
|
||||
return LintingIssue(reason: reason, severity: .error)
|
||||
}
|
||||
return nil
|
||||
|
@ -146,10 +152,11 @@ class TargetLinter: TargetLinting {
|
|||
private func lintInfoplistExists(target: Target) -> [LintingIssue] {
|
||||
var issues: [LintingIssue] = []
|
||||
if let infoPlist = target.infoPlist,
|
||||
case let InfoPlist.file(path: path) = infoPlist,
|
||||
!FileHandler.shared.exists(path)
|
||||
case let InfoPlist.file(path: path) = infoPlist,
|
||||
!FileHandler.shared.exists(path)
|
||||
{
|
||||
issues.append(LintingIssue(reason: "Info.plist file not found at path \(infoPlist.path!.pathString)", severity: .error))
|
||||
issues
|
||||
.append(LintingIssue(reason: "Info.plist file not found at path \(infoPlist.path!.pathString)", severity: .error))
|
||||
}
|
||||
return issues
|
||||
}
|
||||
|
@ -190,7 +197,10 @@ class TargetLinter: TargetLinting {
|
|||
if !deploymentTarget.version.matches(pattern: osVersionRegex) { return [versionFormatIssue] }
|
||||
|
||||
let platform = target.platform
|
||||
let inconsistentPlatformIssue = LintingIssue(reason: "Found an inconsistency between a platform `\(platform.caseValue)` and deployment target `\(deploymentTarget.platform)`", severity: .error)
|
||||
let inconsistentPlatformIssue = LintingIssue(
|
||||
reason: "Found an inconsistency between a platform `\(platform.caseValue)` and deployment target `\(deploymentTarget.platform)`",
|
||||
severity: .error
|
||||
)
|
||||
|
||||
switch deploymentTarget {
|
||||
case .iOS: if platform != .iOS { return [inconsistentPlatformIssue] }
|
||||
|
@ -208,7 +218,7 @@ class TargetLinter: TargetLinting {
|
|||
]
|
||||
|
||||
if let invalidProducts = invalidProductsForPlatforms[target.platform],
|
||||
invalidProducts.contains(target.product)
|
||||
invalidProducts.contains(target.product)
|
||||
{
|
||||
return [
|
||||
LintingIssue(
|
||||
|
@ -227,7 +237,10 @@ class TargetLinter: TargetLinting {
|
|||
target.dependencies.forEach { seen[$0, default: 0] += 1 }
|
||||
let duplicates = seen.enumerated().filter { $0.element.value > 1 }
|
||||
return duplicates.map {
|
||||
.init(reason: "Target '\(target.name)' has duplicate \($0.element.key.typeName) dependency specified: '\($0.element.key.name)'", severity: .warning)
|
||||
.init(
|
||||
reason: "Target '\(target.name)' has duplicate \($0.element.key.typeName) dependency specified: '\($0.element.key.name)'",
|
||||
severity: .warning
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,8 +262,8 @@ class TargetLinter: TargetLinting {
|
|||
}
|
||||
}
|
||||
|
||||
private extension TargetDependency {
|
||||
var typeName: String {
|
||||
extension TargetDependency {
|
||||
fileprivate var typeName: String {
|
||||
switch self {
|
||||
case .target:
|
||||
return "target"
|
||||
|
@ -271,7 +284,7 @@ private extension TargetDependency {
|
|||
}
|
||||
}
|
||||
|
||||
var name: String {
|
||||
fileprivate var name: String {
|
||||
switch self {
|
||||
case let .target(name):
|
||||
return name
|
||||
|
|
|
@ -23,7 +23,7 @@ class TargetScriptLinter: TargetScriptLinting {
|
|||
|
||||
private func lintEmbeddedScriptNotEmpty(_ script: TargetScript) -> [LintingIssue] {
|
||||
guard let script = script.embeddedScript,
|
||||
script.isEmpty
|
||||
script.isEmpty
|
||||
else { return [] }
|
||||
|
||||
return [
|
||||
|
|
|
@ -33,11 +33,12 @@ public final class GenerateInfoPlistProjectMapper: ProjectMapping {
|
|||
// MARK: - ProjectMapping
|
||||
|
||||
public func map(project: Project) throws -> (Project, [SideEffectDescriptor]) {
|
||||
let results = try project.targets.reduce(into: (targets: [Target](), sideEffects: [SideEffectDescriptor]())) { results, target in
|
||||
let (updatedTarget, sideEffects) = try map(target: target, project: project)
|
||||
results.targets.append(updatedTarget)
|
||||
results.sideEffects.append(contentsOf: sideEffects)
|
||||
}
|
||||
let results = try project.targets
|
||||
.reduce(into: (targets: [Target](), sideEffects: [SideEffectDescriptor]())) { results, target in
|
||||
let (updatedTarget, sideEffects) = try map(target: target, project: project)
|
||||
results.targets.append(updatedTarget)
|
||||
results.sideEffects.append(contentsOf: sideEffects)
|
||||
}
|
||||
|
||||
return (project.with(targets: results.targets), results.sideEffects)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,12 @@ import TuistSupport
|
|||
|
||||
enum ModuleMapMapperError: FatalError {
|
||||
case invalidTargetDependency(sourceProject: AbsolutePath, sourceTarget: String, dependentTarget: String)
|
||||
case invalidProjectTargetDependency(sourceProject: AbsolutePath, sourceTarget: String, dependentProject: AbsolutePath, dependentTarget: String)
|
||||
case invalidProjectTargetDependency(
|
||||
sourceProject: AbsolutePath,
|
||||
sourceTarget: String,
|
||||
dependentProject: AbsolutePath,
|
||||
dependentTarget: String
|
||||
)
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
|
@ -27,7 +32,8 @@ enum ModuleMapMapperError: FatalError {
|
|||
case let .invalidProjectTargetDependency(sourceProject, sourceTarget, dependentProject, dependentTarget):
|
||||
return """
|
||||
Target '\(sourceTarget)' of the project at path '\(sourceProject.pathString)' \
|
||||
depends on a target '\(dependentTarget)' of the project at path '\(dependentProject.pathString)' that can't be found. \
|
||||
depends on a target '\(dependentTarget)' of the project at path '\(dependentProject
|
||||
.pathString)' that can't be found. \
|
||||
Please make sure your project configuration is correct.
|
||||
"""
|
||||
}
|
||||
|
@ -103,7 +109,9 @@ public final class ModuleMapMapper: WorkspaceMapping {
|
|||
return (mappedWorkspace, [])
|
||||
}
|
||||
|
||||
private static func makeProjectsByPathWithTargetsByName(workspace: WorkspaceWithProjects) -> ([AbsolutePath: Project], [String: Target]) {
|
||||
private static func makeProjectsByPathWithTargetsByName(workspace: WorkspaceWithProjects)
|
||||
-> ([AbsolutePath: Project], [String: Target])
|
||||
{
|
||||
var projectsByPath = [AbsolutePath: Project]()
|
||||
var targetsByName = [String: Target]()
|
||||
workspace.projects.forEach { project in
|
||||
|
@ -149,7 +157,7 @@ public final class ModuleMapMapper: WorkspaceMapping {
|
|||
dependentTarget = dependentTargetFromName
|
||||
case let .project(name, path):
|
||||
guard let dependentProjectFromPath = projectsByPath[path],
|
||||
let dependentTargetFromName = targetsByName[name]
|
||||
let dependentTargetFromName = targetsByName[name]
|
||||
else {
|
||||
throw ModuleMapMapperError.invalidProjectTargetDependency(
|
||||
sourceProject: project.path,
|
||||
|
|
|
@ -130,7 +130,8 @@ public class ResourcesProjectMapper: ProjectMapping {
|
|||
private class BundleFinder {}
|
||||
|
||||
extension Foundation.Bundle {
|
||||
/// Since \(targetName) is a \(target.product), the bundle containing the resources is copied into the final product.
|
||||
/// Since \(targetName) is a \(target
|
||||
.product), the bundle containing the resources is copied into the final product.
|
||||
static var module: Bundle = {
|
||||
return Bundle(for: BundleFinder.self)
|
||||
}()
|
||||
|
|
|
@ -73,7 +73,9 @@ final class EmbedScriptGenerator: EmbedScriptGenerating {
|
|||
}
|
||||
|
||||
for frameworkReference in frameworkReferences {
|
||||
guard case let GraphDependencyReference.framework(path, _, _, dsymPath, bcsymbolmapPaths, _, _, _) = frameworkReference else {
|
||||
guard case let GraphDependencyReference
|
||||
.framework(path, _, _, dsymPath, bcsymbolmapPaths, _, _, _) = frameworkReference
|
||||
else {
|
||||
preconditionFailure("references need to be of type framework")
|
||||
break
|
||||
}
|
||||
|
@ -253,9 +255,9 @@ final class EmbedScriptGenerator: EmbedScriptGenerating {
|
|||
// swiftlint:enable line_length
|
||||
}
|
||||
|
||||
private extension RelativePath {
|
||||
extension RelativePath {
|
||||
/// Returns the basename without the extension.
|
||||
var basenameWithoutExt: String {
|
||||
fileprivate var basenameWithoutExt: String {
|
||||
if let ext = self.extension {
|
||||
return String(basename.dropLast(ext.count + 1))
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class SortedPBXGroup {
|
|||
// The sorting implementation was taken from https://github.com/yonaskolb/XcodeGen/blob/d64cfff8a1ca01fd8f18cbb41f72230983c4a192/Sources/XcodeGenKit/PBXProjGenerator.swift
|
||||
// We require exactly the same sort which places groups over files while using the PBXGroup from Xcodeproj.
|
||||
private func sort(with group: PBXGroup) {
|
||||
group.children.sort { (child1, child2) -> Bool in
|
||||
group.children.sort { child1, child2 -> Bool in
|
||||
let sortOrder1 = child1.getSortOrder()
|
||||
let sortOrder2 = child2.getSortOrder()
|
||||
if sortOrder1 != sortOrder2 {
|
||||
|
@ -35,14 +35,14 @@ class SortedPBXGroup {
|
|||
}
|
||||
}
|
||||
|
||||
private extension PBXGroup {
|
||||
var childGroups: [PBXGroup] {
|
||||
extension PBXGroup {
|
||||
fileprivate var childGroups: [PBXGroup] {
|
||||
children.compactMap { $0 as? PBXGroup }
|
||||
}
|
||||
}
|
||||
|
||||
private extension PBXFileElement {
|
||||
func getSortOrder() -> Int {
|
||||
extension PBXFileElement {
|
||||
fileprivate func getSortOrder() -> Int {
|
||||
switch self {
|
||||
case is PBXGroup:
|
||||
return -1
|
||||
|
@ -51,11 +51,11 @@ private extension PBXFileElement {
|
|||
}
|
||||
}
|
||||
|
||||
static func sortByNameThenPath(_ lhs: PBXFileElement, _ rhs: PBXFileElement) -> Bool {
|
||||
fileprivate static func sortByNameThenPath(_ lhs: PBXFileElement, _ rhs: PBXFileElement) -> Bool {
|
||||
lhs.namePathSortString.localizedStandardCompare(rhs.namePathSortString) == .orderedAscending
|
||||
}
|
||||
|
||||
var namePathSortString: String {
|
||||
fileprivate var namePathSortString: String {
|
||||
"\(name ?? path ?? "")\t\(name ?? "")\t\(path ?? "")"
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue