Add force flag to the update and install command (#157)
* Define force argument * Add documentation * Update Installer to accept force installs * Add tests
This commit is contained in:
parent
3a15268a32
commit
30ff33c3cc
|
@ -1,6 +1,5 @@
|
|||
import Basic
|
||||
import Foundation
|
||||
import TuistCore
|
||||
|
||||
/// Protocol that defines the interface of a local environment controller.
|
||||
/// It manages the local directory where tuistenv stores the tuist versions and user settings.
|
||||
|
|
|
@ -81,7 +81,7 @@ final class BundleCommand: Command {
|
|||
// Installing
|
||||
if !fileHandler.exists(versionPath) {
|
||||
printer.print("Version \(version) not available locally. Installing...")
|
||||
try installer.install(version: version)
|
||||
try installer.install(version: version, force: false)
|
||||
}
|
||||
|
||||
// Copying
|
||||
|
|
|
@ -93,7 +93,7 @@ class CommandRunner: CommandRunning {
|
|||
if let highgestVersion = versionsController.semverVersions().last?.description {
|
||||
version = highgestVersion
|
||||
} else {
|
||||
try updater.update()
|
||||
try updater.update(force: false)
|
||||
guard let highgestVersion = versionsController.semverVersions().last?.description else {
|
||||
throw CommandRunnerError.versionNotFound
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class CommandRunner: CommandRunning {
|
|||
func runVersion(_ version: String) throws {
|
||||
if !versionsController.versions().contains(where: { $0.description == version }) {
|
||||
printer.print("Version \(version) not found locally. Installing...")
|
||||
try installer.install(version: version)
|
||||
try installer.install(version: version, force: false)
|
||||
}
|
||||
|
||||
let path = versionsController.path(version: version)
|
||||
|
|
|
@ -2,19 +2,33 @@ import Foundation
|
|||
import TuistCore
|
||||
import Utility
|
||||
|
||||
/// Command that installs new versions of Tuist in the system.
|
||||
final class InstallCommand: Command {
|
||||
// MARK: - Command
|
||||
|
||||
/// Command name.
|
||||
static var command: String = "install"
|
||||
|
||||
/// Command description.
|
||||
static var overview: String = "Installs a version of tuist"
|
||||
|
||||
// MARK: - Attributes
|
||||
|
||||
/// Controller to manage system versions.
|
||||
private let versionsController: VersionsControlling
|
||||
|
||||
/// Printer instance to output messages to the user.
|
||||
private let printer: Printing
|
||||
|
||||
/// Installer instance to run the installation.
|
||||
private let installer: Installing
|
||||
|
||||
/// Version argument to specify the version that will be installed.
|
||||
let versionArgument: PositionalArgument<String>
|
||||
|
||||
/// Force argument (-f). When passed, it re-installs the version compiling it from the source.
|
||||
let forceArgument: OptionArgument<Bool>
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
convenience init(parser: ArgumentParser) {
|
||||
|
@ -37,15 +51,24 @@ final class InstallCommand: Command {
|
|||
kind: String.self,
|
||||
optional: false,
|
||||
usage: "The version of tuist to be installed")
|
||||
forceArgument = subParser.add(option: "--force",
|
||||
shortName: "-f",
|
||||
kind: Bool.self,
|
||||
usage: "Re-installs the version compiling it from the source", completion: nil)
|
||||
}
|
||||
|
||||
/// Runs the install command.
|
||||
///
|
||||
/// - Parameter result: Result obtained from parsing the CLI arguments.
|
||||
/// - Throws: An error if the installation process fails.
|
||||
func run(with result: ArgumentParser.Result) throws {
|
||||
let force = result.get(forceArgument) ?? false
|
||||
let version = result.get(versionArgument)!
|
||||
let versions = versionsController.versions().map({ $0.description })
|
||||
if versions.contains(version) {
|
||||
printer.print(warning: "Version \(version) already installed, skipping")
|
||||
return
|
||||
}
|
||||
try installer.install(version: version)
|
||||
try installer.install(version: version, force: force)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,39 +2,63 @@ import Foundation
|
|||
import TuistCore
|
||||
import Utility
|
||||
|
||||
/// Command that updates the version of Tuist in the environment.
|
||||
final class UpdateCommand: Command {
|
||||
// MARK: - Command
|
||||
|
||||
/// Name of the command.
|
||||
static var command: String = "update"
|
||||
|
||||
/// Description of the command.
|
||||
static var overview: String = "Installs the latest version if it's not already installed"
|
||||
|
||||
// MARK: - Attributes
|
||||
|
||||
private let versionsController: VersionsControlling
|
||||
/// Updater instance that runs the update.
|
||||
private let updater: Updating
|
||||
|
||||
/// Printer instance to output updates during the process.
|
||||
private let printer: Printing
|
||||
|
||||
/// Force argument (-f). When passed, it re-installs the latest version compiling it from the source.
|
||||
let forceArgument: OptionArgument<Bool>
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
/// Initializes the update command.
|
||||
///
|
||||
/// - Parameter parser: Argument parser where the command should be registered.
|
||||
convenience init(parser: ArgumentParser) {
|
||||
self.init(parser: parser,
|
||||
versionsController: VersionsController(),
|
||||
updater: Updater(),
|
||||
printer: Printer())
|
||||
}
|
||||
|
||||
/// Initializes the update command.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - parser: Argument parser where the command should be registered.
|
||||
/// - updater: Updater instance that runs the update.
|
||||
/// - printer: Printer instance to output updates during the process.
|
||||
init(parser: ArgumentParser,
|
||||
versionsController: VersionsControlling,
|
||||
updater: Updating,
|
||||
printer: Printer) {
|
||||
parser.add(subparser: UpdateCommand.command, overview: UpdateCommand.overview)
|
||||
self.versionsController = versionsController
|
||||
printer: Printing) {
|
||||
let subParser = parser.add(subparser: UpdateCommand.command, overview: UpdateCommand.overview)
|
||||
self.printer = printer
|
||||
self.updater = updater
|
||||
forceArgument = subParser.add(option: "--force",
|
||||
shortName: "-f",
|
||||
kind: Bool.self,
|
||||
usage: "Re-installs the latest version compiling it from the source", completion: nil)
|
||||
}
|
||||
|
||||
func run(with _: ArgumentParser.Result) throws {
|
||||
/// Runs the update command.
|
||||
///
|
||||
/// - Parameter result: Result obtained from parsing the CLI arguments.
|
||||
/// - Throws: An error if the update process fails.
|
||||
func run(with result: ArgumentParser.Result) throws {
|
||||
let force = result.get(forceArgument) ?? false
|
||||
printer.print(section: "Checking for updates...")
|
||||
try updater.update()
|
||||
try updater.update(force: force)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,21 @@ import Basic
|
|||
import Foundation
|
||||
import TuistCore
|
||||
|
||||
/// Protocol that defines the interface of an instance that can install versions of Tuist.
|
||||
protocol Installing: AnyObject {
|
||||
func install(version: String) throws
|
||||
/// It installs a version of Tuist in the local environment.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - version: Version to be installed.
|
||||
/// - force: When true, it ignores the Swift version and compiles it from the source.
|
||||
/// - Throws: An error if the installation fails.
|
||||
func install(version: String, force: Bool) throws
|
||||
}
|
||||
|
||||
/// Error thrown by the installer.
|
||||
///
|
||||
/// - versionNotFound: When the specified version cannot be found.
|
||||
/// - incompatibleSwiftVersion: When the environment Swift version is incompatible with the Swift version Tuist has been compiled with.
|
||||
enum InstallerError: FatalError, Equatable {
|
||||
case versionNotFound(String)
|
||||
case incompatibleSwiftVersion(local: String, expected: String)
|
||||
|
@ -38,6 +49,7 @@ enum InstallerError: FatalError, Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
/// Class that manages the installation of Tuist versions.
|
||||
final class Installer: Installing {
|
||||
// MARK: - Attributes
|
||||
|
||||
|
@ -66,12 +78,20 @@ final class Installer: Installing {
|
|||
|
||||
// MARK: - Installing
|
||||
|
||||
func install(version: String) throws {
|
||||
func install(version: String, force: Bool) throws {
|
||||
let temporaryDirectory = try TemporaryDirectory(removeTreeOnDeinit: true)
|
||||
try install(version: version, temporaryDirectory: temporaryDirectory)
|
||||
try install(version: version, temporaryDirectory: temporaryDirectory, force: force)
|
||||
}
|
||||
|
||||
func install(version: String, temporaryDirectory: TemporaryDirectory, force: Bool = false) throws {
|
||||
// We ignore the Swift version and install from the soruce code
|
||||
if force {
|
||||
printer.print("Forcing the installation of \(version) from the source code")
|
||||
try installFromSource(version: version,
|
||||
temporaryDirectory: temporaryDirectory)
|
||||
return
|
||||
}
|
||||
|
||||
func install(version: String, temporaryDirectory: TemporaryDirectory) throws {
|
||||
try verifySwiftVersion(version: version)
|
||||
|
||||
var bundleURL: URL?
|
||||
|
@ -184,10 +204,11 @@ final class Installer: Installing {
|
|||
verbose: false,
|
||||
environment: System.userEnvironment).throwIfError()
|
||||
|
||||
// Copying files
|
||||
if !fileHandler.exists(installationDirectory) {
|
||||
try system.capture("/bin/mkdir", arguments: installationDirectory.asString, verbose: false, environment: nil).throwIfError()
|
||||
if fileHandler.exists(installationDirectory) {
|
||||
try fileHandler.delete(installationDirectory)
|
||||
}
|
||||
try fileHandler.createFolder(installationDirectory)
|
||||
|
||||
try buildCopier.copy(from: buildDirectory,
|
||||
to: installationDirectory)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
import TuistCore
|
||||
|
||||
protocol Updating: AnyObject {
|
||||
func update() throws
|
||||
func update(force: Bool) throws
|
||||
}
|
||||
|
||||
final class Updater: Updating {
|
||||
|
@ -27,24 +27,27 @@ final class Updater: Updating {
|
|||
|
||||
// MARK: - Internal
|
||||
|
||||
func update() throws {
|
||||
func update(force: Bool) throws {
|
||||
let releases = try githubClient.releases()
|
||||
|
||||
guard let highestRemoteVersion = releases.map({ $0.version }).sorted().last else {
|
||||
print("No remote versions found")
|
||||
printer.print("No remote versions found")
|
||||
return
|
||||
}
|
||||
|
||||
if let highestLocalVersion = versionsController.semverVersions().sorted().last {
|
||||
if force {
|
||||
printer.print("Forcing the update of version \(highestRemoteVersion)")
|
||||
try installer.install(version: highestRemoteVersion.description, force: true)
|
||||
} else if let highestLocalVersion = versionsController.semverVersions().sorted().last {
|
||||
if highestRemoteVersion <= highestLocalVersion {
|
||||
printer.print("There are no updates available")
|
||||
} else {
|
||||
printer.print("Installing new version available \(highestRemoteVersion)")
|
||||
try installer.install(version: highestRemoteVersion.description)
|
||||
try installer.install(version: highestRemoteVersion.description, force: false)
|
||||
}
|
||||
} else {
|
||||
printer.print("No local versions available. Installing the latest version \(highestRemoteVersion)")
|
||||
try installer.install(version: highestRemoteVersion.description)
|
||||
try installer.install(version: highestRemoteVersion.description, force: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,8 +68,8 @@ final class BundleCommandTests: XCTestCase {
|
|||
let tuistVersionPath = fileHandler.currentPath.appending(component: Constants.versionFileName)
|
||||
try "3.2.1".write(to: tuistVersionPath.url, atomically: true, encoding: .utf8)
|
||||
|
||||
installer.installStub = { versionToInstall in
|
||||
let versionPath = self.versionsController.path(version: versionToInstall)
|
||||
installer.installStub = { version, _ in
|
||||
let versionPath = self.versionsController.path(version: version)
|
||||
try self.fileHandler.createFolder(versionPath)
|
||||
try Data().write(to: versionPath.appending(component: "test").url)
|
||||
}
|
||||
|
@ -102,8 +102,8 @@ final class BundleCommandTests: XCTestCase {
|
|||
|
||||
try "3.2.1".write(to: tuistVersionPath.url, atomically: true, encoding: .utf8)
|
||||
|
||||
installer.installStub = { versionToInstall in
|
||||
let versionPath = self.versionsController.path(version: versionToInstall)
|
||||
installer.installStub = { version, _ in
|
||||
let versionPath = self.versionsController.path(version: version)
|
||||
try self.fileHandler.createFolder(versionPath)
|
||||
try Data().write(to: versionPath.appending(component: "test").url)
|
||||
}
|
||||
|
|
|
@ -84,8 +84,8 @@ final class CommandRunnerTests: XCTestCase {
|
|||
|
||||
versionResolver.resolveStub = { _ in ResolvedVersion.versionFile(self.fileHandler.currentPath, "3.2.1") }
|
||||
|
||||
var installedVersion: String?
|
||||
installer.installStub = { installedVersion = $0 }
|
||||
var installArgs: [(version: String, force: Bool)] = []
|
||||
installer.installStub = { version, force in installArgs.append((version: version, force: force)) }
|
||||
|
||||
system.stub(args: [binaryPath.asString, "--help"],
|
||||
stderror: nil,
|
||||
|
@ -97,7 +97,8 @@ final class CommandRunnerTests: XCTestCase {
|
|||
XCTAssertEqual(printer.printArgs.count, 2)
|
||||
XCTAssertEqual(printer.printArgs.first, "Using version 3.2.1 defined at \(fileHandler.currentPath.asString)")
|
||||
XCTAssertEqual(printer.printArgs.last, "Version 3.2.1 not found locally. Installing...")
|
||||
XCTAssertEqual(installedVersion, "3.2.1")
|
||||
XCTAssertEqual(installArgs.count, 1)
|
||||
XCTAssertEqual(installArgs.first?.version, "3.2.1")
|
||||
}
|
||||
|
||||
func test_when_version_file_and_install_fails() throws {
|
||||
|
@ -106,7 +107,7 @@ final class CommandRunnerTests: XCTestCase {
|
|||
versionResolver.resolveStub = { _ in ResolvedVersion.versionFile(self.fileHandler.currentPath, "3.2.1") }
|
||||
|
||||
let error = NSError.test()
|
||||
installer.installStub = { _ in throw error }
|
||||
installer.installStub = { _, _ in throw error }
|
||||
|
||||
XCTAssertThrowsError(try subject.run()) {
|
||||
XCTAssertEqual($0 as NSError, error)
|
||||
|
@ -159,7 +160,7 @@ final class CommandRunnerTests: XCTestCase {
|
|||
versionResolver.resolveStub = { _ in ResolvedVersion.undefined }
|
||||
|
||||
versionsController.semverVersionsStub = []
|
||||
updater.updateStub = {
|
||||
updater.updateStub = { _ in
|
||||
self.versionsController.semverVersionsStub = [Version(string: "3.2.1")!]
|
||||
}
|
||||
|
||||
|
@ -182,7 +183,7 @@ final class CommandRunnerTests: XCTestCase {
|
|||
|
||||
versionsController.semverVersionsStub = []
|
||||
let error = NSError.test()
|
||||
updater.updateStub = {
|
||||
updater.updateStub = { _ in
|
||||
throw error
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,28 @@ final class InstallCommandTests: XCTestCase {
|
|||
|
||||
versionsController.versionsStub = []
|
||||
|
||||
var installedVersion: String?
|
||||
installer.installStub = { installedVersion = $0 }
|
||||
var installArgs: [(version: String, force: Bool)] = []
|
||||
installer.installStub = { version, force in installArgs.append((version: version, force: force)) }
|
||||
|
||||
try subject.run(with: result)
|
||||
|
||||
XCTAssertEqual(installedVersion, "3.2.1")
|
||||
XCTAssertEqual(installArgs.count, 1)
|
||||
XCTAssertEqual(installArgs.first?.version, "3.2.1")
|
||||
XCTAssertEqual(installArgs.first?.force, false)
|
||||
}
|
||||
|
||||
func test_run_when_force() throws {
|
||||
let result = try parser.parse(["install", "3.2.1", "-f"])
|
||||
|
||||
versionsController.versionsStub = []
|
||||
|
||||
var installArgs: [(version: String, force: Bool)] = []
|
||||
installer.installStub = { version, force in installArgs.append((version: version, force: force)) }
|
||||
|
||||
try subject.run(with: result)
|
||||
|
||||
XCTAssertEqual(installArgs.count, 1)
|
||||
XCTAssertEqual(installArgs.first?.version, "3.2.1")
|
||||
XCTAssertEqual(installArgs.first?.force, true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
import Foundation
|
||||
@testable import TuistEnvKit
|
||||
import Utility
|
||||
import XCTest
|
||||
|
||||
@testable import TuistCoreTesting
|
||||
@testable import TuistEnvKit
|
||||
@testable import Utility
|
||||
|
||||
final class UpdateCommandTests: XCTestCase {
|
||||
var parser: ArgumentParser!
|
||||
var subject: UpdateCommand!
|
||||
var updater: MockUpdater!
|
||||
var printer: MockPrinter!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
parser = ArgumentParser(usage: "test", overview: "overview")
|
||||
updater = MockUpdater()
|
||||
printer = MockPrinter()
|
||||
subject = UpdateCommand(parser: parser,
|
||||
updater: updater,
|
||||
printer: printer)
|
||||
}
|
||||
|
||||
func test_command() {
|
||||
XCTAssertEqual(UpdateCommand.command, "update")
|
||||
}
|
||||
|
@ -11,4 +28,24 @@ final class UpdateCommandTests: XCTestCase {
|
|||
func test_overview() {
|
||||
XCTAssertEqual(UpdateCommand.overview, "Installs the latest version if it's not already installed")
|
||||
}
|
||||
|
||||
func test_init_registers_the_command() {
|
||||
XCTAssertEqual(parser.subparsers.count, 1)
|
||||
XCTAssertEqual(parser.subparsers.first?.key, UpdateCommand.command)
|
||||
XCTAssertEqual(parser.subparsers.first?.value.overview, UpdateCommand.overview)
|
||||
}
|
||||
|
||||
func test_run() throws {
|
||||
let result = try parser.parse(["update", "-f"])
|
||||
|
||||
var updateCalls: [Bool] = []
|
||||
updater.updateStub = { force in
|
||||
updateCalls.append(force)
|
||||
}
|
||||
|
||||
try subject.run(with: result)
|
||||
|
||||
XCTAssertEqual(printer.printSectionArgs, ["Checking for updates..."])
|
||||
XCTAssertEqual(updateCalls, [true])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,9 +180,10 @@ final class InstallerTests: XCTestCase {
|
|||
func test_install_when_no_bundled_release() throws {
|
||||
let version = "3.2.1"
|
||||
let temporaryDirectory = try TemporaryDirectory(removeTreeOnDeinit: true)
|
||||
let installationDirectory = fileHandler.currentPath.appending(component: "3.2.1")
|
||||
|
||||
versionsController.installStub = { _, closure in
|
||||
try closure(self.fileHandler.currentPath)
|
||||
try closure(installationDirectory)
|
||||
}
|
||||
|
||||
system.stub(args: [
|
||||
|
@ -223,13 +224,6 @@ final class InstallerTests: XCTestCase {
|
|||
stderror: nil,
|
||||
stdout: nil,
|
||||
exitstatus: 0)
|
||||
system.stub(args: [
|
||||
"/bin/mkdir",
|
||||
fileHandler.currentPath.asString,
|
||||
],
|
||||
stderror: nil,
|
||||
stdout: nil,
|
||||
exitstatus: 0)
|
||||
|
||||
try subject.install(version: version, temporaryDirectory: temporaryDirectory)
|
||||
|
||||
|
@ -241,7 +235,68 @@ final class InstallerTests: XCTestCase {
|
|||
XCTAssertEqual(printer.printArgs[1], "Building using Swift (it might take a while)")
|
||||
XCTAssertEqual(printer.printArgs[2], "Version 3.2.1 installed")
|
||||
|
||||
let tuistVersionPath = fileHandler.currentPath.appending(component: Constants.versionFileName)
|
||||
let tuistVersionPath = installationDirectory.appending(component: Constants.versionFileName)
|
||||
XCTAssertTrue(fileHandler.exists(tuistVersionPath))
|
||||
}
|
||||
|
||||
func test_install_when_force() throws {
|
||||
let version = "3.2.1"
|
||||
let temporaryDirectory = try TemporaryDirectory(removeTreeOnDeinit: true)
|
||||
let installationDirectory = fileHandler.currentPath.appending(component: "3.2.1")
|
||||
|
||||
versionsController.installStub = { _, closure in
|
||||
try closure(installationDirectory)
|
||||
}
|
||||
|
||||
system.stub(args: [
|
||||
"/usr/bin/env", "git",
|
||||
"clone", Constants.gitRepositoryURL,
|
||||
temporaryDirectory.path.asString,
|
||||
],
|
||||
stderror: nil,
|
||||
stdout: nil,
|
||||
exitstatus: 0)
|
||||
system.stub(args: [
|
||||
"/usr/bin/env", "git", "-C", temporaryDirectory.path.asString,
|
||||
"checkout", version,
|
||||
],
|
||||
stderror: nil,
|
||||
stdout: nil,
|
||||
exitstatus: 0)
|
||||
system.stub(args: ["/usr/bin/xcrun", "-f", "swift"],
|
||||
stderror: nil,
|
||||
stdout: "/path/to/swift",
|
||||
exitstatus: 0)
|
||||
system.stub(args: [
|
||||
"/path/to/swift", "build",
|
||||
"--product", "tuist",
|
||||
"--package-path", temporaryDirectory.path.asString,
|
||||
"--configuration", "release",
|
||||
"-Xswiftc", "-static-stdlib",
|
||||
],
|
||||
stderror: nil,
|
||||
stdout: nil,
|
||||
exitstatus: 0)
|
||||
system.stub(args: [
|
||||
"/path/to/swift", "build",
|
||||
"--product", "ProjectDescription",
|
||||
"--package-path", temporaryDirectory.path.asString,
|
||||
"--configuration", "release",
|
||||
],
|
||||
stderror: nil,
|
||||
stdout: nil,
|
||||
exitstatus: 0)
|
||||
|
||||
try subject.install(version: version, temporaryDirectory: temporaryDirectory, force: true)
|
||||
|
||||
XCTAssertEqual(printer.printArgs.count, 4)
|
||||
|
||||
XCTAssertEqual(printer.printArgs[0], "Forcing the installation of 3.2.1 from the source code")
|
||||
XCTAssertEqual(printer.printArgs[1], "Pulling source code")
|
||||
XCTAssertEqual(printer.printArgs[2], "Building using Swift (it might take a while)")
|
||||
XCTAssertEqual(printer.printArgs[3], "Version 3.2.1 installed")
|
||||
|
||||
let tuistVersionPath = installationDirectory.appending(component: Constants.versionFileName)
|
||||
XCTAssertTrue(fileHandler.exists(tuistVersionPath))
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ import Foundation
|
|||
|
||||
final class MockInstaller: Installing {
|
||||
var installCallCount: UInt = 0
|
||||
var installStub: ((String) throws -> Void)?
|
||||
var installStub: ((String, Bool) throws -> Void)?
|
||||
|
||||
func install(version: String) throws {
|
||||
func install(version: String, force: Bool) throws {
|
||||
installCallCount += 1
|
||||
try installStub?(version)
|
||||
try installStub?(version, force)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ import Foundation
|
|||
|
||||
final class MockUpdater: Updating {
|
||||
var updateCallCount: UInt = 0
|
||||
var updateStub: (() throws -> Void)?
|
||||
var updateStub: ((Bool) throws -> Void)?
|
||||
|
||||
func update() throws {
|
||||
func update(force: Bool) throws {
|
||||
updateCallCount += 1
|
||||
try updateStub?()
|
||||
try updateStub?(force)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,80 @@
|
|||
import Foundation
|
||||
@testable import TuistEnvKit
|
||||
import XCTest
|
||||
|
||||
@testable import TuistCoreTesting
|
||||
@testable import TuistEnvKit
|
||||
|
||||
final class UpdaterTests: XCTestCase {
|
||||
var githubClient: MockGitHubClient!
|
||||
var versionsController: MockVersionsController!
|
||||
var installer: MockInstaller!
|
||||
var printer: MockPrinter!
|
||||
var subject: Updater!
|
||||
|
||||
override func setUp() {
|
||||
githubClient = MockGitHubClient()
|
||||
versionsController = try! MockVersionsController()
|
||||
installer = MockInstaller()
|
||||
printer = MockPrinter()
|
||||
subject = Updater(githubClient: githubClient,
|
||||
versionsController: versionsController,
|
||||
installer: installer,
|
||||
printer: printer)
|
||||
}
|
||||
|
||||
func test_update_when_no_remote_releases() throws {
|
||||
githubClient.releasesStub = { [] }
|
||||
try subject.update(force: false)
|
||||
XCTAssertEqual(printer.printArgs, ["No remote versions found"])
|
||||
}
|
||||
|
||||
func test_update_when_force() throws {
|
||||
githubClient.releasesStub = { [Release.test(version: "3.2.1")] }
|
||||
var installArgs: [(version: String, force: Bool)] = []
|
||||
installer.installStub = { version, force in installArgs.append((version: version, force: force)) }
|
||||
|
||||
try subject.update(force: true)
|
||||
|
||||
XCTAssertEqual(printer.printArgs, ["Forcing the update of version 3.2.1"])
|
||||
XCTAssertEqual(installArgs.count, 1)
|
||||
XCTAssertEqual(installArgs.first?.version, "3.2.1")
|
||||
XCTAssertEqual(installArgs.first?.force, true)
|
||||
}
|
||||
|
||||
func test_update_when_there_are_no_updates() throws {
|
||||
versionsController.semverVersionsStub = ["3.2.1"]
|
||||
githubClient.releasesStub = { [Release.test(version: "3.2.1")] }
|
||||
|
||||
try subject.update(force: false)
|
||||
|
||||
XCTAssertEqual(printer.printArgs, ["There are no updates available"])
|
||||
}
|
||||
|
||||
func test_update_when_there_are_updates() throws {
|
||||
versionsController.semverVersionsStub = ["3.1.1"]
|
||||
githubClient.releasesStub = { [Release.test(version: "3.2.1")] }
|
||||
var installArgs: [(version: String, force: Bool)] = []
|
||||
installer.installStub = { version, force in installArgs.append((version: version, force: force)) }
|
||||
|
||||
try subject.update(force: false)
|
||||
|
||||
XCTAssertEqual(printer.printArgs, ["Installing new version available 3.2.1"])
|
||||
XCTAssertEqual(installArgs.count, 1)
|
||||
XCTAssertEqual(installArgs.first?.version, "3.2.1")
|
||||
XCTAssertEqual(installArgs.first?.force, false)
|
||||
}
|
||||
|
||||
func test_update_when_no_local_versions_available() throws {
|
||||
versionsController.semverVersionsStub = []
|
||||
githubClient.releasesStub = { [Release.test(version: "3.2.1")] }
|
||||
var installArgs: [(version: String, force: Bool)] = []
|
||||
installer.installStub = { version, force in installArgs.append((version: version, force: force)) }
|
||||
|
||||
try subject.update(force: false)
|
||||
|
||||
XCTAssertEqual(printer.printArgs, ["No local versions available. Installing the latest version 3.2.1"])
|
||||
XCTAssertEqual(installArgs.count, 1)
|
||||
XCTAssertEqual(installArgs.first?.version, "3.2.1")
|
||||
XCTAssertEqual(installArgs.first?.force, false)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue