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

Ankit Agarwal ankit at ankit.im
Thu Jul 7 13:45:58 CDT 2016


Hi,

Thanks for feedback. I agree that specifying external dependencies with
targets would be great.
I think the only thing issue is to figure out is how to specify them. Some
thoughts:

Note: Currently target name has to be unique across all the targets in the
package (including its dependencies).

1. Target(name: "FooLibrary", dependencies: ["FooCore", "ExternalTarget"])

pro: This is probably the easiest way to specify the external dependency
it. It fits perfectly into the current semantics and just needs to be
implemented for external deps.
con: No way to know which targets are external dependencies by just looking
at manifest file. No way to know from which package that dep is coming from.

2. Target(name: "FooLibrary", dependencies: ["FooCore"],
externalDependencies: ["ExternalTarget"])

pro: Explicitly mentions what all external deps the target relies on.
con: Doesn't mention which package contains that external dep.

3. Target(name: "FooLibrary", dependencies: ["FooCore",
"SomePackage.ExternalTarget"])

pro: Mentions which package + target the external dependency belongs to.
con: is probably too verbose and stringly typed.

4. Target(name: "FooLibrary", dependencies: ["FooCore"],
externalDependencies: [("SomePackage", "ExternalTarget")])

pro: Mentions which package + target the external dependency belongs to.
con: verbose and stringly typed.

Would love some feedback or another way to better express the external
deps, will update the proposal then.

Thanks!

On Thu, Jul 7, 2016 at 9:35 PM, Anders Bertelrud <anders at apple.com> wrote:

> 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
>
> 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:
>
>    1.
>
>    Control over the targets exposed (and built) when a SwiftPM package is
>    used as a dependency.
>    2.
>
>    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
>
>
>


-- 
Ankit
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20160708/07a26d97/attachment.html>


More information about the swift-build-dev mailing list