CarthageRemoteCache
Centralized cache to serve Carthage frameworks. Useful for distributed CI setup with several build machines. It's aware of your xcodebuild
and swift
versions and builds on top of Carthage's .xyz.version
file mechanism.
Installation
The gem is published at rubygems.org, installation is as easy as:
$ gem install carthage_remote_cache
Note: Installing ri documentation for sinatra can be quite slow. Install with --no-rdoc --no-ri
if you don't want to wait.
Quickstart
- Run
carthagerc server
to start the cache on a remote server -
cd
to your project's root folder - Run
carthagerc init
to createCartrcfile
and point the server property to your running server URL - Assuming your
Carthage
directory is already built, runcarthagerc upload
to populate remote cache - Push your
Cartrcfile
and from a different machine runcartrcfile download
to fetch frameworks intoCarthage/Build/
folder - Build your app without having to wait for
carthage bootstrap
Usage
Init
Before running any other commands, it's required to initialize carthagerc
in your project directory by running:
$ carthagerc init
Which produces a Cartrcfile
. Configuration is done via plain ruby
code, so it is as simple as:
Configuration.setup do |c|
c.server = "http://localhost:9292/"
end
Cartrcfile
is supposed to be version controlled (e.g. included in git repository), so that it lives along your code and all consumers of the repository have access to same configuration.
Upload Workflow
Make sure that all your framework binaries have been built with carthage
, otherwise there is nothing to upload.
$ carthage bootstrap
Start the upload with:
$ carthagerc upload
After couple of seconds you should be able to see confirmation in terminal:
Uploaded 53 archives (97.2 MB), skipped 0.
Overwriting Existing Cache
Attempting to run carthagerc upload
again will not upload any framework binaries, since all of them are already present on the cache server:
Uploaded 0 archives (0.0 MB), skipped 53.
If your cache happens to be tainted by invalid framework binaries, you can overwrite existing cache with
$ carthagerc upload --force
Upgrading Xcode or Swift
It is recommended to always perform the upload workflow after upgrading Xcode and Swift versions since carthagerc
cached frameworks are not only bound to framework versions, but also to your build environment.
Download Workflow
Once the cache server has been populated with framework binaries, it's time to fetch frameworks from a different machine. Make sure to pull in Cartrcfile
from the repository before executing:
$ carthagerc download
You should expect to see the following output on a machine with empty Carthage
folder:
Downloaded and extracted 53 archives (97.2 MB), skipped 0 archives.
Your project should be ready for building.
Overwrite Local Carthage Folder
In case you happen to change a file in Carthage/Build
by accident, it's possible to force download all frameworks again with:
$ carthagerc download --force
Download Only Some Platforms
The example above downloaded all frameworks for all platforms (iOS, macOS, tvOS, watchOS). If large dependencies or network speed are an issue, you can download only a subset of the platforms by using the --platform
argument:
$ carthagerc download --platform iOS,macOS,tvOS,watchOS
Please note, that invoking the download
command multiple times with different platform arguments is not supported. The .version
file will "forget" that carthagerc
already downloaded the platform specified before the last download. If you need multiple platforms, specify them in a single download
command once, delimited with a comma.
Config
To get a quick overview on Xcode / Swift / Framework versions, execute
$ carthagerc config
Which will print similar information:
Xcodebuild: 9C40b
---
Swift: 4.0.3
---
Server: http://localhost:9292/
---
Cartfile.resolved:
github "kayak/attributions" "0.3"
---
Local Build Frameworks:
Attributions 0.3 [:iOS]
Verify Framework Versions
When switching between development branches, it's very easy to lose track of whether existing framework binaries in Carthage/Build
match version numbers from Cartfile.resolved
. As a result, you will probably lose several minutes of your development time, because Xcode
doesn't tell you about outdated or missing framework binaries.
Luckily, carthage_remote_cache
provides following command:
carthagerc verify
If existing frameworks match Cartfile.resolved
, script exits with 0
and doesn't print anything.
In the event of framework version mismatch, you'll be able to observe following output:
Detected differences between existing frameworks in 'Carthage/Build' and entries in 'Cartfile.resolved':
+-----------------+----------------+-------------------+
| Framework | Carthage/Build | Cartfile.resolved |
+-----------------+----------------+-------------------+
| CocoaLumberjack | 3.2.1 | 3.4.1 |
| PhoneNumberKit | 1.3.0 | 2.1.0 |
| HelloWorld | - | 3.0.0 |
+-----------------+----------------+-------------------+
To resolve the issue:
- run `carthagerc download` to fetch missing frameworks from the server.
- if the issue persists, run `carthage bootstrap` to build frameworks and `carthagerc upload` to populate the server.
Git Hook
Running carthagerc verify
manually on every git checkout / merge / pull could be quite cumbersome. To automate this task, integrate following script carthagerc-verify-githook into your repository's git hooks, e.g. post-checkout
.
See $ man githooks
for all available git hooks and their documentation.
Cache Server
Start the server with
$ carthagerc server
and browse to localhost:9292 where you should be able to see the default Welcome message.
Framework binaries will be stored in ~/.carthagerc_server
folder.
Server is bound to port 9292 by default. If you need to use different port, specify the port number via -pPORT
or --port=PORT
command line arguments, e.g.:
$ carthage server -p9000
$ carthage server --port=9000
Don't forget to change port number in your version controlled Cartrcfile
.
Version Compatibility
Before each carthagerc [upload|download]
, the script compares its version number against cache server. If the version doesn't match, carthagerc
aborts with:
Version mismatch:
Cache server version: 0.0.7
Client version: 0.0.6
Please use the same version as cache server is using by running:
$ gem install carthage_remote_cache -v 0.0.7
Please note, that this functionality only works with clients starting with version 0.0.6.
Directory Structure
Cache server stores version files and framework archives in following directory structure:
.carthagerc_server/
9C40b/ # Xcode version
4.0.3/ # Swift version
Framework1/
1.0.0/ # Framework1 version
.Framework1.version # Carthage .version file
Framework1-iOS.zip # Framework binary, dSYM and bcsymbolmap files
Framework1-macOS.zip
Framework1-tvOS.zip
Framework1-watchOS.zip
2.0.3/ # Framework1 version
.Framework1.version
Framework1-iOS.zip
Framework2/
v3.2/ # Framework2 version
.Framework2.version
Framework2-iOS.zip
It's safe to delete whole directories since no other metadata is stored.
Launch Agent
You can also run the cache server as a launch agent. Copy the template com.kayak.carthagerc.server.plist file to ~/Library/LaunchAgents
, change log
paths to include your username and run:
$ launchctl load -w ~/Library/LaunchAgents/com.kayak.carthagerc.server.plist
If you want to stop the agent, run:
$ launchctl unload ~/Library/LaunchAgents/com.kayak.carthagerc.server.plist
Check out official documentation on Launch Agents for more info.
Docker
To build an image based on the latest released gem, run
$ docker build -t carthagerc .
Afterwards you can run the image in a container using
$ docker run -d --publish 9292:9292 --name carthagerc carthagerc:latest
The server will now be available on port 9292 on localhost
. Note that the command above will cause any data added to ~/.carthagerc_server
to be written into the container layer. While this works, it's generally discouraged due to decreased performance and portability. To avoid this, you can use a volume.
$ docker run -d --publish 9292:9292 --mount "source=carthagerc,target=/root/.carthagerc_server" --name carthagerc carthagerc:latest
We also recommend adding the --log-opt
option to limit the size of logs, e.g. --log-opt max-size=50m
.
To inspect the logs after running, use
$ docker logs carthagerc
To stop the container, run
$ docker container stop carthagerc
Version
$ carthagerc version
Help
Documentation is also available when running carthagerc
or carthagerc --help
. Both commands print list of available commands with brief description.
carthagerc COMMAND [OPTIONS]
...
COMMANDS
config
print environment information and Cartrcfile configuration
download [-f|--force] [-v|--verbose] [-mPLATFORM|--platform=PLATFORM]
fetch missing frameworks into Carthage/Build
init
create initial Cartrcfile in current directory
upload [-f|--force] [-v|--verbose]
archive frameworks in Carthage/Build and upload them to the server
server [-pPORT|--port=PORT]
start cache server
verify
compare versions from Cartfile.resolved to existing frameworks in Carthage/Build
version
print current version number
OPTIONS
-f, --force Force upload/download of framework archives even if local and server .version files match
-h, --help Show help
-m, --platform=PLATFORM Comma delimited list of platforms which should be downloaded from the server; e.g. `--platform iOS,macOS`; Supported values: iOS, macOS, tvOS, watchOS
-n, --no-retry Don't retry download or upload on network failures
-p, --port=PORT Server application port used when starting server, default port is 9292
-v, --verbose Show extra runtime information
Development
Setup
After checking out the repo, run dev/setup
to install dependencies. You can also run dev/console
for an interactive prompt that will allow you to experiment.
Development Server
To start development server, run dev/start_server
, which utilizes rerun
for automatic reloading of source code and resources.
Tests
Execute unit tests with rake test
or start monitoring directories for changes with bundle exec guard
.
Source Code Format
Before committing, make sure to auto-format source code wit rake format
.
Gem Lifecycle
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Experiments With Example Folder
Repository is bundled with an example Carthage setup for your experiments. Open the example folder, where you should be able to see following files, which are preconfigured to bring in a couple of frameworks:
- Cartfile
- Cartfile.resolved
- Cartrcfile
Make sure to build these dependencies with carthage bootstrap
before attempting to upload them.
Try out a few commands:
$ carthagerc config
$ carthagerc upload
$ carthagerc download
License
The gem is available as open source under the terms of the Apache 2.0 License.