Implement updater command and generate tuistenv

This commit is contained in:
Pedro Piñera 2018-07-25 08:38:16 -04:00
parent 6ad266f2d6
commit db4b615d31
7 changed files with 61 additions and 69 deletions

View File

@ -24,7 +24,7 @@
"repositoryURL": "git@github.com:tuist/SwiftShell.git",
"state": {
"branch": null,
"revision": "12d47f0ed2f9a8dc11b4bb6a0d9ba3d0cb053a56",
"revision": "b9afd2eb8cc5b0cd5713d6ed4e649948ec70ff8e",
"version": null
}
},

View File

@ -15,7 +15,7 @@ let package = Package(
dependencies: [
.package(url: "git@github.com:tuist/xcodeproj.git", .revision("549d67686d90ef8e45fccdca147682f185af2ad0")),
.package(url: "git@github.com:apple/swift-package-manager.git", .revision("3e71e57db41ebb32ccec1841a7e26c428a9c08c5")),
.package(url: "git@github.com:tuist/SwiftShell.git", .revision("12d47f0ed2f9a8dc11b4bb6a0d9ba3d0cb053a56")),
.package(url: "git@github.com:tuist/SwiftShell.git", .revision("b9afd2eb8cc5b0cd5713d6ed4e649948ec70ff8e")),
],
targets: [
.target(

View File

@ -25,7 +25,7 @@ public final class CommandRegistry {
/// Default constructor.
public convenience init() {
self.init(processArguments: CommandRegistry.processArguments,
commands: [LocalCommand.self, BundleCommand.self])
commands: [LocalCommand.self, BundleCommand.self, UpdateCommand.self])
}
/// Initializes the command registrry with its attributes.

View File

@ -4,35 +4,27 @@ import TuistCore
import Utility
class LocalCommand: Command {
/// Command name.
// MARK: - Command
static var command: String = "local"
/// Command overview
static var overview: String = "Creates a .tuist-version file to pin the tuist version that should be used in the current directory."
/// Version argument.
static var overview: String = "Creates a .tuist-version file to pin the tuist version that should be used in the current directory. If the version is not specified, it prints the current version."
// MARK: - Attributes
let versionArgument: PositionalArgument<String>
/// File handler.
let fileHandler: FileHandling
/// Printer.
let printer: Printing
/// Default constructor.
///
/// - Parameter parser: argument parser.
// MARK: - Init
required convenience init(parser: ArgumentParser) {
self.init(parser: parser,
fileHandler: FileHandler(),
printer: Printer())
}
/// Initializes the command with its attributes.
///
/// - Parameters:
/// - parser: The argument parser used to register arguments.
/// - fileHandler: file handler.
init(parser: ArgumentParser,
fileHandler: FileHandling,
printer: Printing) {
@ -46,10 +38,9 @@ class LocalCommand: Command {
self.printer = printer
}
/// Runs the command.
///
/// - Parameter result: argument parser result.
/// - Throws: an error if the version file cannot be written.
// MARK: - Internal
func run(with result: ArgumentParser.Result) throws {
let version = result.get(versionArgument)!
let currentPath = fileHandler.currentPath

View File

@ -1,38 +1,42 @@
import Foundation
import TuistCore
import Utility
import TuistCore
final class UpdateCommand: Command {
/// Command name.
static var command: String = "update"
/// Command overview.
// MARK: - Command
static var command: String = "update"
static var overview: String = "Installs the latest version if it's not already installed."
// MARK: - Attributes
/// Versions controller.
private let versionsController: VersionsControlling
private let updater: Updating
private let printer: Printing
/// Initializes the update command with the argument parser.
///
/// - Parameter parser: argument parser.
// MARK: - Init
convenience init(parser: ArgumentParser) {
self.init(parser: parser,
versionsController: VersionsController())
versionsController: VersionsController(),
updater: Updater(),
printer: Printer())
}
/// Default update command constructor.
///
/// - Parameters:
/// - parser: argument parser.
/// - versionsController: local versions controller.
init(parser: ArgumentParser,
versionsController: VersionsControlling) {
versionsController: VersionsControlling,
updater: Updating,
printer: Printer) {
parser.add(subparser: UpdateCommand.command, overview: UpdateCommand.overview)
self.versionsController = versionsController
self.printer = printer
self.updater = updater
}
func run(with _: ArgumentParser.Result) throws {
func run(with: ArgumentParser.Result) throws {
printer.print(section: "Checking for updates...")
try updater.update()
}
}

View File

@ -1,46 +1,34 @@
import Foundation
import TuistCore
/// Objects that conform this interface expose an interface for checking
/// updates of tuist and installing them.
protocol Updating: AnyObject {
/// Checks if there's a new version available. If there is it installs it locally.
///
/// - Throws: an error if the releases cannot be fetched from GitHub or the installation
/// process fails for any reason.
func update() throws
}
final class Updater: Updating {
/// GitHub client.
// MARK: - Attributes
let githubClient: GitHubClienting
/// GitHub request factory.
let githubRequestFactory: GitHubRequestsFactory = GitHubRequestsFactory()
/// Versions controller.
let versionsController: VersionsControlling
/// Installer.
let installer: Installing
let printer: Printing
/// Initializes the updater with its attributes.
///
/// - Parameters:
/// - githubClient: GitHub API client.
/// - versionsController: versions controller.
/// - installer: installer.
// MARK: - Init
init(githubClient: GitHubClienting = GitHubClient(),
versionsController: VersionsControlling = VersionsController(),
installer: Installing = Installer()) {
installer: Installing = Installer(),
printer: Printing = Printer()) {
self.githubClient = githubClient
self.versionsController = versionsController
self.installer = installer
self.printer = printer
}
/// Checks if there's a new version available. If there is it installs it locally.
///
/// - Throws: an error if the releases cannot be fetched from GitHub or the installation
/// process fails for any reason.
// MARK: - Internal
func update() throws {
let json = try githubClient.execute(request: githubRequestFactory.releases())
let jsonDecoder = JSONDecoder()
@ -48,12 +36,21 @@ final class Updater: Updating {
let releases: [Release] = try jsonDecoder.decode([Release].self, from: jsonData)
guard let highestRemoteVersion = releases.map({ $0.version }).sorted().last,
let highestLocalVersion = versionsController.semverVersions().sorted().last else {
guard let highestRemoteVersion = releases.map({ $0.version }).sorted().last else {
print("No remote versions found")
return
}
if highestRemoteVersion <= highestLocalVersion { return }
try installer.install(version: highestRemoteVersion.description)
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)
}
} else {
printer.print("No local versions available. Installing the latest version \(highestRemoteVersion)")
try installer.install(version: highestRemoteVersion.description)
}
}
}

Binary file not shown.