Giter Site home page Giter Site logo

xcodesorg / xcodes Goto Github PK

View Code? Open in Web Editor NEW
3.5K 29.0 108.0 1019 KB

The best command-line tool to install and switch between multiple versions of Xcode.

License: MIT License

Swift 86.37% Makefile 0.44% HTML 13.08% Shell 0.11%
xcode swift macos hacktoberfest

xcodes's Introduction

xcodes

The best command-line tool to install and switch between multiple versions of Xcode.

If you're looking for an app version of xcodes, try Xcodes.app.

CI Status

Header Image

🎉 Announcment

Xcodes is now part of the XcodesOrg - read more here

Installation

Homebrew (Preferred)

brew install xcodesorg/made/xcodes

These are Developer ID-signed and notarized release builds and don't require Xcode to already be installed in order to use.

Other methods:

Download a release

Download the latest release from the Releases page. These are Developer ID-signed release builds and don't require Xcode to already be installed in order to use.

Using Mint
mint install XcodesOrg/xcodes
Build from source

Building from source requires Xcode 12.0 or later, so it's not an option for setting up a computer from scratch.

git clone https://github.com/XcodesOrg/xcodes
cd xcodes
make install
# or, if /usr/local/ isn't in your PATH
PREFIX=/your/install/directory make install

While installing, you may get the following output:

swift build
error: terminated(72): xcrun --sdk macosx --find xctest output:

If that occurs, it means you need to select a version of Xcode. You can do this with xcode-select or by choosing a Command Line Tools option in Xcode's preferences Locations tab.

Usage

Install Xcode :

Install a specific version of Xcode using a command like one of these:

xcodes install 10.2.1
xcodes install 11 Beta 7
xcodes install 11.2 GM seed
xcodes install 9.0 --path ~/Archive/Xcode_9.xip
xcodes install --latest-prerelease
xcodes install --latest --directory "/Volumes/Bag Of Holding/"
xcodes install --latest --experimental-unxip

You'll then be prompted to enter your Apple ID username and password. You can also provide these with the XCODES_USERNAME and XCODES_PASSWORD environment variables.

After successfully authenticating, xcodes will save your Apple ID password into the keychain and will remember your Apple ID for future use. If you need to use a different Apple ID than the one that's remembered, set the XCODES_USERNAME environment variable.

xcodes will download and install the version you asked for so that it's ready to use.

(1/6) Downloading Xcode 11.2.0: 100%
(2/6) Unarchiving Xcode (This can take a while)
(3/6) Moving Xcode to /Applications/Xcode-11.2.0.app
(4/6) Moving Xcode archive Xcode-11.2.0.xip to the Trash
(5/6) Checking security assessment and code signing
(6/6) Finishing installation
xcodes requires superuser privileges in order to finish installation.
macOS User Password:

Xcode 11.2.0 has been installed to /Applications/Xcode-11.2.0.app

If you have aria2 installed (it's available in Homebrew, brew install aria2), then xcodes will default to use it for downloads. It uses up to 16 connections to download Xcode 3-5x faster than URLSession.

Xcode will be installed to /Applications by default, but you can provide the path to a different directory with the --directory option or the XCODES_DIRECTORY environment variable. All of the xcodes commands support this option, like select and uninstall, so you can manage Xcode versions that aren't in /Applications. xcodes supports having all of your Xcode versions installed in one directory, wherever that may be.

Install Runtimes :

Run this command line to display the available runtimes

xcodes runtimes --include-betas

Install the wanted Runtime (ex. iOS 17.0-beta1)

xcodes runtimes install "iOS 17.0-beta1"

.xcode-version

We recommend the creation of a .xcode-version file to explicitly declare and store the Xcode version to be used by your CI environment as well as your team.

13.4.1

Read the proposal of .xcode-version.

Commands

  • download <version>: Download a specific version of Xcode
  • install <version>: Download and install a specific version of Xcode
  • installed: List the versions of Xcode that are installed
  • list: List all versions of Xcode that are available to install
  • select: Change the selected Xcode
  • uninstall: Uninstall a specific version of Xcode
  • update: Update the list of available versions of Xcode
  • version: Print the version number of xcodes itself
  • signout: Clears the stored username and password

Experimental Unxip - for faster unxipping

Thanks to the amazing work by saagarjhi - Xcodes now includes the ability to unxip up to 70% faster on some systems.

xcodes install --latest --experimental-unxip

Shell Completion Scripts

xcodes can generate completion scripts which allow you to press the tab key on your keyboard to autocomplete commands and arguments when typing an xcodes command. The steps to install a completion script depend on the shell that you use. More information about installation instructions for different shells and the underlying implementation is available in the swift-argument-parser repo.

Zsh, with oh-my-zsh:

Run the following commands:

mkdir ~/.oh-my-zsh/completions
xcodes --generate-completion-script > ~/.oh-my-zsh/completions/_xcodes

Development

You'll need Xcode 13 in order to build and run xcodes.

Using Xcode Even though xcodes is a command-line app, all of the normal functionality works in Xcode, like building, running, and running tests. You can even type text into Xcode's console when it prompts you for input like your Apple ID or 2FA code.

When running xcodes from Xcode, if you want to run a particular command or pass some arguments, you can hold the option key to present a sheet with more options. This means you'd use Option + Command + R or hold Option while clicking the Run button. Here you can add, remove, and toggle arguments that will be passed to xcodes when it's launched.

Xcode Edit Scheme Screen

Using Swift command line tools You can also use the Swift command line tools once you have Xcode installed:
  • Build: swift build
  • Run: swift run, or commands like swift run xcodes list
  • Run tests: swift test

There's a Makefile to help build xcodes for distribution. We already do this for you in order to provide Developer ID-signed and notarized release builds via Homebrew (see Installation).

Releasing a new version of xcodes
# Bump the version number in Version.swift, commit the change, and tag it
vim Sources/XcodesKit/Version.swift
git add Sources/XcodesKit/Version.swift
git commit -m "Bump version to $VERSION"
git tag -asm "$VERSION" "$VERSION"

# Clean first
make clean

# Make a release build of xcodes, sign it, and zip it
make zip
# Create a Homebrew bottle
make bottle VERSION="$VERSION"

# Notarize the release build
# This can take a while
make notarize \
    TEAMID="ABC123"

# Push the new version bump commit and tag
git push --follow-tags

# Edit the draft release created by Release Drafter to point at the new tag
# Set the release title to the new version
# Add the xcodes.zip and xcodes-$VERSION.mojave.tar.gz files to the release
# Publish the release

# Update the Homebrew Bottle: https://github.com/XcodesOrg/homebrew-made/blob/master/Formula/xcodes.rb

Notable design decisions are recorded in DECISIONS.md. The Apple authentication flow is described in Apple.paw, which will allow you to play with the API endpoints that are involved using the Paw app.

xcode-install and fastlane/spaceship both deserve credit for figuring out the hard parts of what makes this possible.

Maintainers

Matt Kiazyk - Twitter

xcodes's People

Contributors

adamprice avatar ahmetgeymen avatar art-divin avatar ccarpita avatar dependabot[bot] avatar dmytro-kasianchuk-doordash avatar dylanbettermanndd avatar ffittschen avatar fishcharlie avatar florentmorin avatar garrettmoon avatar interstateone avatar jpsim avatar juanjonol avatar kemchenj avatar krzyzanowskim avatar mattkiazyk avatar ninjalikescheez avatar nscoder avatar pakko972 avatar pastey avatar rogerluan avatar rpendleton avatar stephengazzard avatar stevensorial avatar tahirmt avatar thepredators avatar thii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xcodes's Issues

Output more information about current step and progress in install process

Should print the following steps for the install command:

  • Downloading, with progress as a percentage, if the archive is being downloaded. If installing from an archive URL, print that this is occurring as a confirmation of the use of the --url flag.
  • Unarchiving, with a note that this can take a while. If it's possible to output some sort of indeterminate activity indicator, do that. I don't necessarily want to use PackageKit without more investigation, so that could be a separate issue if not done here.
  • Moving unarchived Xcode to /Applications
  • Moving archive to Trash
  • Performing security/signing validation
  • Enable developer mode
  • Approve license
  • Install components

Don't abort installation when Xcode fails spctl check

Proposal: Clearly output the results of running spctl --assess but don't let failures abort the install process.

FB6142402: spctl rejects Xcode 11 beta 1 because of invalid symbolic link destination

I have mixed feelings about doing this, and we should wait until Xcode 11 GM to see if Apple resolves this before implementing a change.

Benefits: Easier to use xcodes because installation steps will continue automatically even if Xcode fails spctl --assess. All Xcode 11 betas through 4 have failed this command.
Always showing failures for otherwise valid Xcodes teaches users to ignore the failures.

Drawbacks: Ignores Apple's own guidance, increases security risks. Showing the failures and continuing might still teach users to ignore the failures...

GM seed versions aren't parsed correctly and prevent more than one from being installed

Version+Xcode.swift supports "GM" but not "GM Seed", or any multi-word prerelease type. This results in output like:

$ xcodes list
# ...
11.0 Gm (11A420a)
11.0 Gm (11A419c) (Installed)

where the first is GM seed 2 and the second is GM seed 1.

I would expect this to instead output something like:

$ xcodes list
# ...
11.0 GM Seed 2 (11A420a)
11.0 GM Seed 1 (11A419c) (Installed)

The current behaviour also prevents installing more than one GM seed because installation doesn't compare build metadata (intentionally, because it isn't always available). They need to have unique prerelease identifiers.

Check for .xip in expected location when installing

If xcodes fails to install at any point after downloading a .xip, subsequent uses of the install command should automatically check to see if a .xip for the requested version exists at the expected path before downloading the .xip.

This should not occur if the --url argument is provided.

Improve error message if user signs in with Apple ID that isn't a developer

Not sure of the details of this yet, but had a user that was running xcodes update, signing in successfully, then got this error output:

The operation couldn't be completed. (DecodingError.keyNotFound(CodingKeys(stringValue: "downloads", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"downloads\", intValue: nil) (\"downloads\").", underlyingError: nil)))

The error message seems to indicate that parsing the downloads JSON failed because the session was invalid.

It turns out their Apple ID wasn't a developer account. Need to investigate if this means "doesn't have a valid ADC membership" or something else.

[Feature request] Store username in config/cache after every successful login

Currently, users have to enter their Apple ID username or specify XCODES_USERNAME environment variable every time they run the xcodes update or xcodes install commands (and also xcodes list for the first time). This feature will eliminate the need of asking users to type in their username every time.

Implementation details

  • If a username isn't specified with the XCODES_USERNAME environment variable, and there is no
    username saved, prompt the user for a username.
    • If the login succeeds, then save the username.
    • If the login fails, don't save the username.
  • If a username isn't specified with the XCODES_USERNAME environment variable, and there is a username saved, use that username for login and don't prompt the user for a username.
  • If a username is specified with the XCODES_USERNAME environment variable, use that username for login (don't check for a saved username, don't prompt the user for a username).
    • If the login succeeds, then save the username.
    • If the login fails, don't save the username.

Ensure that error output from shell commands is printed

I've hit this a few times when the xip command is unarchiving because I've run out of disk space. xcodes currently prints that an error occurred (don't have it handy to paste here) but not the exact underlying error. The xip command does print this itself though, so xcodes probably just needs to capture standard output or standard error data and print it.

A change that resolves issue this should make sure that all shell commands have this behaviour.

Swift 5.1 and Xcode 11

Resolving this should:

  • perform only enough code changes to make things work, silence warnings, etc.
  • Update .gitignore so we can commit the .swiftpm directory without shared user data
  • Remove .vscode directory
  • Update .swift-version file
  • Update Package.swift
  • CI workflow should be run using Xcode 11

This scope doesn't include a rewrite to use Combine or anything like that.

Print the path of installed versions when running the installed command

The current behaviour prints the versions that are installed:

$ xcodes installed
12.2
12.3 (Selected)
12.4 Release Candidate (12D4e)

It may be useful to also print the path they're installed at, perhaps like:

$ xcodes installed
12.2	/Applications/Xcode-12.2.0.app
12.3 (Selected)	/Applications/Xcode-12.3.0.app
12.4 Release Candidate (12D4e)	/Applications/Xcode-12.4.0-release.candidate.app

There should be a tab character in between the current output and the path so it's easier to split the lines into their components. For example, you could get a specific path with:

$ xcodes installed | \ # get all installed versions and their paths
    grep 12.2 | \ # get the line for version 12.2
    cut -d$'\t' -f2 # split by tab character, return second field
/Applications/Xcode-12.2.0.app

GitHub Action CI workflow doesn't show resulting status in PRs from forks

The workflow runs in the forks (which also requires that they have access to Actions as a feature), not this repo, and this is deliberate. CircleCI allows you to run CI on PRs from forks. We need to investigate if there's a workaround for this behaviour and potentially switch back to Circle so that we can see CI statuses on all PRs.

Update Keychain Access > 3.1.3 to fix warning

KeychainAccess has a warning on build. Update to > 3.1.3 to fix

warning: PackageDescription API v3 is deprecated and will be removed in the future; used by package(s): KeychainAccess

Improve pre-release version comparison

See release 0.3.1 and acd05f9. Ideally the output of xcodes installed and xcodes list would be more precise to reflect the installed and available pre-release versions. Need to check if there's enough info available before downloading a pre-release version and in an installed Info.plist to do this.

Pre-release builds publish a product version on developer.apple.com/downloads, e.g. Xcode 11 Beta 1 is 11M336W. The app bundle contains a file at Contents/version.plist and the value for ProductBuildVersion matches this, although it should be compared case-insensitively because it is 11M336w.

Document syntax for downloading beta/GM seeds

It's not inherently clear how to download a GM seed from xcodes.
I tried a bunch of different ways before landing upon xcodes install 11.2.1GM\ Seed.

image

It would be great if you could add an example for downloading a beta and a GM seed to --help and to the repo's readme. I'm sure I'm not the only one who had to try a bunch of different things to figure it out.

Download errors should provide more information

$ xcodes install 11.2.1 GM seed
Downloading Xcode 11.2.1-gm-seed+11B53: 58%
The operation couldn’t be completed. (NSPOSIXErrorDomain.28)

This error code corresponds to "No space left on device". xcodes should be printing the localized error description in this situation.

Xcode 11 beta

I did xcodes update and then xcodes list and I do not see the 11 beta. I do see it when I use xcversion. It would seem that this might be a regression as #6 implies that this was once added.

Downloading % goes past 100%

Because math. But seriously - I'm not sure if it was because my laptop was going to sleep when I closed the lid or what. The download eventually failed.

Screenshot 2019-10-29 20 54 13

Cookies aren't being persisted to disk in time for app exit

The result of this is that subsequent runs will always prompt for re-auth because olympus returns a 401.

I don't think there's anything available in the HTTPCookieStorage API to force it to write to disk in time, and the cookies will eventually need to be in a shared location if Client will be used for more than just downloading Xcodes. Might be better to jump to implementing something similar to Spaceship's use of https://github.com/sparklemotion/http-cookie

Allow .xip to be persisted after install

I made the mistake of leaving Xcode 11b3 on my machine when Xcode11b4 was being installed and ended up with Xcode 11b4 thinking that it contained modules with the wrong version of Swift.

I'm on a very poor network connection (hotel) and instead of unarchiving the previously downloaded .xip I have to redownload.

It may be useful to have a --preserveXIP option where the .xip will be revealed in the finder for someone to store for future use.

Xcode 11 betas are listed twice because they're included on the beta and release download sites

The actual output of running xcodes update is:

❯ xcodes update  
...
11.0 Beta 5 (11M382q) (Installed)
11.0 Beta 6 (11M392q) (Installed)
11.0 Beta 7 (11M392r)
11.0
11.0

The expected output would be for the list to end with:

11.0 Beta 5 (11M382q) (Installed)
11.0 Beta 6 (11M392q) (Installed)
11.0 Beta 7 (11M392r)

The reason this is happening is because Xcode 11 betas 6 and 7 are listed on developer.apple.com/download and developer.apple.com/download/more. The latter was previously reserved for non-beta releases of Xcode, and xcodes operates on that assumption.

The list on developer.apple.com/download/more does list the betas as "Xcode 11 beta 6" and "Xcode 11 beta 7", so it should be possible to parse this and de-duplicate the available Xcodes. Might be worth waiting to see what happens after the Xcode 11 GM release in case this was accidental.

Add `switch` command as a proxy to `xcode-select`

I find the standard xcode-select invocations very verbose and easy to get wrong. Can you please add a switch subcommand to xcodes, which would call xcode-select and pass a path to the xcode version requested by the user? Thanks.

Resume an incomplete download

I'm not sure that URLSessionDownloadTask's resume functionality is going to handle the situation where xcodes gets a SIGKILL or something, because it requires resume data to resume, but you only get that from the session delegate method. Might want to do what xcode-install does and install to a known location and be able to resume from the bytes that have been downloaded already. libcurl probably fits this use case better. On the other hand, xcodes could probably use resume data to be resilient against some connection issues.

Test coverage for authentication

At a high level this should involve pushing some of the code in main.swift into the XcodesKit module so that it can be tested without invoking xcodes.

Notarize xcodes binaries

We should notarize xcodes binaries that we release.

I don't think this is possible yet. The only way to distribute a notarized standalone binary is by packaging it in a disk image or installer package.

Although tickets are created for standalone binaries, it’s not currently possible to staple tickets to them.

Customizing the Notarization Workflow

man stapler
# ...
SUPPORTED FILE FORMATS
    stapler works only with UDIF disk images, signed "flat" installer packages, and certain code-signed executable bundles such as ".app".

As far as I know these file formats won't work with Homebrew bottles, which expect a gzipped tarball.

Bottles are simple gzipped tarballs of compiled binaries.

– Bottles

I'm not sure if this would work, and it feels like bending the intended use of Homebrew, but it might be worth exploring a non-bottle formula that simply installs the pre-built and stapled binary. Another option might be to convert to distributing via a cask in our own tap. I like this least because I don't think there's a migration story from a formula to a cask. It's also not really the intended use of casks, because xcodes is a standalone binary. FAQ: Rejected Casks

Different beta versions installed to the same location

When I installed Xcode 11 beta 2 it replaced the previously installed Xcode 11 beta 1 at /Applications/Xcode-11.0.0-beta. (xcode-install does keep each beta version separately)

It would be nice to keep the previously installed beta versions as is. The old betas are removed from the Apple website when the new beta is available, and sometimes there are new issues with the latest beta so being able to switch back would be nice (happened to us last year with Xcode 10 beta 5).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.