Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Define Archive Action on Scheme #697

Merged
merged 1 commit into from Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ Please, check out guidelines: https://keepachangelog.com/en/1.0.0/
- Add `ProjectDescription.Settings.defaultSettings` none case that don't override any `Project` or `Target` settings. https://github.com/tuist/tuist/pull/698 by @rowwingman.
- `ProjectEditor` utility https://github.com/tuist/tuist/pull/702 by @pepibumur.
- Fix warnings in the project, refactor SHA256 diegest code https://github.com/tuist/tuist/pull/704 by @rowwingman.
- Define `ArchiveAction` on `Scheme` https://github.com/tuist/tuist/pull/697 by @grsouza.

## 0.19.0

Expand Down
29 changes: 28 additions & 1 deletion Sources/ProjectDescription/Scheme.swift
Expand Up @@ -8,17 +8,20 @@ public struct Scheme: Equatable, Codable {
public let buildAction: BuildAction?
public let testAction: TestAction?
public let runAction: RunAction?
public let archiveAction: ArchiveAction?

public init(name: String,
shared: Bool = true,
buildAction: BuildAction? = nil,
testAction: TestAction? = nil,
runAction: RunAction? = nil) {
runAction: RunAction? = nil,
archiveAction: ArchiveAction? = nil) {
self.name = name
self.shared = shared
self.buildAction = buildAction
self.testAction = testAction
self.runAction = runAction
self.archiveAction = archiveAction
}
}

Expand Down Expand Up @@ -132,3 +135,27 @@ public struct RunAction: Equatable, Codable {
arguments: arguments)
}
}

// MARK: - Archive Action

public struct ArchiveAction: Equatable, Codable {
public let configurationName: String
public let revealArchiveInOrganizer: Bool
public let customArchiveName: String?
public let preActions: [ExecutionAction]
public let postActions: [ExecutionAction]

public init(
configurationName: String,
revealArchiveInOrganizer: Bool = true,
customArchiveName: String? = nil,
preActions: [ExecutionAction] = [],
postActions: [ExecutionAction] = []
) {
self.configurationName = configurationName
self.revealArchiveInOrganizer = revealArchiveInOrganizer
self.customArchiveName = customArchiveName
self.preActions = preActions
self.postActions = postActions
}
}
44 changes: 42 additions & 2 deletions Sources/TuistCore/Models/Scheme.swift
Expand Up @@ -9,19 +9,22 @@ public class Scheme: Equatable {
public let buildAction: BuildAction?
public let testAction: TestAction?
public let runAction: RunAction?
public let archiveAction: ArchiveAction?

// MARK: - Init

public init(name: String,
shared: Bool = false,
buildAction: BuildAction? = nil,
testAction: TestAction? = nil,
runAction: RunAction? = nil) {
runAction: RunAction? = nil,
archiveAction: ArchiveAction? = nil) {
self.name = name
self.shared = shared
self.buildAction = buildAction
self.testAction = testAction
self.runAction = runAction
self.archiveAction = archiveAction
}

// MARK: - Equatable
Expand All @@ -31,7 +34,8 @@ public class Scheme: Equatable {
lhs.shared == rhs.shared &&
lhs.buildAction == rhs.buildAction &&
lhs.testAction == rhs.testAction &&
lhs.runAction == rhs.runAction
lhs.runAction == rhs.runAction &&
lhs.archiveAction == rhs.archiveAction
}
}

Expand Down Expand Up @@ -174,3 +178,39 @@ public class RunAction: Equatable {
lhs.arguments == rhs.arguments
}
}

public class ArchiveAction: Equatable {
// MARK: - Attributes

public let configurationName: String
public let revealArchiveInOrganizer: Bool
public let customArchiveName: String?
public let preActions: [ExecutionAction]
public let postActions: [ExecutionAction]

// MARK: - Init

public init(
configurationName: String,
revealArchiveInOrganizer: Bool = true,
customArchiveName: String? = nil,
preActions: [ExecutionAction] = [],
postActions: [ExecutionAction] = []
) {
self.configurationName = configurationName
self.revealArchiveInOrganizer = revealArchiveInOrganizer
self.customArchiveName = customArchiveName
self.preActions = preActions
self.postActions = postActions
}

// MARK: - Equatable

public static func == (lhs: ArchiveAction, rhs: ArchiveAction) -> Bool {
return lhs.configurationName == rhs.configurationName
&& lhs.revealArchiveInOrganizer == rhs.revealArchiveInOrganizer
&& lhs.customArchiveName == rhs.customArchiveName
&& lhs.preActions == rhs.preActions
&& lhs.postActions == rhs.postActions
}
}
20 changes: 18 additions & 2 deletions Sources/TuistCoreTesting/Models/Scheme+TestData.swift
Expand Up @@ -46,16 +46,32 @@ public extension BuildAction {
}
}

public extension ArchiveAction {
static func test(configurationName: String = "Beta Release",
revealArchiveInOrganizer: Bool = true,
customArchiveName: String? = nil,
preActions: [ExecutionAction] = [],
postActions: [ExecutionAction] = []) -> ArchiveAction {
return ArchiveAction(configurationName: configurationName,
revealArchiveInOrganizer: revealArchiveInOrganizer,
customArchiveName: customArchiveName,
preActions: preActions,
postActions: postActions)
}
}

public extension Scheme {
static func test(name: String = "Test",
shared: Bool = false,
buildAction: BuildAction? = BuildAction.test(),
testAction: TestAction? = TestAction.test(),
runAction: RunAction? = RunAction.test()) -> Scheme {
runAction: RunAction? = RunAction.test(),
archiveAction: ArchiveAction? = ArchiveAction.test()) -> Scheme {
return Scheme(name: name,
shared: shared,
buildAction: buildAction,
testAction: testAction,
runAction: runAction)
runAction: runAction,
archiveAction: archiveAction)
}
}
28 changes: 26 additions & 2 deletions Sources/TuistGenerator/Generator/SchemesGenerator.swift
Expand Up @@ -73,6 +73,7 @@ final class SchemesGenerator: SchemesGenerating {
let generatedTestAction = schemeTestAction(scheme: scheme, project: project, generatedProject: generatedProject)
let generatedLaunchAction = schemeLaunchAction(scheme: scheme, project: project, generatedProject: generatedProject)
let generatedProfileAction = schemeProfileAction(scheme: scheme, project: project, generatedProject: generatedProject)
let generatedArchiveAction = schemeArchiveAction(scheme: scheme, project: project, generatedProject: generatedProject)

let scheme = XCScheme(name: scheme.name,
lastUpgradeVersion: SchemesGenerator.defaultLastUpgradeVersion,
Expand All @@ -82,7 +83,7 @@ final class SchemesGenerator: SchemesGenerating {
launchAction: generatedLaunchAction,
profileAction: generatedProfileAction,
analyzeAction: schemeAnalyzeAction(for: project),
archiveAction: schemeArchiveAction(for: project))
archiveAction: generatedArchiveAction)
try scheme.write(path: schemePath.path, override: true)
}

Expand Down Expand Up @@ -147,6 +148,29 @@ final class SchemesGenerator: SchemesGenerating {
testables: testables)
}

/// Generates the scheme archive action.
/// - Parameter scheme: Scheme manifest.
/// - Parameter project: Project manifest.
/// - Parameter generatedProject: Generated Xcode project.
/// - Returns: Scheme archive action.
func schemeArchiveAction(scheme: Scheme,
project: Project,
generatedProject: GeneratedProject) -> XCScheme.ArchiveAction {
guard let archiveAction = scheme.archiveAction else {
return defaultSchemeArchiveAction(for: project)
}

return XCScheme.ArchiveAction(buildConfiguration: archiveAction.configurationName,
revealArchiveInOrganizer: archiveAction.revealArchiveInOrganizer,
customArchiveName: archiveAction.customArchiveName,
preActions: schemeExecutionActions(actions: archiveAction.preActions,
project: project,
generatedProject: generatedProject),
postActions: schemeExecutionActions(actions: archiveAction.postActions,
project: project,
generatedProject: generatedProject))
}

/// Generates the array of BuildableReference for targets that the
/// coverage report should be generated for them.
///
Expand Down Expand Up @@ -439,7 +463,7 @@ final class SchemesGenerator: SchemesGenerating {
/// Returns the scheme archive action
///
/// - Returns: Scheme archive action.
func schemeArchiveAction(for project: Project) -> XCScheme.ArchiveAction {
func defaultSchemeArchiveAction(for project: Project) -> XCScheme.ArchiveAction {
let buildConfiguration = defaultReleaseBuildConfigurationName(in: project)
return XCScheme.ArchiveAction(buildConfiguration: buildConfiguration,
revealArchiveInOrganizer: true)
Expand Down
20 changes: 19 additions & 1 deletion Sources/TuistKit/Generator/GeneratorModelLoader.swift
Expand Up @@ -586,12 +586,14 @@ extension TuistCore.Scheme {
let buildAction = manifest.buildAction.map { TuistCore.BuildAction.from(manifest: $0) }
let testAction = manifest.testAction.map { TuistCore.TestAction.from(manifest: $0) }
let runAction = manifest.runAction.map { TuistCore.RunAction.from(manifest: $0) }
let archiveAction = manifest.archiveAction.map { TuistCore.ArchiveAction.from(manifest: $0) }

return Scheme(name: name,
shared: shared,
buildAction: buildAction,
testAction: testAction,
runAction: runAction)
runAction: runAction,
archiveAction: archiveAction)
}
}

Expand Down Expand Up @@ -636,6 +638,22 @@ extension TuistCore.RunAction {
}
}

extension TuistCore.ArchiveAction {
static func from(manifest: ProjectDescription.ArchiveAction) -> TuistCore.ArchiveAction {
let configurationName = manifest.configurationName
let revealArchiveInOrganizer = manifest.revealArchiveInOrganizer
let customArchiveName = manifest.customArchiveName
let preActions = manifest.preActions.map { TuistCore.ExecutionAction.from(manifest: $0) }
let postActions = manifest.postActions.map { TuistCore.ExecutionAction.from(manifest: $0) }

return TuistCore.ArchiveAction(configurationName: configurationName,
revealArchiveInOrganizer: revealArchiveInOrganizer,
customArchiveName: customArchiveName,
preActions: preActions,
postActions: postActions)
}
}

extension TuistCore.ExecutionAction {
static func from(manifest: ProjectDescription.ExecutionAction) -> TuistCore.ExecutionAction {
return ExecutionAction(title: manifest.title, scriptText: manifest.scriptText, target: manifest.target)
Expand Down
20 changes: 18 additions & 2 deletions Tests/TuistGeneratorTests/Generator/SchemesGeneratorTests.swift
Expand Up @@ -357,12 +357,28 @@ final class SchemeGeneratorTests: XCTestCase {
XCTAssertEqual(got.buildConfiguration, "Debug")
}

func test_schemeArchiveAction() {
let got = subject.schemeArchiveAction(for: .test())
func test_defaultSchemeArchiveAction() {
let got = subject.defaultSchemeArchiveAction(for: .test())
XCTAssertEqual(got.buildConfiguration, "Release")
XCTAssertEqual(got.revealArchiveInOrganizer, true)
}

func test_schemeArchiveAction() {
let target = Target.test(name: "App", platform: .iOS, product: .app)
let scheme = Scheme.test(archiveAction: ArchiveAction.test(configurationName: "Beta Release",
revealArchiveInOrganizer: true,
customArchiveName: "App [Beta]"))
let pbxTarget = PBXNativeTarget(name: "App")
let project = Project.test(path: AbsolutePath("/project.xcodeproj"), targets: [target])
let generatedProject = GeneratedProject.test(targets: ["App": pbxTarget])

let got = subject.schemeArchiveAction(scheme: scheme, project: project, generatedProject: generatedProject)

XCTAssertEqual(got.buildConfiguration, "Beta Release")
XCTAssertEqual(got.customArchiveName, "App [Beta]")
XCTAssertEqual(got.revealArchiveInOrganizer, true)
}

// MARK: - Private

private func generatedProject(targets: [Target]) -> GeneratedProject {
Expand Down
55 changes: 55 additions & 0 deletions docs/usage/projectswift.mdx
Expand Up @@ -673,6 +673,14 @@ A `Scheme` defines a collection of targets to `Build, Run, Test, Profile, Analyz
optional: true,
default: 'nil',
},
{
name: 'Archive action',
description: 'Action that runs the project archive.',
type: 'ArchiveAction',
typeLink: '#archive-action',
optional: true,
default: 'nil',
},
]}
/>

Expand Down Expand Up @@ -908,6 +916,53 @@ Arguments contain commandline arguments passed on launch and Environment variabl
]}
/>

### Archive Action

<PropertiesTable
properties={[
{
name: 'Configuration Name',
description:
'Indicates the build configuration to run the archive with.',
type: 'String',
optional: false,
default: '',
},
{
name: 'Reveal Archive in Organizer',
description:
'If set to true, Xcode will reveal the Organizer on completion.',
type: 'Bool',
optional: true,
default: 'true',
},
{
name: 'Custom Archive Name',
description:
'Set if you want to override Xcode's default archive name.',
type: 'String',
optional: true,
default: 'nil',
},
{
name: 'Pre-actions',
description:
'A list of actions that are executed before starting the archive process.',
type: '[ExecutionAction]',
optional: true,
default: '[]',
},
{
name: 'Post-actions',
description:
'A list of actions that are executed after the archive process.',
type: '[ExecutionAction]',
optional: true,
default: '[]',
},
]}
/>

## Settings

A `Settings` object contains an optional dictionary with build settings and relative path to an `.xcconfig` file. It is initialized with the following attributes:
Expand Down
2 changes: 2 additions & 0 deletions features/generate.feature
Expand Up @@ -180,6 +180,7 @@ Scenario: The project is an iOS application with multiple configurations (ios_ap
Then the scheme Framework2 has a build setting CUSTOM_FLAG with value "Debug" for the configuration Debug
Then the scheme Framework2 has a build setting CUSTOM_FLAG with value "Target.Beta" for the configuration Beta
Then the scheme Framework2 has a build setting CUSTOM_FLAG with value "Release" for the configuration Release
Then I should be able to archive for iOS the scheme App

Scenario: The project is an iOS application with CocoaPods dependencies (ios_app_with_pods)
Given that tuist is available
Expand Down Expand Up @@ -227,6 +228,7 @@ Scenario: The project is an iOS application with extensions (ios_app_with_extens
Then I should be able to build for iOS the scheme App
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'StickersPackExtension'
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'NotificationServiceExtension'
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'NotificationServiceExtension'

Scenario: The project is an iOS application with watch app (ios_app_with_watchapp2)
Given that tuist is available
Expand Down
7 changes: 4 additions & 3 deletions fixtures/ios_app_with_multi_configs/App/Project.swift
Expand Up @@ -11,9 +11,10 @@ let settings = Settings(base: [
], configurations: configurations)

let betaScheme = Scheme(name: "App-Beta",
shared: true,
buildAction: BuildAction(targets: ["App"]),
runAction: RunAction(configurationName: "Beta", executable: "App"))
shared: true,
buildAction: BuildAction(targets: ["App"]),
runAction: RunAction(configurationName: "Beta", executable: "App"),
archiveAction: ArchiveAction(configurationName: "Beta"))

let project = Project(name: "MainApp",
settings: settings,
Expand Down