Proposal: dependency preheating


(Fastmail) #1

Sometimes it is desirable to run a sequence of commands and cache the output of those commands as a filesystem snapshot in CI. This is especially relevant to swift packages, where compilation times are relatively long, but the dependencies don’t change often.

In particular, Docker users will often do something like so (though this can be applied to Travis and other CI solutions).

FROM swift

WORKDIR /code

COPY Package.swift /code/
RUN swift build -c release # This fails because of point 2, below
# Changes to `Sources` will not trigger refetch or recompilation of dependencies
COPY ./Sources /code/Sources
RUN swift build -c release
EXPOSE 8000
CMD .build/release/App

Unfortunately, the above fails in certain scenarios:

1. `swift package fetch` will break if the target source layout doesn’t match. This bug is described in https://bugs.swift.org/browse/SR-3756
2. `swift build` will correctly fail if it cannot find sources matching the source layout described in Package.swift. This is a feature, not a bug.

I propose making this workflow easier with `swift package preheat` – a command which will fetch ONLY dependencies specified in Package.swift, and optionally (with the option —build) compile those dependencies, but not the main Package.

This would also be great for bootstrapping a project with a lot of dependencies, or with deps that have long compilation times.

This command should also support specifying a build configuration, so that we can cache both debug and release builds at the same time to accelerate development iteration.

Are there any comments, concerns, objections or +1s to this?

Tom


(Ankit Aggarwal) #2

Hi,

I think this makes sense and is very useful. The fetch part does sound like a bug and should be an easy fix (hopefully).

Instead of preset we could add a flag to swift build for e.g. --dependencies or --deps-only. This would automatically give you all the other build options.
$ swift build --deps-only

This might be a bit tricky to do but should be possible by only reading the product target dependencies in the root manifest. What do others think?

···

On 27-Jan-2017, at 6:48 PM, swizzlr via swift-build-dev <swift-build-dev@swift.org> wrote:

Sometimes it is desirable to run a sequence of commands and cache the output of those commands as a filesystem snapshot in CI. This is especially relevant to swift packages, where compilation times are relatively long, but the dependencies don’t change often.

In particular, Docker users will often do something like so (though this can be applied to Travis and other CI solutions).

FROM swift

WORKDIR /code

COPY Package.swift /code/
RUN swift build -c release # This fails because of point 2, below
# Changes to `Sources` will not trigger refetch or recompilation of dependencies
COPY ./Sources /code/Sources
RUN swift build -c release
EXPOSE 8000
CMD .build/release/App

Unfortunately, the above fails in certain scenarios:

1. `swift package fetch` will break if the target source layout doesn’t match. This bug is described in https://bugs.swift.org/browse/SR-3756
2. `swift build` will correctly fail if it cannot find sources matching the source layout described in Package.swift. This is a feature, not a bug.

I propose making this workflow easier with `swift package preheat` – a command which will fetch ONLY dependencies specified in Package.swift, and optionally (with the option —build) compile those dependencies, but not the main Package.

This would also be great for bootstrapping a project with a lot of dependencies, or with deps that have long compilation times.

This command should also support specifying a build configuration, so that we can cache both debug and release builds at the same time to accelerate development iteration.

Are there any comments, concerns, objections or +1s to this?

Tom

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev


(Daniel Dunbar) #3

I think it would be fine to have a --dependencies or --dependencies-only
flag, and bypass the local sources as much as possible.

I'm not sure exactly how useful it would be yet, but I wouldn't object to a
PR for it as long as it was a maintainable addition (e.g. we need to make
sure it handles the upcoming changes w.r.t. products API w/ additional
work).

- Daniel

···

On Fri, Jan 27, 2017 at 6:05 AM, Ankit Aggarwal via swift-build-dev < swift-build-dev@swift.org> wrote:

Hi,

I think this makes sense and is very useful. The fetch part does sound
like a bug and should be an easy fix (hopefully).

Instead of preset we could add a flag to swift build for e.g.
--dependencies or --deps-only. This would automatically give you all the
other build options.
$ swift build --deps-only

This might be a bit tricky to do but should be possible by only reading
the product target dependencies in the root manifest. What do others think?

On 27-Jan-2017, at 6:48 PM, swizzlr via swift-build-dev < > swift-build-dev@swift.org> wrote:

Sometimes it is desirable to run a sequence of commands and cache the
output of those commands as a filesystem snapshot in CI. This is especially
relevant to swift packages, where compilation times are relatively long,
but the dependencies don’t change often.

In particular, Docker users will often do something like so (though this
can be applied to Travis and other CI solutions).

FROM swift

WORKDIR /code

COPY Package.swift /code/
RUN swift build -c release # This fails because of point 2, below
# Changes to `Sources` will not trigger refetch or recompilation of
dependencies
COPY ./Sources /code/Sources
RUN swift build -c release
EXPOSE 8000
CMD .build/release/App

Unfortunately, the above fails in certain scenarios:

1. `swift package fetch` will break if the target source layout doesn’t
match. This bug is described in https://bugs.swift.org/browse/SR-3756
2. `swift build` will correctly fail if it cannot find sources matching
the source layout described in Package.swift. This is a feature, not a bug.

I propose making this workflow easier with `swift package preheat` – a
command which will fetch ONLY dependencies specified in Package.swift, and
optionally (with the option —build) compile those dependencies, but not the
main Package.

This would also be great for bootstrapping a project with a lot of
dependencies, or with deps that have long compilation times.

This command should also support specifying a build configuration, so that
we can cache both debug and release builds at the same time to accelerate
development iteration.

Are there any comments, concerns, objections or +1s to this?

Tom

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev