Generate .gitignore when bootstrapping a project (#118)

* Generate .gitignore file and format the code with the latest version of swiftformat

* Update CHANGELOG
This commit is contained in:
Pedro Piñera Buendía 2018-09-04 18:39:51 +02:00 committed by GitHub
parent abc25b2308
commit a385f27235
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 79 additions and 114 deletions

View File

@ -5,7 +5,10 @@ Please, check out guidelines: https://keepachangelog.com/en/1.0.0/
## Next version
### Added
- Support for JSON and Yaml manifests https://github.com/tuist/tuist/pull/110 by @pepibumur.
- Generate `.gitignore` file when running init command https://github.com/tuist/tuist/pull/118 by @pepibumur.
### Fixed
- Snake-cased build settings keys https://github.com/tuist/tuist/pull/107 by @pepibumur.

View File

@ -20,37 +20,48 @@ let package = Package(
targets: [
.target(
name: "TuistCore",
dependencies: ["Utility", "ReactiveTask"]),
dependencies: ["Utility", "ReactiveTask"]
),
.target(
name: "TuistCoreTesting",
dependencies: ["TuistCore"]),
dependencies: ["TuistCore"]
),
.testTarget(
name: "TuistCoreTests",
dependencies: ["TuistCore", "TuistCoreTesting"]),
dependencies: ["TuistCore", "TuistCoreTesting"]
),
.target(
name: "TuistKit",
dependencies: ["xcodeproj", "Utility", "TuistCore", "Yams"]),
dependencies: ["xcodeproj", "Utility", "TuistCore", "Yams"]
),
.testTarget(
name: "TuistKitTests",
dependencies: ["TuistKit", "TuistCoreTesting"]),
dependencies: ["TuistKit", "TuistCoreTesting"]
),
.target(
name: "tuist",
dependencies: ["TuistKit"]),
dependencies: ["TuistKit"]
),
.target(
name: "TuistEnvKit",
dependencies: ["Utility", "TuistCore"]),
dependencies: ["Utility", "TuistCore"]
),
.testTarget(
name: "TuistEnvKitTests",
dependencies: ["TuistEnvKit", "TuistCoreTesting"]),
dependencies: ["TuistEnvKit", "TuistCoreTesting"]
),
.target(
name: "tuistenv",
dependencies: ["TuistEnvKit"]),
dependencies: ["TuistEnvKit"]
),
.target(
name: "ProjectDescription",
dependencies: []),
dependencies: []
),
.testTarget(
name: "ProjectDescriptionTests",
dependencies: ["ProjectDescription"]),
dependencies: ["ProjectDescription"]
),
.testTarget(
name: "IntegrationTests",
dependencies: ["TuistKit", "Utility"]

View File

@ -3,7 +3,6 @@ import Foundation
// MARK: - Workspace
public class Workspace: Codable {
// MARK: - Codable
enum CodingKeys: String, CodingKey {

View File

@ -5,7 +5,6 @@ public protocol ErrorHandling: AnyObject {
}
public final class ErrorHandler: ErrorHandling {
// MARK: - Attributes
let printer: Printing

View File

@ -12,7 +12,6 @@ public protocol Printing: AnyObject {
}
public class Printer: Printing {
// MARK: - Init
public init() {}
@ -67,7 +66,6 @@ public class Printer: Printing {
}
final class InteractiveWriter {
// MARK: - Attributes
static let stderr = InteractiveWriter(stream: stderrStream)

View File

@ -51,7 +51,6 @@ public struct SystemResult {
}
public final class System: Systeming {
// MARK: - Attributes
let printer: Printing

View File

@ -29,7 +29,6 @@ enum BundleCommandError: FatalError, Equatable {
}
final class BundleCommand: Command {
// MARK: - Command
static var command: String = "bundle"

View File

@ -4,7 +4,6 @@ import TuistCore
import Utility
public final class CommandRegistry {
// MARK: - Attributes
let parser: ArgumentParser

View File

@ -25,7 +25,6 @@ enum CommandRunnerError: FatalError {
}
class CommandRunner: CommandRunning {
// MARK: - Attributes
let versionResolver: VersionResolving

View File

@ -3,7 +3,6 @@ import TuistCore
import Utility
final class InstallCommand: Command {
// MARK: - Command
static var command: String = "install"

View File

@ -4,7 +4,6 @@ import TuistCore
import Utility
class LocalCommand: Command {
// MARK: - Command
static var command: String = "local"

View File

@ -3,7 +3,6 @@ import TuistCore
import Utility
final class UninstallCommand: Command {
// MARK: - Command
static var command: String = "uninstall"

View File

@ -3,7 +3,6 @@ import TuistCore
import Utility
final class UpdateCommand: Command {
// MARK: - Command
static var command: String = "update"

View File

@ -33,7 +33,6 @@ enum GitHubClientError: FatalError {
}
class GitHubClient: GitHubClienting {
// MARK: - Attributes
let sessionScheduler: URLSessionScheduling

View File

@ -9,7 +9,6 @@ protocol URLSessionScheduling: AnyObject {
}
final class URLSessionScheduler: URLSessionScheduling {
// MARK: - Constants
/// The default request timeout.

View File

@ -7,7 +7,6 @@ protocol BuildCopying: AnyObject {
}
class BuildCopier: BuildCopying {
// MARK: - Static
/// Files that should be copied (if they exist).

View File

@ -31,7 +31,6 @@ enum InstallerError: FatalError, Equatable {
}
final class Installer: Installing {
// MARK: - Attributes
let system: Systeming

View File

@ -2,7 +2,6 @@ import Foundation
/// Settings
class Settings: Codable, Equatable {
// MARK: - Init
/// Initializes the settings instance.

View File

@ -18,7 +18,6 @@ protocol SettingsControlling: AnyObject {
/// Controller to manage user settings.
class SettingsController: SettingsControlling {
// MARK: - Attributes
/// Environment controller.

View File

@ -6,7 +6,6 @@ protocol Updating: AnyObject {
}
final class Updater: Updating {
// MARK: - Attributes
let githubClient: GitHubClienting

View File

@ -51,7 +51,6 @@ enum VersionResolverError: FatalError, Equatable {
}
class VersionResolver: VersionResolving {
// MARK: - Attributes
private let settingsController: SettingsControlling

View File

@ -37,7 +37,6 @@ enum InstalledVersion: CustomStringConvertible, Equatable {
}
class VersionsController: VersionsControlling {
// MARK: - Attributes
let environmentController: EnvironmentControlling

View File

@ -4,7 +4,6 @@ import TuistCore
import Utility
public final class CommandRegistry {
// MARK: - Attributes
let parser: ArgumentParser

View File

@ -4,7 +4,6 @@ import TuistCore
import Utility
class DumpCommand: NSObject, Command {
// MARK: - Command
static let command = "dump"

View File

@ -22,7 +22,6 @@ enum EmbedCommandError: FatalError {
}
final class EmbedCommand: HiddenCommand {
// MARK: - HiddenCommand
static var command: String = "embed"

View File

@ -4,7 +4,6 @@ import TuistCore
import Utility
class GenerateCommand: NSObject, Command {
// MARK: - Static
static let command = "generate"

View File

@ -22,7 +22,6 @@ enum InitCommandError: FatalError {
}
class InitCommand: NSObject, Command {
// MARK: - Attributes
static let command = "init"
@ -95,6 +94,7 @@ class InitCommand: NSObject, Command {
try generateTests(name: name, path: path)
try generatePlists(platform: platform, product: product, path: path)
try generatePlaygrounds(name: name, path: path, platform: platform)
try generateGitIgnore(path: path)
printer.print(success: "Project generated at path \(path.asString).")
}
@ -139,6 +139,15 @@ class InitCommand: NSObject, Command {
product: .unitTests)
}
fileprivate func generateGitIgnore(path: AbsolutePath) throws {
let path = path.appending(component: ".gitignore")
let content = """
*.xcodeproj
*.xcworkspace
"""
try content.write(to: path.url, atomically: true, encoding: .utf8)
}
fileprivate func generateSources(name: String, platform: Platform, product: Product, path: AbsolutePath) throws {
let path = path.appending(component: "Sources")

View File

@ -4,7 +4,6 @@ import TuistCore
import Utility
class VersionCommand: NSObject, Command {
// MARK: - Command
static let command = "version"

View File

@ -1,7 +1,6 @@
import Foundation
struct Device: Hashable, Equatable {
// MARK: - Attributes
let state: String

View File

@ -1,7 +1,6 @@
import Foundation
struct DeviceType: Hashable {
// MARK: - Attributes
let name: String

View File

@ -1,7 +1,6 @@
import Foundation
struct Runtime: Equatable, Hashable {
// MARK: - Attributes
let buildVersion: String

View File

@ -10,7 +10,6 @@ protocol FrameworkEmbedding: AnyObject {
}
final class FrameworkEmbedder: FrameworkEmbedding {
// MARK: - Attributes
private let fileHandler: FileHandling

View File

@ -22,7 +22,6 @@ protocol ConfigGenerating: AnyObject {
}
final class ConfigGenerator: ConfigGenerating {
// MARK: - Attributes
let fileGenerator: FileGenerating

View File

@ -54,7 +54,6 @@ protocol LinkGenerating: AnyObject {
}
final class LinkGenerator: LinkGenerating {
// MARK: - LinkGenerating
func generateLinks(target: Target,

View File

@ -3,7 +3,6 @@ import Foundation
import xcodeproj
class ProjectFileElements {
// MARK: - Static
// swiftlint:disable:next force_try

View File

@ -14,7 +14,6 @@ protocol ProjectGenerating: AnyObject {
}
final class ProjectGenerator: ProjectGenerating {
// MARK: - Attributes
let targetGenerator: TargetGenerating

View File

@ -3,7 +3,6 @@ import Foundation
import xcodeproj
class ProjectGroups {
// MARK: - Attributes
let main: PBXGroup

View File

@ -31,7 +31,6 @@ protocol TargetGenerating: AnyObject {
}
final class TargetGenerator: TargetGenerating {
// MARK: - Attributes
let configGenerator: ConfigGenerating

View File

@ -13,7 +13,6 @@ protocol WorkspaceGenerating: AnyObject {
}
final class WorkspaceGenerator: WorkspaceGenerating {
// MARK: - Attributes
let projectGenerator: ProjectGenerating

View File

@ -6,7 +6,6 @@ protocol GraphLinting: AnyObject {
}
class GraphLinter: GraphLinting {
// MARK: - Attributes
let projectLinter: ProjectLinting

View File

@ -7,7 +7,6 @@ protocol ProjectLinting: AnyObject {
}
class ProjectLinter: ProjectLinting {
// MARK: - Attributes
let targetLinter: TargetLinting

View File

@ -7,7 +7,6 @@ protocol SettingsLinting: AnyObject {
}
final class SettingsLinter: SettingsLinting {
// MARK: - Attributes
let fileHandler: FileHandling

View File

@ -6,7 +6,6 @@ protocol TargetLinting: AnyObject {
}
class TargetLinter: TargetLinting {
// MARK: - Attributes
private let fileHandler: FileHandling

View File

@ -52,7 +52,6 @@ protocol Graphing: AnyObject {
}
class Graph: Graphing {
// MARK: - Attributes
private let cache: GraphLoaderCaching

View File

@ -13,7 +13,6 @@ protocol GraphCircularDetecting: AnyObject {
}
final class GraphCircularDetector: GraphCircularDetecting {
// MARK: - Attributes
var edges: [GraphCircularDetectorNode: [GraphCircularDetectorNode]] = [:]

View File

@ -7,7 +7,6 @@ protocol GraphLoading: AnyObject {
}
class GraphLoader: GraphLoading {
// MARK: - Attributes
let linter: GraphLinting

View File

@ -15,7 +15,6 @@ protocol GraphLoaderCaching: AnyObject {
/// Graph loader cache.
class GraphLoaderCache: GraphLoaderCaching {
// MARK: - GraphLoaderCaching
var projects: [AbsolutePath: Project] = [:]

View File

@ -76,7 +76,6 @@ protocol GraphManifestLoading {
}
class GraphManifestLoader: GraphManifestLoading {
// MARK: - Attributes
let moduleLoader: GraphModuleLoading

View File

@ -3,7 +3,6 @@ import Foundation
import TuistCore
class GraphNode: Equatable, Hashable {
// MARK: - Attributes
let path: AbsolutePath
@ -26,7 +25,6 @@ class GraphNode: Equatable, Hashable {
}
class TargetNode: GraphNode {
// MARK: - Attributes
let project: Project
@ -190,7 +188,6 @@ class FrameworkNode: PrecompiledNode {
}
class LibraryNode: PrecompiledNode {
// MARK: - Attributes
let publicHeaders: AbsolutePath

View File

@ -3,7 +3,6 @@ import Foundation
import TuistCore
class CoreDataModel: Equatable, GraphJSONInitiatable {
// MARK: - Attributes
let path: AbsolutePath

View File

@ -5,7 +5,6 @@ import xcodeproj
/// Headers
class Headers: GraphJSONInitiatable, Equatable {
// MARK: - Attributes
let `public`: [AbsolutePath]

View File

@ -3,7 +3,6 @@ import Foundation
import TuistCore
class Project: Equatable {
// MARK: - Attributes
let path: AbsolutePath

View File

@ -2,7 +2,6 @@ import Basic
import Foundation
class Scheme: JSONMappable, Equatable {
// MARK: - Attributes
let name: String
@ -45,7 +44,6 @@ class Scheme: JSONMappable, Equatable {
}
class Arguments: JSONMappable, Equatable {
// MARK: - Attributes
let environment: [String: String]
@ -73,7 +71,6 @@ class Arguments: JSONMappable, Equatable {
}
class BuildAction: JSONMappable, Equatable {
// MARK: - Attributes
let targets: [String]
@ -96,7 +93,6 @@ class BuildAction: JSONMappable, Equatable {
}
class TestAction: JSONMappable, Equatable {
// MARK: - Attributes
let targets: [String]
@ -135,7 +131,6 @@ class TestAction: JSONMappable, Equatable {
}
class RunAction: JSONMappable, Equatable {
// MARK: - Attributes
let config: BuildConfiguration

View File

@ -3,7 +3,6 @@ import Foundation
import TuistCore
class Configuration: Equatable {
// MARK: - Attributes
let settings: [String: String]
@ -30,7 +29,6 @@ class Configuration: Equatable {
}
class Settings: GraphJSONInitiatable, Equatable {
// MARK: - Attributes
let base: [String: String]

View File

@ -3,7 +3,6 @@ import Foundation
import TuistCore
class Target: GraphJSONInitiatable, Equatable {
// MARK: - Static
static let validSourceExtensions: [String] = ["m", "swift", "mm"]

View File

@ -3,7 +3,6 @@ import Foundation
import TuistCore
class Workspace: Equatable {
// MARK: - Attributes
let name: String

View File

@ -34,7 +34,6 @@ protocol PlaygroundGenerating: AnyObject {
}
final class PlaygroundGenerator: PlaygroundGenerating {
// MARK: - Attributes
private let fileHandler: FileHandling

View File

@ -42,7 +42,6 @@ protocol CommandChecking: AnyObject {
}
final class CommandCheck: CommandChecking {
// MARK: - Attributes
let system: Systeming

View File

@ -8,7 +8,6 @@ protocol InfoPlistProvisioning: AnyObject {
/// Creates a base Info.plist. This is intended to be used from the init command.
class InfoPlistProvisioner: InfoPlistProvisioning {
// MARK: - Attributes
/// File handler.

View File

@ -57,16 +57,16 @@ final class InstallerTests: XCTestCase {
"--output", downloadPath.asString,
downloadURL.absoluteString,
],
stderror: nil,
stdout: nil,
exitstatus: 0)
stderror: nil,
stdout: nil,
exitstatus: 0)
system.stub(args: [
"unzip", downloadPath.asString,
"-d", self.fileHandler.currentPath.asString,
],
stderror: nil,
stdout: nil,
exitstatus: 0)
stderror: nil,
stdout: nil,
exitstatus: 0)
try subject.install(version: version,
temporaryDirectory: temporaryDirectory)
@ -104,9 +104,9 @@ final class InstallerTests: XCTestCase {
"--output", downloadPath.asString,
downloadURL.absoluteString,
],
stderror: "download_error",
stdout: nil,
exitstatus: 1)
stderror: "download_error",
stdout: nil,
exitstatus: 1)
let expected = SystemError(stderror: "download_error", exitcode: 1)
XCTAssertThrowsError(try subject.install(version: version,
@ -139,16 +139,16 @@ final class InstallerTests: XCTestCase {
"--output", downloadPath.asString,
downloadURL.absoluteString,
],
stderror: nil,
stdout: nil,
exitstatus: 0)
stderror: nil,
stdout: nil,
exitstatus: 0)
system.stub(args: [
"unzip", downloadPath.asString,
"-d", self.fileHandler.currentPath.asString,
],
stderror: "unzip_error",
stdout: nil,
exitstatus: 1)
stderror: "unzip_error",
stdout: nil,
exitstatus: 1)
let expected = SystemError(stderror: "unzip_error", exitcode: 1)
XCTAssertThrowsError(try subject.install(version: version,
@ -170,16 +170,16 @@ final class InstallerTests: XCTestCase {
"clone", Constants.gitRepositoryURL,
temporaryDirectory.path.asString,
],
stderror: nil,
stdout: nil,
exitstatus: 0)
stderror: nil,
stdout: nil,
exitstatus: 0)
system.stub(args: [
"git", "-C", temporaryDirectory.path.asString,
"checkout", version,
],
stderror: nil,
stdout: nil,
exitstatus: 0)
stderror: nil,
stdout: nil,
exitstatus: 0)
system.stub(args: ["/usr/bin/xcrun", "-f", "swift"],
stderror: nil,
stdout: "/path/to/swift",
@ -191,25 +191,25 @@ final class InstallerTests: XCTestCase {
"--configuration", "release",
"-Xswiftc", "-static-stdlib",
],
stderror: nil,
stdout: nil,
exitstatus: 0)
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)
stderror: nil,
stdout: nil,
exitstatus: 0)
system.stub(args: [
"/bin/mkdir",
fileHandler.currentPath.asString,
],
stderror: nil,
stdout: nil,
exitstatus: 0)
stderror: nil,
stdout: nil,
exitstatus: 0)
try subject.install(version: version, temporaryDirectory: temporaryDirectory)
@ -238,16 +238,16 @@ final class InstallerTests: XCTestCase {
"clone", Constants.gitRepositoryURL,
temporaryDirectory.path.asString,
],
stderror: nil,
stdout: nil,
exitstatus: 0)
stderror: nil,
stdout: nil,
exitstatus: 0)
system.stub(args: [
"git", "-C", temporaryDirectory.path.asString,
"checkout", version,
],
stderror: "did not match any file(s) known to git ",
stdout: nil,
exitstatus: 1)
stderror: "did not match any file(s) known to git ",
stdout: nil,
exitstatus: 1)
let expected = InstallerError.versionNotFound(version)
XCTAssertThrowsError(try subject.install(version: version, temporaryDirectory: temporaryDirectory)) {

View File

@ -2,5 +2,4 @@ import Foundation
@testable import TuistEnvKit
import XCTest
final class SettingsTests: XCTestCase {
}
final class SettingsTests: XCTestCase {}

View File

@ -92,6 +92,7 @@ final class InitCommandTests: XCTestCase {
let result = try parser.parse(["init", "--product", "application", "--platform", "ios"])
try subject.run(with: result)
let name = fileHandler.currentPath.components.last!
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: ".gitignore")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Project.swift")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Info.plist")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Tests.plist")))
@ -112,6 +113,7 @@ final class InitCommandTests: XCTestCase {
let result = try parser.parse(["init", "--product", "application", "--platform", "tvos"])
try subject.run(with: result)
let name = fileHandler.currentPath.components.last!
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: ".gitignore")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Project.swift")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Info.plist")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Tests.plist")))
@ -132,6 +134,7 @@ final class InitCommandTests: XCTestCase {
let result = try parser.parse(["init", "--product", "application", "--platform", "macos"])
try subject.run(with: result)
let name = fileHandler.currentPath.components.last!
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: ".gitignore")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Project.swift")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Info.plist")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Tests.plist")))
@ -152,6 +155,7 @@ final class InitCommandTests: XCTestCase {
let result = try parser.parse(["init", "--product", "framework", "--platform", "ios"])
try subject.run(with: result)
let name = fileHandler.currentPath.components.last!
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: ".gitignore")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Project.swift")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Info.plist")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Tests.plist")))
@ -172,6 +176,8 @@ final class InitCommandTests: XCTestCase {
let result = try parser.parse(["init", "--product", "framework", "--platform", "tvos"])
try subject.run(with: result)
let name = fileHandler.currentPath.components.last!
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: ".gitignore")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Project.swift")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Info.plist")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Tests.plist")))
@ -192,6 +198,7 @@ final class InitCommandTests: XCTestCase {
let result = try parser.parse(["init", "--product", "framework", "--platform", "macos"])
try subject.run(with: result)
let name = fileHandler.currentPath.components.last!
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: ".gitignore")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Project.swift")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Info.plist")))
XCTAssertTrue(fileHandler.exists(fileHandler.currentPath.appending(component: "Tests.plist")))