• SE-0292 (Package registry)ͳͲʹΑͬͯɺcon fi gurationσΟϨΫτϦʹΑΓݎ ࿚ͳσΟϨΫτϦߏ͕ٻΊΒΕΔΑ͏ʹͳͬͨɻ • <project>/.swiftpm/con fi g (mirrors fi le) -> <project>/.swiftpm/con fi guration/mirrors.json • ~/.swiftpm/con fi g/collections.json (collection fi le) -> ~/.swiftpm/con fi guration/collections.json • Swift 5.6͕ࣗಈͰίϐʔͯ͠ɺϢʔβʔʹݹ͍ͷΛফ͢Α͏ʹwarningΛग़͢ https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
protocol Product { /// Unique identifier for the product. var id: ID { get } typealias ID = String /// The name of the product, as defined in the package manifest. This name /// is unique among the products of the package in which it is defined. var name: String { get } /// The targets that directly comprise the product, in the order in which /// they are declared in the package manifest. The product will contain the /// transitive closure of the these targets and their dependencies. Some /// kinds of products have further restrictions on the set of targets (for /// example, an executable product must have one and only one target that /// defines the main entry point for an executable). var targets: [Target] { get } }
protocol Target { /// Unique identifier for the target. var id: ID { get } typealias ID = String /// The name of the target, as defined in the package manifest. This name /// is unique among the targets of the package in which it is defined. var name: String { get } /// The absolute path of the target directory in the local file system. var directory: Path { get } /// Any other targets on which this target depends, in the same order as /// they are specified in the package manifest. Conditional dependencies /// that do not apply have already been filtered out. var dependencies: [TargetDependency] { get } } /// Represents a dependency of a target on a product or on another target. public enum TargetDependency { /// A dependency on a target in the same package. case target(Target) /// A dependency on a product in another package. case product(Product) }
targets on which the reciver depends, /// ordered such that every dependency appears before any other target that /// depends on it (i.e. in "topological sort order"). public var recursiveTargetDependencies: [Target] { // FIXME: We can rewrite this to use a stack instead of recursion. var result = [Target]() var visited = Set<Target.ID>() func visit(target: Target) { guard !visited.insert(target.id).inserted else { return } target.dependencies.forEach{ visit(dependency: $0) } result.append(target) } func visit(dependency: TargetDependency) { switch dependency { case .target(let target): visit(target: target) case .product(let product): product.targets.forEach{ visit(target: $0) } } } return result } } https://github.com/apple/swift-package-manager/pull/3758/ fi les#di ff -79b44ed51fc53000c5d9cfd941b77065d03a99760a8b1ddd6cf5fafdc5f5835fR417-R440
releases GET /{scope}/{name}/{version} Fetch metadata for a package release GET /{scope}/{name}/{version}/Package.swift{?swift-version} Fetch manifest for a package release GET /{scope}/{name}/{version}.zip Download source archive for a package release GET /identi fi ers{?url} Lookup package identi fi ers registered for a URL
resolutionͷtop-level unitͱ͢Δ • RegistryPackageContainer͕HTTPϦ ΫΤετͱಉͷૢ࡞Λߦ͏ public protocol PackageContainer { /// The identifier for the package. var package: PackageReference { get } func isToolsVersionCompatible(at version: Version) -> Bool func toolsVersion(for version: Version) throws -> ToolsVersion /// Get the list of versions which are available for the package. /// /// The list will be returned in sorted order, with the latest version *first*. /// All versions will not be requested at once. Resolver will request the next one only /// if the previous one did not satisfy all constraints. func toolsVersionsAppropriateVersionsDescending() throws -> [Version] /// Get the list of versions in the repository sorted in the ascending order, that is the earliest /// version appears first. func versionsAscending() throws -> [Version] func versionsDescending() throws -> [Version] // FIXME: We should perhaps define some particularly useful error codes // here, so the resolver can handle errors more meaningfully. // /// Fetch the declared dependencies for a particular version. /// /// This property is expected to be efficient to access, and cached by the /// client if necessary. /// /// - Precondition: `versions.contains(version)` /// - Throws: If the version could not be resolved; this will abort /// dependency resolution completely. func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [PackageContainerConstraint] /// Fetch the declared dependencies for a particular revision. /// /// This property is expected to be efficient to access, and cached by the /// client if necessary. /// /// - Throws: If the revision could not be resolved; this will abort /// dependency resolution completely. func getDependencies(at revision: String, productFilter: ProductFilter) throws -> [PackageContainerConstraint] /// Fetch the dependencies of an unversioned package container. /// /// NOTE: This method should not be called on a versioned container. func getUnversionedDependencies(productFilter: ProductFilter) throws -> [PackageContainerConstraint] /// Get the updated identifier at a bound version. /// /// This can be used by the containers to fill in the missing information that is obtained /// after the container is available. The updated identifier is returned in result of the /// dependency resolution. func loadPackageReference(at boundVersion: BoundVersion) throws -> PackageReference }
Manager during dependency resolution Task Git operation Registry request Fetch the contents of a package git clone && git checkout GET /{scope}/{name}/{version}.zip List the available tags for a package git tag GET /{scope}/{name} Fetch a package manifest git clone GET /{scope}/{name}/{version}/Package.swift
of downloaded source archive of dependency 'mona.LinkedList' (c2b934fe66e55747d912f1cfd03150883c4f037370c40ca2ad4203805db79457) does not match checksum speci fi ed by the manifest (ed008d5af44c1d0ea0e3668033cae9b695235f18b1a99240b7cf0f3d9559a30d)
ίϚϯυඪ४ͷsource archiveΛ࡞͢Δํ๏Λఏڙ͢Δ SYNOPSIS swift package archive-source [--output=< fi le>] OPTIONS -o < fi le>, --output=< fi le> Write the archive to < fi le>. If unspeci fi ed, the package is written to `\(PackageName).zip`.
• ηϧϑϗετ͍ͨ͠Private Package͕͋Δ • ϛϥʔαΠτΛཱ͍ͯͨ߹ • ঝೝ͢ΈύοέʔδͷΈΛར༻ͤ͞ΔϙϦγʔΛద༻ͤ͞Δ߹ • ύοέʔδͷར༻ঢ়گͷޮՌଌఆΛߦ͍ɺϥϯΩϯάϥΠηϯεྉۚΛٻ͢Δ߹ SYNOPSIS swift package-registry set <url> [options] OPTIONS: --global Apply settings to all projects for this user --scope Associate the registry with a given scope --login Specify a user name for the remote machine --password Supply a password for the remote machine
swift package-registry unset [options] OPTIONS: --global Apply settings to all projects for this user --scope Removes the registry's association to a given scope
fi guration/registries.json Λߋ৽͢Δ • Local Con fi guration GlobalΑΓ༏ઌ͞ΕΔ ྫ) foo scope https://local.example.com Λར༻͢Δ • ΧϨϯτσΟϨΫτϦͷPackageϚχϑΣετ (./Package.swift) • طଘͷlock fi le (./Package.resolved) • Local con fi guration (./.swiftpm/con fi guration/registries.json) • Global con fi guration (~/.swiftpm/con fi guration/registries.json) SYNOPSIS swift package-registry unset [options] OPTIONS: --global Apply settings to all projects for this user --scope Removes the registry's association to a given scope // Global configuration (~/.swiftpm/configuration/registries.json) { "registries": { "[default]": { "url": "https://global.example.com" }, "foo": { "url": "https://global.example.com" }, }, "version": 1 } // Local configuration (.swiftpm/configuration/registries.json) { "registries": { "foo": { "url": "https://local.example.com" } }, "version": 1 }
• Swift Package Managerɺ࣍ͷରࡦΛߨ͡Δ͜ͱͰɺ͜ͷϦεΫΛ͞ΒʹܰݮͰ͖·͢ɻ • ͯ͢ͷURLʹHTTPSΛద༻͢Δ • DNS over HTTPSʢDoHʣΛ༻ͨ͠URLͷղܾ • Punycodeͱͯ͠ද͞ΕΔࠃࡍԽυϝΠϯ໊ʢIDNʣͷURLΛཁٻ͢Δ • Publish͢ΔࡍϦΫΤετʹଟཁૉೝূΛར༻͢Δ͜ͱΛਪ͢Δ