From de0f123d0829144455848eb0100ce43d6ca3847d Mon Sep 17 00:00:00 2001 From: Kyle Newsome Date: Wed, 7 Nov 2018 22:07:35 -0500 Subject: [PATCH 1/5] wip --- Sources/MarathonCore/PackageManager.swift | 25 ++++++++++++----------- Sources/MarathonCore/ScriptManager.swift | 14 +++++++++---- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Sources/MarathonCore/PackageManager.swift b/Sources/MarathonCore/PackageManager.swift index bfb51b8..bcdb0fa 100644 --- a/Sources/MarathonCore/PackageManager.swift +++ b/Sources/MarathonCore/PackageManager.swift @@ -105,17 +105,17 @@ public final class PackageManager { // MARK: - API - @discardableResult public func addPackage(at url: URL, throwIfAlreadyAdded: Bool = true) throws -> Package { - let name = try nameOfPackage(at: url) + @discardableResult public func addPackage(at url: URL, named name: String? = nil, throwIfAlreadyAdded: Bool = true) throws -> Package { + let dependencyName = try name ?? nameOfPackage(at: url) if throwIfAlreadyAdded { - guard (try? folder.file(named: name)) == nil else { - throw Error.packageAlreadyAdded(name) + guard (try? folder.file(named: dependencyName)) == nil else { + throw Error.packageAlreadyAdded(dependencyName) } } let latestVersion = try latestMajorVersionForPackage(at: url) - let package = Package(name: name, url: absoluteRepositoryURL(from: url), majorVersion: latestVersion) + let package = Package(name: dependencyName, url: absoluteRepositoryURL(from: url), majorVersion: latestVersion) try save(package: package) try updatePackages() @@ -124,17 +124,18 @@ public final class PackageManager { return package } - public func addPackagesIfNeeded(from packageURLs: [URL]) throws { - let existingPackageURLs = Set(makePackageList().map { package in - return package.url.absoluteString.lowercased() - }) + public func addPackagesIfNeeded(from packageInfos: [(URL, String?)]) throws { + let existingPackages = makePackageList() - for url in packageURLs { - guard !existingPackageURLs.contains(url.absoluteString.lowercased()) else { + for info in packageInfos { + let exists = try existingPackages.contains { (package) throws -> Bool in + return package.url.absoluteString.lowercased() == info.0.absoluteString.lowercased() + } + guard !exists else { continue } - try addPackage(at: url, throwIfAlreadyAdded: false) + try addPackage(at: info.0, named: info.1, throwIfAlreadyAdded: false) } } diff --git a/Sources/MarathonCore/ScriptManager.swift b/Sources/MarathonCore/ScriptManager.swift index 58e1d1a..1c067de 100644 --- a/Sources/MarathonCore/ScriptManager.swift +++ b/Sources/MarathonCore/ScriptManager.swift @@ -172,7 +172,8 @@ public final class ScriptManager { let script = Script(name: file.nameExcludingExtension, folder: folder, printer: printer) if let marathonFile = try script.resolveMarathonFile(fileName: config.dependencyFile) { - try packageManager.addPackagesIfNeeded(from: marathonFile.packageURLs) + let packageInfos: [(URL, String?)] = marathonFile.packageURLs.map { ($0, nil) } + try packageManager.addPackagesIfNeeded(from: packageInfos) try addDependencyScripts(fromMarathonFile: marathonFile, for: script) } @@ -312,7 +313,8 @@ public final class ScriptManager { private func resolveInlineDependencies(from file: File) throws { let lines = try file.readAsString().components(separatedBy: .newlines) - var packageURLs = [URL]() + + var packages = [(URL, String?)]() for line in lines { if line.hasPrefix("import ") { @@ -322,13 +324,17 @@ public final class ScriptManager { continue } + let importName = components.first! + .replacingOccurrences(of: "import ", with: "") + .replacingOccurrences(of: "//", with: "") + .trimmingCharacters(in: .whitespaces) let urlString = components.last!.trimmingCharacters(in: .whitespaces) guard let url = URL(string: urlString) else { throw Error.invalidInlineDependencyURL(urlString) } - packageURLs.append(url) + packages.append((url, importName)) } else if let firstCharacter = line.unicodeScalars.first { guard !CharacterSet.alphanumerics.contains(firstCharacter) else { break @@ -336,7 +342,7 @@ public final class ScriptManager { } } - try packageManager.addPackagesIfNeeded(from: packageURLs) + try packageManager.addPackagesIfNeeded(from: packages) } private func makeManagedScriptPathList() -> [String] { From ef4f4df92246bf97893eb885042e47821f014b15 Mon Sep 17 00:00:00 2001 From: Kyle Newsome Date: Sat, 10 Nov 2018 10:47:38 -0500 Subject: [PATCH 2/5] Add support for multiple dependencies from one package --- Sources/MarathonCore/Dependency.swift | 14 ++++ Sources/MarathonCore/Package.swift | 25 ++++++- Sources/MarathonCore/PackageManager.swift | 91 ++++++++++++++++++----- Sources/MarathonCore/Script.swift | 4 +- Sources/MarathonCore/ScriptManager.swift | 22 +++--- 5 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 Sources/MarathonCore/Dependency.swift diff --git a/Sources/MarathonCore/Dependency.swift b/Sources/MarathonCore/Dependency.swift new file mode 100644 index 0000000..4ec170d --- /dev/null +++ b/Sources/MarathonCore/Dependency.swift @@ -0,0 +1,14 @@ +import Foundation + +public struct Dependency { + public let name: String? + public let url: URL +} + +extension Dependency: Equatable { + public static func ==(lhs: Dependency, rhs: Dependency) -> Bool { + return + lhs.name == rhs.name + && lhs.url == rhs.url + } +} diff --git a/Sources/MarathonCore/Package.swift b/Sources/MarathonCore/Package.swift index ba4d0ca..05d7fb2 100644 --- a/Sources/MarathonCore/Package.swift +++ b/Sources/MarathonCore/Package.swift @@ -11,12 +11,19 @@ import Releases public struct Package { public let name: String public let url: URL - public var majorVersion: Int + public var version: Version + public var majorVersion: Int { return version.major } } extension Package: Equatable { public static func ==(lhs: Package, rhs: Package) -> Bool { - return lhs.url == rhs.url && lhs.majorVersion == rhs.majorVersion + return lhs.url == rhs.url && lhs.version == rhs.version + } +} + +extension Package: Hashable { + public var hashValue: Int { + return "\(url.absoluteString);\(version.description)".hashValue } } @@ -24,7 +31,17 @@ extension Package: Unboxable { public init(unboxer: Unboxer) throws { name = try unboxer.unbox(key: "name") url = try unboxer.unbox(key: "url") - majorVersion = try unboxer.unbox(key: "majorVersion") + + if let versionData: [String: Int] = try? unboxer.unbox(key: "version") + , let major: Int = versionData["major"] + , let minor: Int = versionData["minor"] + , let patch: Int = versionData["patch"] { + version = Version(major: major, minor: minor, patch: patch, prefix: nil, suffix: nil) + } else { + let majorVersion: Int = try unboxer.unbox(key: "majorVersion") + version = Version(major: majorVersion) + } + } } @@ -42,7 +59,7 @@ internal extension Package { return ".Package(url: \"\(url.absoluteString)\", majorVersion: \(majorVersion))" } - return ".package(url: \"\(url.absoluteString)\", from: \"\(majorVersion).0.0\")" + return ".package(url: \"\(url.absoluteString)\", from: \"\(version.major).\(version.minor).\(version.patch)\")" } } diff --git a/Sources/MarathonCore/PackageManager.swift b/Sources/MarathonCore/PackageManager.swift index bcdb0fa..c0fd389 100644 --- a/Sources/MarathonCore/PackageManager.swift +++ b/Sources/MarathonCore/PackageManager.swift @@ -105,17 +105,17 @@ public final class PackageManager { // MARK: - API - @discardableResult public func addPackage(at url: URL, named name: String? = nil, throwIfAlreadyAdded: Bool = true) throws -> Package { - let dependencyName = try name ?? nameOfPackage(at: url) + @discardableResult public func addPackage(at url: URL, throwIfAlreadyAdded: Bool = true) throws -> Package { + let name = try nameOfPackage(at: url) if throwIfAlreadyAdded { - guard (try? folder.file(named: dependencyName)) == nil else { - throw Error.packageAlreadyAdded(dependencyName) + guard (try? folder.file(named: name)) == nil else { + throw Error.packageAlreadyAdded(name) } } - let latestVersion = try latestMajorVersionForPackage(at: url) - let package = Package(name: dependencyName, url: absoluteRepositoryURL(from: url), majorVersion: latestVersion) + let latestVersion = try latestVersionForPackage(at: url) + let package = Package(name: name, url: absoluteRepositoryURL(from: url), version: latestVersion) try save(package: package) try updatePackages() @@ -124,18 +124,18 @@ public final class PackageManager { return package } - public func addPackagesIfNeeded(from packageInfos: [(URL, String?)]) throws { + public func addPackagesIfNeeded(from dependencies: [Dependency]) throws { let existingPackages = makePackageList() - for info in packageInfos { + for dependency in dependencies { let exists = try existingPackages.contains { (package) throws -> Bool in - return package.url.absoluteString.lowercased() == info.0.absoluteString.lowercased() + return package.url.absoluteString.lowercased() == dependency.url.absoluteString.lowercased() } guard !exists else { continue } - try addPackage(at: info.0, named: info.1, throwIfAlreadyAdded: false) + try addPackage(at: dependency.url, throwIfAlreadyAdded: false) } } @@ -179,7 +179,7 @@ public final class PackageManager { return try makePackageDescription(for: script) } - return masterDescription.replacingOccurrences(of: masterPackageName, with: script.name) + return try generatePackageDescription(for: script, toolsVersion: toolsVersion) } public func symlinkPackages(to folder: Folder) throws { @@ -220,13 +220,13 @@ public final class PackageManager { public func updateAllPackagesToLatestMajorVersion() throws { for var package in addedPackages { - let latestMajorVersion = try latestMajorVersionForPackage(at: package.url) + let latestVersion = try latestVersionForPackage(at: package.url) - guard latestMajorVersion > package.majorVersion else { + guard latestVersion > package.version else { continue } - package.majorVersion = latestMajorVersion + package.version = latestVersion try save(package: package) } @@ -258,7 +258,7 @@ public final class PackageManager { // MARK: - Private - private func latestMajorVersionForPackage(at url: URL) throws -> Int { + private func latestVersionForPackage(at url: URL) throws -> Version { printer.reportProgress("Resolving latest major version for \(url.absoluteString)...") let releases = try perform(Releases.versions(for: url).withoutPreReleases(), @@ -268,7 +268,7 @@ public final class PackageManager { throw Error.failedToResolveLatestVersion(url) } - return latestVersion.major + return latestVersion } private func nameOfPackage(at url: URL) throws -> String { @@ -336,7 +336,7 @@ public final class PackageManager { let package = Package( name: pinnedPackage.name, url: pinnedPackage.url, - majorVersion: pinnedPackage.version.major + version: pinnedPackage.version ) try save(package: package) @@ -400,12 +400,69 @@ public final class PackageManager { try generatedFolder.createFile(named: "Package.swift", contents: description.data(using: .utf8).require()) } + + private func generatePackageDescription(for script: Script, toolsVersion: Version) throws -> String{ + let header = makePackageDescriptionHeader(forSwiftToolsVersion: toolsVersion) + let packages = makePackageDictionary() + + var description = "\(header)\n\n" + + "import PackageDescription\n\n" + + "let package = Package(\n" + + " name: \"\(script.name)\",\n" + + " products: [],\n" + + " dependencies: [\n" + + let dependencyPackages = try Set(script.dependencies.map { dependency throws -> Package in + guard let package = packages[dependency.url] else { + throw PackageManagerError.failedToReadPackageFile(dependency.url.absoluteString) + } + return package + }) + + for (index, package) in dependencyPackages.enumerated() { + if index > 0 { + description += ",\n" + } + + let dependencyString = package.dependencyString(forSwiftToolsVersion: toolsVersion) + description.append(" \(dependencyString)") + } + + description.append("\n ],\n") + + if toolsVersion.major > 3 { + description.append(" targets: [.target(name: \"\(script.name)\", dependencies: [") + + if !script.dependencies.isEmpty { + description.append("\"") + let dependencyNames = try script.dependencies.map { try $0.name ?? nameOfPackage(at: $0.url) } + description.append(dependencyNames.joined(separator: "\", \"")) + description.append("\"") + } + + description.append("])],\n") + } + + if toolsVersion.major >= 4 && toolsVersion.minor >= 2 { + description.append(" swiftLanguageVersions: [.version(\"\(toolsVersion.major).\(toolsVersion.minor)\")]\n)") + } else { + description.append(" swiftLanguageVersions: [\(toolsVersion.major)]\n)") + } + + return description + } private func makePackageList() -> [Package] { return folder.files.compactMap { file in return try? unbox(data: file.read()) } } + + private func makePackageDictionary() -> [URL: Package] { + var packageDict: [URL: Package] = [:] + makePackageList().forEach { packageDict[$0.url] = $0 } + return packageDict + } private func resolveSwiftToolsVersion() throws -> Version { var versionString = try shellOutToSwiftCommand("package --version", printer: printer) diff --git a/Sources/MarathonCore/Script.swift b/Sources/MarathonCore/Script.swift index a264677..14841c0 100644 --- a/Sources/MarathonCore/Script.swift +++ b/Sources/MarathonCore/Script.swift @@ -69,6 +69,7 @@ public final class Script { public let name: String public let folder: Folder + public var dependencies: [Dependency] private let printer: Printer private var copyLoopDispatchQueue: DispatchQueue? @@ -76,9 +77,10 @@ public final class Script { // MARK: - Init - init(name: String, folder: Folder, printer: Printer) { + init(name: String, folder: Folder, dependencies: [Dependency], printer: Printer) { self.name = name self.folder = folder + self.dependencies = dependencies self.printer = printer } diff --git a/Sources/MarathonCore/ScriptManager.swift b/Sources/MarathonCore/ScriptManager.swift index 1c067de..013aea9 100644 --- a/Sources/MarathonCore/ScriptManager.swift +++ b/Sources/MarathonCore/ScriptManager.swift @@ -169,15 +169,16 @@ public final class ScriptManager { private func script(from file: File) throws -> Script { let identifier = scriptIdentifier(from: file.path) let folder = try createFolderIfNeededForScript(withIdentifier: identifier, file: file) - let script = Script(name: file.nameExcludingExtension, folder: folder, printer: printer) - + let script = Script(name: file.nameExcludingExtension, folder: folder, dependencies: [], printer: printer) + if let marathonFile = try script.resolveMarathonFile(fileName: config.dependencyFile) { - let packageInfos: [(URL, String?)] = marathonFile.packageURLs.map { ($0, nil) } - try packageManager.addPackagesIfNeeded(from: packageInfos) + let marathonFileDependencies: [Dependency] = marathonFile.packageURLs.map { Dependency(name: nil, url: $0) } + try packageManager.addPackagesIfNeeded(from: marathonFileDependencies) try addDependencyScripts(fromMarathonFile: marathonFile, for: script) + script.dependencies += marathonFileDependencies } - try resolveInlineDependencies(from: file) + script.dependencies += try resolveInlineDependencies(from: file) do { let packageFile = try folder.createFile(named: "Package.swift") @@ -249,7 +250,7 @@ public final class ScriptManager { let cloneFiles = cloneFolder.makeFileSequence(recursive: true) if cloneFiles.contains(where: { $0.name == "main.swift" }) { - return Script(name: packageName, folder: cloneFolder, printer: printer) + return Script(name: packageName, folder: cloneFolder, dependencies: [], printer: printer) } } @@ -311,10 +312,10 @@ public final class ScriptManager { } } - private func resolveInlineDependencies(from file: File) throws { + private func resolveInlineDependencies(from file: File) throws -> [Dependency] { let lines = try file.readAsString().components(separatedBy: .newlines) - var packages = [(URL, String?)]() + var dependencies = [Dependency]() for line in lines { if line.hasPrefix("import ") { @@ -334,7 +335,7 @@ public final class ScriptManager { throw Error.invalidInlineDependencyURL(urlString) } - packages.append((url, importName)) + dependencies.append(Dependency(name: importName, url: url)) } else if let firstCharacter = line.unicodeScalars.first { guard !CharacterSet.alphanumerics.contains(firstCharacter) else { break @@ -342,7 +343,8 @@ public final class ScriptManager { } } - try packageManager.addPackagesIfNeeded(from: packages) + try packageManager.addPackagesIfNeeded(from: dependencies) + return dependencies } private func makeManagedScriptPathList() -> [String] { From cb87ba7a4d174be55a616e966025ebaf6e1e6c90 Mon Sep 17 00:00:00 2001 From: Kyle Newsome Date: Sat, 10 Nov 2018 11:18:05 -0500 Subject: [PATCH 3/5] Make sure dependency and package use a consistent URL --- Sources/MarathonCore/Dependency.swift | 2 +- Sources/MarathonCore/PackageManager.swift | 15 +++++++++------ Sources/MarathonCore/ScriptManager.swift | 7 +++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Sources/MarathonCore/Dependency.swift b/Sources/MarathonCore/Dependency.swift index 4ec170d..912a245 100644 --- a/Sources/MarathonCore/Dependency.swift +++ b/Sources/MarathonCore/Dependency.swift @@ -2,7 +2,7 @@ import Foundation public struct Dependency { public let name: String? - public let url: URL + public var url: URL } extension Dependency: Equatable { diff --git a/Sources/MarathonCore/PackageManager.swift b/Sources/MarathonCore/PackageManager.swift index c0fd389..147939f 100644 --- a/Sources/MarathonCore/PackageManager.swift +++ b/Sources/MarathonCore/PackageManager.swift @@ -124,18 +124,21 @@ public final class PackageManager { return package } - public func addPackagesIfNeeded(from dependencies: [Dependency]) throws { + public func addPackagesIfNeeded(from dependencies: [Dependency]) throws -> [Dependency] { let existingPackages = makePackageList() - for dependency in dependencies { - let exists = try existingPackages.contains { (package) throws -> Bool in + return try dependencies.map { dependency throws in + let existingPackage = try existingPackages.first { (package) throws -> Bool in return package.url.absoluteString.lowercased() == dependency.url.absoluteString.lowercased() } - guard !exists else { - continue + guard existingPackage == nil else { + return dependency } - try addPackage(at: dependency.url, throwIfAlreadyAdded: false) + let newPackage = try addPackage(at: dependency.url, throwIfAlreadyAdded: false) + var dep = dependency + dep.url = newPackage.url // make sure that any ~ or trailing slashes are identical by setting a new URL on the dependency + return dep } } diff --git a/Sources/MarathonCore/ScriptManager.swift b/Sources/MarathonCore/ScriptManager.swift index 013aea9..2c7c411 100644 --- a/Sources/MarathonCore/ScriptManager.swift +++ b/Sources/MarathonCore/ScriptManager.swift @@ -173,9 +173,9 @@ public final class ScriptManager { if let marathonFile = try script.resolveMarathonFile(fileName: config.dependencyFile) { let marathonFileDependencies: [Dependency] = marathonFile.packageURLs.map { Dependency(name: nil, url: $0) } - try packageManager.addPackagesIfNeeded(from: marathonFileDependencies) + let resolvedDependencies = try packageManager.addPackagesIfNeeded(from: marathonFileDependencies) try addDependencyScripts(fromMarathonFile: marathonFile, for: script) - script.dependencies += marathonFileDependencies + script.dependencies += resolvedDependencies } script.dependencies += try resolveInlineDependencies(from: file) @@ -343,8 +343,7 @@ public final class ScriptManager { } } - try packageManager.addPackagesIfNeeded(from: dependencies) - return dependencies + return try packageManager.addPackagesIfNeeded(from: dependencies) } private func makeManagedScriptPathList() -> [String] { From d4cb79c0125a4e1c13f3d5d2e5018431370d184a Mon Sep 17 00:00:00 2001 From: Kyle Newsome Date: Sun, 11 Nov 2018 10:47:09 -0500 Subject: [PATCH 4/5] Support for direct path references in Swift Tools v4.2 --- Package.swift | 2 +- Sources/MarathonCore/Package.swift | 4 ++++ Sources/MarathonCore/PackageManager.swift | 26 +++++++---------------- Sources/MarathonCore/ScriptManager.swift | 2 +- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/Package.swift b/Package.swift index b740e07..9617e5c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:4.1 +// swift-tools-version:4.2 /** * Marathon diff --git a/Sources/MarathonCore/Package.swift b/Sources/MarathonCore/Package.swift index 05d7fb2..ddf5be8 100644 --- a/Sources/MarathonCore/Package.swift +++ b/Sources/MarathonCore/Package.swift @@ -58,6 +58,10 @@ internal extension Package { if toolsVersion.major == 3 { return ".Package(url: \"\(url.absoluteString)\", majorVersion: \(majorVersion))" } + + if toolsVersion >= Version(major: 4, minor: 2) && !url.isForRemoteRepository { + return ".package(path: \"\(url.absoluteString)\")" + } return ".package(url: \"\(url.absoluteString)\", from: \"\(version.major).\(version.minor).\(version.patch)\")" } diff --git a/Sources/MarathonCore/PackageManager.swift b/Sources/MarathonCore/PackageManager.swift index 147939f..652c4cd 100644 --- a/Sources/MarathonCore/PackageManager.swift +++ b/Sources/MarathonCore/PackageManager.swift @@ -169,19 +169,9 @@ public final class PackageManager { } public func makePackageDescription(for script: Script) throws -> String { - guard let masterDescription = try? generatedFolder.file(named: "Package.swift").readAsString() else { - try updatePackages() - return try makePackageDescription(for: script) - } - let toolsVersion = try resolveSwiftToolsVersion() let expectedHeader = makePackageDescriptionHeader(forSwiftToolsVersion: toolsVersion) - guard masterDescription.hasPrefix(expectedHeader) else { - try generateMasterPackageDescription(forSwiftToolsVersion: toolsVersion) - return try makePackageDescription(for: script) - } - return try generatePackageDescription(for: script, toolsVersion: toolsVersion) } @@ -319,14 +309,14 @@ public final class PackageManager { private func updatePackages() throws { printer.reportProgress("Updating packages...") - do { - let toolsVersion = try resolveSwiftToolsVersion() - try generateMasterPackageDescription(forSwiftToolsVersion: toolsVersion) - try shellOutToSwiftCommand("package update", in: generatedFolder, printer: printer) - try generatedFolder.createSubfolderIfNeeded(withName: "Packages") - } catch { - throw Error.failedToUpdatePackages(folder) - } +// do { +// let toolsVersion = try resolveSwiftToolsVersion() +// try generateMasterPackageDescription(forSwiftToolsVersion: toolsVersion) +// try shellOutToSwiftCommand("package update", in: generatedFolder, printer: printer) +// try generatedFolder.createSubfolderIfNeeded(withName: "Packages") +// } catch { +// throw Error.failedToUpdatePackages(folder) +// } } private func addMissingPackageFiles() { diff --git a/Sources/MarathonCore/ScriptManager.swift b/Sources/MarathonCore/ScriptManager.swift index 2c7c411..0880110 100644 --- a/Sources/MarathonCore/ScriptManager.swift +++ b/Sources/MarathonCore/ScriptManager.swift @@ -280,7 +280,7 @@ public final class ScriptManager { private func createFolderIfNeededForScript(withIdentifier identifier: String, file: File) throws -> Folder { let scriptFolder = try cacheFolder.createSubfolderIfNeeded(withName: identifier) - try packageManager.symlinkPackages(to: scriptFolder) +// try packageManager.symlinkPackages(to: scriptFolder) if (try? scriptFolder.file(named: "OriginalFile")) == nil { try scriptFolder.createSymlink(to: file.path, at: "OriginalFile", printer: printer) From 5ad43267881973ee7a9d172051f8b5c9d3a865b0 Mon Sep 17 00:00:00 2001 From: Kyle Newsome Date: Tue, 13 Nov 2018 19:08:51 -0500 Subject: [PATCH 5/5] Makes Dependency and Script classes public --- Sources/MarathonCore/Dependency.swift | 5 +++++ Sources/MarathonCore/Script.swift | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/MarathonCore/Dependency.swift b/Sources/MarathonCore/Dependency.swift index 912a245..88a2556 100644 --- a/Sources/MarathonCore/Dependency.swift +++ b/Sources/MarathonCore/Dependency.swift @@ -3,6 +3,11 @@ import Foundation public struct Dependency { public let name: String? public var url: URL + + public init(name: String? = nil, url: URL) { + self.name = name + self.url = url + } } extension Dependency: Equatable { diff --git a/Sources/MarathonCore/Script.swift b/Sources/MarathonCore/Script.swift index 14841c0..2651dd0 100644 --- a/Sources/MarathonCore/Script.swift +++ b/Sources/MarathonCore/Script.swift @@ -77,7 +77,7 @@ public final class Script { // MARK: - Init - init(name: String, folder: Folder, dependencies: [Dependency], printer: Printer) { + public init(name: String, folder: Folder, dependencies: [Dependency], printer: Printer) { self.name = name self.folder = folder self.dependencies = dependencies