-
Notifications
You must be signed in to change notification settings - Fork 55
Swiftly proxies #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Swiftly proxies #155
Conversation
Add a design proposal for the new swiftly proxy system
Hijacking https://github.com/anders0nmat/swift-embedded-pm/pull/3/files Consider:
Or proxy CLI arguments that don't exist in swiftly to
(I just write Swift for fun, so take my suggestions with a grain of salt) |
@BrianHenryIE your feedback is appreciated, thank you.
It seems from the above patch that the end goal is to be able to invoke the llvm-ar executable from the current toolchain. I'm curious, why dig through the symlink to the real path using the
Providing a swiftly run subcommand is something that we can consider as an enhancement to the current swiftly design. We could allow someone to run any command that they want, not just the toolchain ones. The command runs where the PATH is set to the toolchain binaries with the highest precedence. Also, we can set certain environment variables like CC and CXX to the selected clang version.
We can put these ideas and more into #22 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% convinced by this yet. I wonder how the core team would feel about the swift exe being hijacked by swiftly.
|
||
The use subcommand also supports `.swift-version` files. If version file is present in the current working directory, or an ancestory directory, then swiftly will update that file with the new version to use. This can be a useful feature for a team to share and align on toolchain versions with git. As a special case, if swiftly could not find a version file, but it could find a Package.swift file it will create a new version file for you in the package and set that to the requested toolchain version. | ||
|
||
Note: The `.swift-version` file mechanisms can be overridden using the `--global-default` flag so that your swiftly installation's default toolchain can be set explicitly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather the default is the other way. ie use
edits global settings and you can change local settings with a --local
flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that there are advantage of having this local as the default. It encourages the sharing of the toolchain revision that the team is working with through discovery of this feature of swiftly. Also, this helps to tie into one of the values of using swiftly itself, which is how easily and flexibly you can switch toolchains.
In terms of precedence, git defaults to local over global for its configuration.
I'm curious what you think are the pitfalls of this approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I realised as I was writing this, there is previous art that defaults to local. It is more a preference on my behalf and how I'd use swiftly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pyenv
and rbenv
call this command local
, global
or shell
depending on whether you're setting the Python/Ruby version for a directory, globally on the machine (for your user), or just in the current shell. The shell setting overrides the local setting, which overrides the global setting.
I'm definitely interested to hear if there are opinions from the core team about this enhancement. I prefer to think of this as extending the semantics, not "hijacking" the toolchain itself. There are precedents for a proxy mechanism of a toolchain manager on top of the toolchain itself, such as |
DESIGN.md
Outdated
* The presence of a .swift-version file in the current working directory, or ancestor directory, with the required toolchain version | ||
* The swiftly default (in-use) toolchain set in the config.json by `swiftly install` or `swiftly use` commands | ||
|
||
In the first two cases, if there is no matching toolchain installed, swiftly will attempt to automatically install the requested toolchain and use it if the installation succeeeds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need a way to disable this. People with a bad network connection will not be wanting to download 900MB of swift toolchain just to build a project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll update this since this has come up a few times. It could be a case of over automation. Instead, if there's no matching toolchain then the command fails. The swiftly install
with no arguments can be used to install the currently selected toolchain with the full capabilities of that subcommand, including post install script, etc. Also, it's clear that an error is related to the install operation itself since that is the request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we also have a command line option to ignore the .swift-version
file. This would make it easier for things like CI to test a library (which includes a .swift-version
file) against multiple swift toolchains
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think that this in this case the command-line selectors will take precedence over both the .swift-version file and the global default in-use toolchain from the config.json. The CI can do this to force specific toolchain(s):
swiftly install 5.10.1 # Install this specific toolchain
swift build +5.10.1 # Build with this toolchain
…ocation clarify the boundaries of the swiftly toolchain abstraction and elaborate on how to work around them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be interested to hear the core team's view on intercepting any calls to swift
. Node does a similar thing with nvm
IIRC so there's precedent, not that that's the best example of an ecosystem if there are any security concerns 😅
I would say that the +
syntax is not overly discoverable or intuitive, I'm not aware of any other tool that has this. I'd be more inclined to have an actual flag that can either be intercepted or called via swiftly run
etc.
Overall however I agree that having a mechanism for being able to run commands in Swift with different versions without having to constantly switch your local version is valuable and should be implemented
DESIGN.md
Outdated
|
||
Swiftly helps you to easily install different Swift toolchains locally on your account. It also provides a single path where you can run the tools in the currently selected toolchain. Toolchain selection is [configurable](#toolchain-selection) using different mechanisms. | ||
|
||
Note that swiftly is *not* a virtual toolchain in itself since there are cases where it cannot behave as a self-contained Swift toolchain. For example, there can be external dependencies on specific files, such as headers or libraries, far too many and variable between toolchain versions to be managed by swiftly. Also, for long-lived processes, there is no way to gracefully restart them without help from the client. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence needs some tweaking I think
Note that swiftly is *not* a virtual toolchain in itself since there are cases where it cannot behave as a self-contained Swift toolchain. For example, there can be external dependencies on specific files, such as headers or libraries, far too many and variable between toolchain versions to be managed by swiftly. Also, for long-lived processes, there is no way to gracefully restart them without help from the client. | |
Note that swiftly is *not* a virtual toolchain in itself since there are cases where it cannot behave as a self-contained Swift toolchain. For example, there can be external dependencies on specific files, such as headers or libraries, far too many variables between toolchain versions to be managed by swiftly. Also, for long-lived processes, there is no way to gracefully restart them without help from the client. |
Do you know a way to engage the core team on this? I'm also curious if there are any concerns or suggestions from there. The proxy idea has been mentioned in the forums a couple of times now, the last one points to this PR. I have received some feedback, but I don't know if any have been representative of the core.
Thank you, this is a fair observation. The proxy concept along with the In their documentation there is only a small mention of the special selector syntax: I think that this syntax can be discoverable in swiftly by providing (some) examples in the getting started guide, demonstrating how to use swiftly. In the swiftly steady state I imagine that the syntax won't be used very often as the toolchain will likely be selected with either the in-use global default for the user, or hopefully, the project's I can see the
I'm wondering, since this has come up a few times, if it might be worth providing both proxy capability and #22 at the same time in this PR to suit different preferences and use cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally tend to prefer a subcommand over the +
syntax since swiftly isn't ubiquitous (yet 🙂) like rustup is, and so introducing swiftly-specific syntax to a non-swiftly binary invocation may cause confusion for non-swiftly users when they encounter someone else using it (or more frustratingly, compatibility issues in scripts and what not). That said, it is a generally useful syntax, so if the core team is supportive, then I don't have a problem with it.
To avoid blocking the work for this, I'd suggest we start with the more conservative swiftly run <toolchain>
or swiftly exec <toolchain>
command and then add the +
syntax later.
DESIGN.md
Outdated
For cases where the physical toolchain must be located, such as references specific header files, or shared libraries that are not proxied by swiftly there is a method to resolve the currently selected toolchain to its physical location using `swiftly use`. | ||
|
||
``` | ||
swiftly use --location |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps --print-location
? As it is, it looks like --location
affects use
in some way.
DESIGN.md
Outdated
The toolchains (i.e. the contents of a given Swift download tarball) would be contained in the toolchains directory, each named according to the major/minor/patch version. `config.json` would contain any required metadata (e.g. the latest Swift version, which toolchain is selected, etc.). If pulling in Foundation to use `JSONEncoder`/`JSONDecoder` (or some other JSON tool) would be a problem, we could also use something simpler. | ||
|
||
The `~/.local/bin` directory would include symlinks pointing to the `bin` directory of the "active" toolchain, if any. | ||
The `~/.local/bin` directory would include symlinks pointing to swiftly itself. When these binaries are run swiftly proxies them to the requested toolchain, or a default. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to more clearly explain what "these binaries" refer to in this sentence.
Maybe @shahmishal can bring it up but this should probably be raised at the Platform Steering Group until whatever group will end up with ownership of this takes over them |
I think this is right. There are plans to add a third steering group in future (dubbed "Ecosystem") and this might fall under that rather than Platform, but I could see it going either way in this case so starting with the platform steering group is the right way to go for now. The first step is to write up a pitch and post it to the forums. That pitch should cover the pros/cons of the approach, and recommend one (with the others being alternatives considered). Then engagement on the merits can happen in that thread. That said, it's fine to hash out early ideas on a doc in this repo beforehand. Once the pitch has had some time to converge on a way forward, the platform steering group would take it up as a proposal. You don't need the steering group to pre-clear that pitch, though you might want to give them a heads up about it, so they can engage in it too since they'll ultimately be the ones deciding which way to go with this. Note that since Swiftly was ingested into swiftlang and so is part of the Swift project now, I don't see anything contentious about close integration between the swift launch tool and swiftly per se. But of course, the other tradeoffs cited in this thread about exactly how that integration actually works should be discussed. |
Thanks everyone for the discussion here. This has been really positive. I will change the shape of this PR in a couple of ways and see if this can be accomplished in the near term:
Please let me know if there are any concerns over this latest pivot. |
…new swiftly run command
Change the nature of the swiftly symlinks so that they point to the swiftly executable at install time. These do not change when new toolchains are used. Toolchain selection happens each time when the proxies are run. The proxies are created for a well-known set of toolchain binaries that are constant for a wide variety of toolchain versions and platforms. Add support for .swift-version files for toolchain selection. Update the use command so that it can point out which toolchain is in use based on context, such as swift version files that are located in the current working directory or above. The fallback selection comes from the global default configuration's 'inUse' setting. When querying for what's in use the global default is shown with the "(default)" tag. If the in-use toolchain is selected by a swift-version file the path to that file is displayed. Provide a print location flag to the use subcommand that can print the file path of the toolchain that is in use in the current context. When using a new toolchain, depending on whether a swift version is selecting the current one, update the swift version file with the selected toolchain version. If no swift version file can be located, attempt to create a new one at the top of the git worktree. If there is no git worktree, then fallback to updating the global default in the configuration. Provide a global default flag for the use subcommand so that only the global default in-use toolchain is considered and not any of the swift version files.
@swift-ci test macOS |
Out of curiosity, do you have an idea of how this would interact with xcrun? |
Swiftly's mechanisms for toolchain selection are entirely separate from xcrun. But, it will install toolchain packages in the user's volume, and those should be reachable with xcrun. |
…esult and centralized error messages
Provide a run command that allows arbitrary commands to be run in the context of the selected toolchain. Provide a one-off selection mechanism with a special syntax on the run command.
@swift-ci test macOS |
DESIGN.md
Outdated
|
||
`swiftly install` | ||
|
||
If no swift version file can be found then the installation fails indicating that it couldn't fine the file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very small nit, but could we use
If no .swift-version file ...
Rather than
swift version file
Just to be consistent, so users don't conflate the "swift version file" with something else in the Swift ecosystem. This way we explicitly mention the file in question. This is how it's written in the "Installing the version from the .swift-version
files" section
DESIGN.md
Outdated
|
||
`swiftly use main-snapshot` | ||
|
||
The use subcommand also supports `.swift-version` files. If version file is present in the current working directory, or an ancestory directory, then swiftly will update that file with the new version to use. This can be a useful feature for a team to share and align on toolchain versions with git. As a special case, if swiftly could not find a version file, but it could find a Package.swift file it will create a new version file for you in the package and set that to the requested toolchain version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use subcommand also supports `.swift-version` files. If version file is present in the current working directory, or an ancestory directory, then swiftly will update that file with the new version to use. This can be a useful feature for a team to share and align on toolchain versions with git. As a special case, if swiftly could not find a version file, but it could find a Package.swift file it will create a new version file for you in the package and set that to the requested toolchain version. | |
If a .swift-version file |
Simple wording change suggestion
$ swiftly install 5.7-snapshot | ||
$ swiftly install main-snapshot | ||
|
||
Install whatever toolchain is current selected, such as a .swift-version file: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Install whatever toolchain is current selected, such as a .swift-version file: | |
Install whatever toolchain is currently selected, such as a .swift-version file: |
*Run a command while proxying to the selected toolchain commands.* | ||
|
||
|
||
Run a command with a selected toolchain, so that all toolchain commands are become the default added to the system path and other common environment variables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording of this sentence confuses me a bit, might just need some reworking
Sources/Swiftly/Install.swift
Outdated
$ swiftly install 5.7-snapshot | ||
$ swiftly install main-snapshot | ||
Install whatever toolchain is current selected, such as a .swift-version file: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Install whatever toolchain is current selected, such as a .swift-version file: | |
Install whatever toolchain is currently selected, such as a .swift-version file: |
try await Use.execute(toUse, globalDefault: true, &config) | ||
} else { | ||
// If there are no more toolchains installed, just unuse the currently active toolchain. | ||
try Swiftly.currentPlatform.unUse(currentToolchain: toolchain) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want to unuse
the toolchain if there are no more toolchains to be set active, in order to clean up all the symlinks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change the proxy symlinks are created at install time of swiftly and remain there. Keeping them stable helps with certain shells that aggressively cache commands on the PATH, such as zsh. If there are no toolchains installed and someone tries to run "swift", "clang", or some other toolchain command then swiftly will give an error indicating that they can install one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting, so by installing swiftly then you wouldn't really be able to invoke your original swift toolchain installation?
Say I had a toolchain installed, then I decide to install swiftly, I download some toolchains with swiftly, then ultimately uninstall them all. I then go to invoke swift again under the assumption my default toolchain which was installed prior to swiftly would take precedence. Sounds like in this case that would not work because all the symlinks would still be proxying through swiftly which wouldn't be able to find a toolchain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, by installing swiftly you're giving it the ability to control which toolchain you are invoking. Note that since swiftly maintains its own record of toolchains it installed, any that you've installed previously wouldn't be known to swiftly since they could be in virtually any location on the system.
The user can take control temporarily by overriding their PATH to the external toolchain that they want to use, or uninstall swiftly.
Fix symlink target selection for swiftly when it is system managed
@swift-ci test macOS |
Note that macOS CI is failing in a way that is unrelated to the tests. The tests are all green:
|
@swift-ci test macOS |
@swift-ci test macOS |
DESIGN.md
Outdated
The `~/.local/bin` directory would include symlinks pointing to the `bin` directory of the "active" toolchain, if any. | ||
The `~/.local/bin` directory would include symlinks pointing to swiftly itself. When the proxies binaries are executed swiftly proxies them to the requested toolchain, or the default. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO we ought to be using ~/.swiftly/bin
for this. Swiftly doesn't own that directory and while it's fine to install the swiftly
command itself there (assuming it's being installed per-user rather than system-wide), I think it's very bad form installing "proxies" in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've changed this to put the proxies and swiftly itself into its own managed directory by default, which is ~/.local/share/swiftly/bin
. This matches what we do on macOS, except there we use a more typical macOS location ~/Library/Application Support/swiftly/bin
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
~/.local/bin
was originally chosen according to the XDG Base Directories specification, which is something of a standard for directories like this. While swiftly doesn't own ~/.local/bin
, it is the designated place to drop per-user executables according to that spec. Why would it be bad form to put our symlinks there?
https://specifications.freedesktop.org/basedir-spec/latest/
https://wiki.archlinux.org/title/XDG_Base_Directory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The concern is that the user might have swift toolchain, and other items (clang, lld, lldb, etc.) existing in the ~/.local/bin directory and swiftly will attempt to manage those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are really two reasons for this; the first is that, as @cmcgee1024 says, you might actually have Swift installed in ~/.local/bin
, in which case the proxies would then overwrite your Swift executables, which would be wrong. The second is that when using tools like swiftly
, there are situations where you want to bypass the proxies, and it's easiest to do that if they're in a separate bin
directory all of their own (since whether you're using the proxies or not is dependent on whether that bin
directory appears in your PATH
).
There is precedent here; pyenv
, rbenv
et al also put their shims (which we seem to be calling proxies) into a separate bin
directory for the same reasons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've changed this to put the proxies and swiftly itself into its own managed directory by default
I think swiftly
itself belongs in ~/.local/bin
or /usr/local/bin
or wherever the user installed it. It's just the proxies that should live elsewhere IMO. // @cmcgee1024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@al45tair swiftly is aware of two locations at the moment. There is the swiftly home dir, where its configuration lives, and the swiftly bin dir where all of the binaries that it manages live. I'm hesitant to add another location to the list.
In the Linux case ~/.local/bin
doesn't tend to be on the user's path, so swiftly finds itself adding it as part of augmenting the user's profile, being mindful of collisions with other packages that might attempt to do the same, or even the user themselves. There's no similar common CLT bin directory at a user level for macOS, so the swiftly bin directory is ~/Application Support/swiftly/bin
as the default. There's a far less likelihood of a path collision where something else that adds swiftly's managed bin directory. I think it makes sense to keep all of the binaries that swiftly manages (potentially itself too), separate from a shared binary location on all platforms as the default. The user can customize the paths if they want in the installer to change this, but then they are taking on more responsibility for the possibility of collisions.
Swiftly itself can be installed by a system package manager where it will probably be installed in one of the usual locations like /usr/bin
or /usr/local/bin
. The latter is where swiftly is installed using the macOS pkg file. The package manager manages these paths and the user's profile likely includes them in their path without extra handling by swiftly. In this case the swiftly bin directory is just the proxies that swiftly manages since it can't manage its own binary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong objection to that, I suppose, but it does mean that you can't use swiftly
without having the proxies in your path if you've let swiftly
install itself. At least, unless you make a symlink from ~/.local/bin
or similar.
DESIGN.md
Outdated
swiftly run make | ||
``` | ||
|
||
Swiftly adjusts certain environment variables, such as prefixing the PATH to the selected toolchain directory, and setting the CC and CXX variables to the locations of clang and clang++ in those toolchains so that the build tools use them. If you want to explicitly specify a toolchain for the command you can do that with a selector notation like this: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I don't think manipulating PATH
is a good idea. Swiftly should have its proxy bin
directory added to the path when it is installed, but should refrain from messing with PATH
thereafter. Similarly for CC
and CXX
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the setting of CC
and CXX
variables, opting instead to have the user provide those if they need them, copied verbatim along with the rest of their environment. The only environment changes is to the PATH
prepending the current toolchain, and leaving the rest of it untouched as the user had set previously.
Overriding the proxies in this case has the benefit of keeping this as a workaround for proxy performance issues. Also, this approach has pyenv
as a precedent, which is documented to be doing the exact same thing. https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-exec
|
||
The use subcommand also supports `.swift-version` files. If version file is present in the current working directory, or an ancestory directory, then swiftly will update that file with the new version to use. This can be a useful feature for a team to share and align on toolchain versions with git. As a special case, if swiftly could not find a version file, but it could find a Package.swift file it will create a new version file for you in the package and set that to the requested toolchain version. | ||
|
||
Note: The `.swift-version` file mechanisms can be overridden using the `--global-default` flag so that your swiftly installation's default toolchain can be set explicitly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pyenv
and rbenv
call this command local
, global
or shell
depending on whether you're setting the Python/Ruby version for a directory, globally on the machine (for your user), or just in the current shell. The shell setting overrides the local setting, which overrides the global setting.
… ones, giving a message about the shell Set only the PATH environment in swiftly run leaving CC and CXX to the user
@swift-ci test macOS |
@swift-ci test macOS |
@swift-ci test macOS |
The macOS tests are passing:
|
@swift-ci test macOS |
@al45tair @justice-adams-apple When you get a change, can you review the latest changes? |
@swift-ci test macOS |
@swift-ci test macOS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked carefully through the code changes to swiftly
itself, but I think the overall design seems fine. (I still have a slight reservation about the install location of the swiftly
binary itself, but it's relatively minor and easily fixed by the user with a symlink if they care.)
Add a design for the new swiftly proxy system for more flexible routing of command invocations to a toolchain.
Re-target the symbolic links that swiftly creates to point to swiftly itself, which can decide the selected toolchain more flexibly on a per-invocation basis.
Add support for reading the toolchain version from a
.swift-version
file if a selector isn't given. Theswiftly use
command will attempt to update a swift version file, or in certain circumstances it will create the version file for you. The specialswiftly install
with no selector argument that will attempt to install a toolchain version specified in a version file.Create a
swiftly run
subcommand that can run arbitrary commands, such as build scripts or makefile generators. This subcommand will set the PATH environment variable to the currently selected toolchain, and other special environment variables like CC and CXX to specifically point to the clang and clang++ executables. Add an ability for this subcommand to accept arbitrary toolchain selectors that take the higher precedence over the presence of the swift version file or the global default.Update
swiftly use
andswiftly list
to take into account that there is a global default, which is the fallback if there is no.swift-version
file, but also a potentially different toolchain that is in use in the current context. Theswiftly use
subcommand with not arguments will show in brackets the reason why the current in-use toolchain is selected, whether it is a special.swift-version
file in which case it will show the file path, or it is the global default.