[swift-evolution] [swift-build-dev] Proposal: SwiftPM Target Access Control

Anders Bertelrud anders at apple.com
Thu Jul 7 11:05:27 CDT 2016


Hello Ankit,

Thanks a lot for taking the initiative for this!  This looks like a great start.

I think what we will eventually want to do is to let package authors express the "role" of each target, which would then allow expression of such things as build-time vs run-time dependencies.  For example, in some cases there may be a dependency on a build tool (that generates code or formats resources in some way) and that affects such things as the platform and architectures for which the target should be built.

But that can all be added in the future.  I like the direction represented by this proposal, and I think it represents a good improvement on its own.  I do agree with other comments that it would be a great addition to let dependencies be specified at the target level, not just the package level.  That would be in scope for inclusion in this proposal.

Thanks!

Anders

> On 2016-07-07, at 05.26, Ankit Agarwal via swift-build-dev <swift-build-dev at swift.org> wrote:
> 
> Hi swift packagers,
> 
> I am proposing access control to package targets. 
> 
> Link: https://github.com/aciidb0mb3r/swift-evolution/blob/swiftpm-module-access-control/proposals/xxxx-swiftpm-target-access-control.md <https://github.com/aciidb0mb3r/swift-evolution/blob/swiftpm-module-access-control/proposals/xxxx-swiftpm-target-access-control.md>
> 
> Feedback appreciated!
> 
> SwiftPM Target Access Control
> 
> Proposal: SE-XXXX <https://github.com/apple/swift-evolution/blob/master/proposals/xxxx-swiftpm-target-access-control.md>
> Author: Ankit Aggarwal <https://github.com/aciidb0mb3r>
> Status: In Discussion
> Review manager: TBD
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#introduction>Introduction
> 
> This proposal aims to address two issues:
> 
> Control over the targets exposed (and built) when a SwiftPM package is used as a dependency.
> 
> Import (and build) selected targets of a dependency.
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#motivation>Motivation
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#1-control-over-exposed-targets>1. Control over exposed targets:
> 
> SwiftPM allows multiple targets (or modules) inside a package. Packages usually contain sample usage or example targets which are useful during development or testing of the package but are redundant when the package is used as a dependency. This increases compile time for the user of the package.
> 
> As a concrete example: Vapor has a target called Development <https://github.com/qutheory/vapor/tree/master/Sources/Development>.
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#2-import-selected-targets>2. Import selected targets:
> 
> Sometimes user of a package is only interested in few targets of a dependency instead of all the targets. Currently there is no way to state this in Package.swift and all the targets are implicitly built and exposed to the user package.
> 
> For e.g.: I would like to use the targets libc, POSIX, Basic of SwiftPM but don't want other targets to be built or exposed in my package.
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#proposed-solution>Proposed Solution
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#1-control-over-exposed-targets-1>1. Control over exposed targets:
> 
> I propose that package authors be able mark the targets they don't want to be exposed as private i.e. the privatetargets will be built when that package is root package but not when the package is used as a dependency.
> 
> To mark a target as private I propose PackageDescription's Target gains a isPrivate boolean property which defaults to false.
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#2-import-selected-targets-1>2. Import selected targets:
> 
> I propose that package user be able to specify the targets they want to import into their package.
> 
> To specify the targets to be import I propose to add an optional string array property targets in PackageDescription's Package.Dependency which defaults to nil i.e. all targets.
> 
> Instead of an optional string array property an enum can also be used:
> 
> enum ImportedTargets {
>     case allTargets // Import all the targets, default value.
>     case targets([String]) // Import only these targets.
> }
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#detailed-design>Detailed Design
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#1-control-over-exposed-targets-2>1. Control over exposed targets:
> 
> Consider a package with following structure: 
> 
> ├── Package.swift
> └── Sources
>     ├── FooLibrary
>     │   └── Foo.swift
>     └── SampleCLI
>         └── main.swift
> The manifest with private target could look like:
> 
> import PackageDescription
> 
> let package = Package(
>    name: "FooLibrary",
>    targets: [
>        Target(name: "FooLibrary"),
>        Target(name: "SampleCLI", isPrivate: true),
>    ])
> When this package is used as a dependency only FooLibrary is built and is importable.
> 
> Targets can have other targets as dependency inside a package. A private target should only be a dependency to other private targets. For e.g. A manifest like this should result in a build failure.
> 
> import PackageDescription
> 
> let package = Package(
>    name: "FooLibrary",
>    targets: [
>        Target(name: "FooCore", isPrivate: true),
>        Target(name: "FooLibrary", dependencies: ["FooCore"]), // Error FooCore is private.
>        Target(name: "SampleCLI", dependencies: ["FooCore"], isPrivate: true), // Not an error because SampleCLI is private.
>    ])
> Error: FooCore is a private target, it cannot be a dependency to the public target FooLibrary.
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#2-import-selected-targets-2>2. Import selected targets:
> 
> Consider a dependency with following manifest file:
> 
> import PackageDescription
> 
> let package = Package(
>    name: "FooLibrary",
>    targets: [
>        Target(name: "Foo"),
>        Target(name: "Bar", dependencies: ["Foo"]),
>        Target(name: "Baz"),
>    ])
> To get only the Bar target from the above package, following manifest could be written:
> 
> import PackageDescription
> 
> let package = Package(
>    name: "FooUser",
>    dependencies: [
>        .Package(
>            url: "../FooLibrary", 
>            majorVersion: 1, 
>            targets: ["Bar"])
>    ])
> Note: In this case since Bar depends on Foo, Foo will be also be implicitly built and be available.
> 
> Any target mentioned in targets and not present in the package should result in build failure.
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#impact-on-existing-code>Impact on Existing Code
> 
> There will be no impact on existing code as these features are additive.
> 
>  <https://github.com/aciidb0mb3r/swift-evolution/tree/swiftpm-module-access-control#alternatives-considered>Alternatives Considered
> 
> None at this time.
> 
> -- 
> Ankit
> 
> 
> 
> _______________________________________________
> swift-build-dev mailing list
> swift-build-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-build-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160707/d2bc2ff7/attachment-0001.html>


More information about the swift-evolution mailing list