-
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
Changes from 5 commits
e4efbeb
3b5c404
956256f
375df29
ed68a9e
c745f4c
560236d
ae29e88
ce0d27a
66dd459
2df7357
8976bba
3caab66
31f4327
16caf80
b2aa165
7504dd3
0e7b661
43d620a
2e3c59d
9dd640c
5e615ea
10a0856
6d6050e
6989796
52d081f
2f6d701
cb0e923
bb36de0
7269128
35cb5c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -4,21 +4,28 @@ This document contains the high level design of swiftly. Not all features have b | |||||
|
||||||
## Index | ||||||
|
||||||
- [Swiftly's purpose](#swiftlys-purpose) | ||||||
- [Installation of swiftly](#installation-of-switly) | ||||||
- [Linux](#linux) | ||||||
- [Installation of swiftly](#installation-of-swiftly) | ||||||
- [Installation of a Swift toolchain](#installation-of-a-swift-toolchain) | ||||||
- [macOS](#macos) | ||||||
- [Installation of swiftly](#installation-of-swiftly-1) | ||||||
- [Installation of a Swift toolchain](#installation-of-a-swift-toolchain-1) | ||||||
- [Interface](#interface) | ||||||
- [Toolchain names and versions](#toolchain-names-and-versions) | ||||||
- [Commands](#commands) | ||||||
- [Toolchain selection](#toolchain-selection) | ||||||
- [Detailed design](#detailed-design) | ||||||
- [Implementation sketch - Core](#implementation-sketch---core) | ||||||
- [Implementation sketch - Ubuntu 20.04](#implementation-sketch---ubuntu-2004) | ||||||
- [Implementation sketch - macOS](#implementation-sketch---macos) | ||||||
- [`config.json` schema](#configjson-schema) | ||||||
|
||||||
## Swiftly's purpose | ||||||
|
||||||
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. | ||||||
|
||||||
## Installation of swiftly | ||||||
|
||||||
The installation of swiftly is divided into two phases: delivery and initialization. Delivery of the swiftly binary can be accomplished using different methods: | ||||||
|
@@ -60,7 +67,7 @@ A simple setup for managing the toolchains could look like this: | |||||
|
||||||
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. | ||||||
|
||||||
|
||||||
This is all very similar to how rustup does things, but I figure there's no need to reinvent the wheel here. | ||||||
|
||||||
|
@@ -78,7 +85,7 @@ The contents of `~/Library/Application Support/swiftly` would look like this: | |||||
– env | ||||||
``` | ||||||
|
||||||
Instead of downloading tarballs containing the toolchains and storing them directly in `~/.local/share/swiftly/toolchains`, we instead install Swift toolchains to `~/Library/Developer/Toolchains` via the `.pkg` files provided for download at swift.org. To select a toolchain for use, we update the symlinks at `~/Library/Application Support/swiftly/bin` to point to the desired toolchain in `~/Library/Developer/Toolchains`. In the env file, we’ll contain a line that looks like `export PATH="$HOME/Library/Application Support/swiftly:$PATH"`, so the version of swift being used will automatically always be from the active toolchain. `config.json` will contain version information about the selected toolchain as well as its actual location on disk. | ||||||
Instead of downloading tarballs containing the toolchains and storing them directly in `~/.local/share/swiftly/toolchains`, we instead install Swift toolchains to `~/Library/Developer/Toolchains` via the `.pkg` files provided for download at swift.org. In the env file, we’ll add a line that looks like `export PATH="$HOME/Library/Application Support/swiftly:$PATH"`, so that swiftly can proxy toolchain commands to the requested toolchain, or default. `config.json` will contain version information about the selected toolchain as well as its actual location on disk. | ||||||
|
||||||
This scheme works for ensuring the version of Swift used on the command line can be controlled, but it doesn’t affect the active toolchain used by Xcode, which uses its own mechanisms for that. Xcode, if it is installed, can find the toolchains installed by swiftly. | ||||||
|
||||||
|
@@ -138,6 +145,14 @@ Installing a specific snapshot from a swift version development branch | |||||
|
||||||
`swiftly install 5.5-snapshot-2022-1-28` | ||||||
|
||||||
##### Installing the version from the `.swift-version` file | ||||||
|
||||||
A package could have a swift version file that specifies the recommended toolchain version. A swiftly install with no version will search for a version file and install that version. | ||||||
|
||||||
`swiftly install` | ||||||
|
||||||
If no swift version file can be found then the installation fails indicating that it couldn't fine the file. | ||||||
|
||||||
|
||||||
#### uninstall | ||||||
|
||||||
Uninstalling versions of Swift should be in a similar form to install. Uninstalling a toolchain that is currently “in use” (see the “use” command section below) will cause swiftly to use the latest Swift release toolchain that is installed. If none are, the latest snapshot will be used. If no snapshots are installed either, then a message will be printed indicating that all Swift versions are uninstalled. | ||||||
|
@@ -178,7 +193,7 @@ To list all the versions of swift installed on your system | |||||
|
||||||
#### use | ||||||
|
||||||
“Using” a toolchain sets it as the active toolchain, meaning it will be the one found via $PATH and invoked via `swift` commands executed in the shell. Only a single toolchain can be used at a given time. Using a toolchain doesn’t uninstall anything; it only updates symlinks so that the requested toolchain can be found by the shell. | ||||||
“Using” a toolchain sets it as the default toolchain, meaning it will be the default one that is used when running toolchain commands from the shell. Only a single toolchain can be the default at a given time and location. Using a toolchain doesn’t uninstall anything; it only updates the configuration. | ||||||
|
||||||
To use the toolchain associated with the most up-to-date Swift version, the “latest” version can be specified: | ||||||
|
||||||
|
@@ -208,6 +223,10 @@ To use the latest installed main snapshot, leave off the date: | |||||
|
||||||
`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. | ||||||
|
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
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.
Outdated
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.
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