Skip to content

Instantly share code, notes, and snippets.

@KoCMoHaBTa
Last active July 19, 2018 15:52
Show Gist options
  • Save KoCMoHaBTa/455df6a19f91e62b4e02ef8e68fb395d to your computer and use it in GitHub Desktop.
Save KoCMoHaBTa/455df6a19f91e62b4e02ef8e68fb395d to your computer and use it in GitHub Desktop.
Carthage Integration

Carthage Integration

A common, safe and flexible way to setup carthage for your project.

What you need:

Working Directory

First of all, you will need a working directyory for carthage. The most common place for this is your project root directory. However i would recommend to create a subdirectory and use it in order to keep the project structure clean. You can name as you want or for example Libraries, lib, libs.

Integration (using checkout references)

There are multiple ways to integrate Carthage, but in this section, I will describe the way of using cehckout references

After you have chosen your working directory, follow these steps to integrate Carthage into it:

Basic setup
  1. Create a Cartfile and add some dependencies to it.
  2. execute the following command carthage update --no-build - this will checkout all dependencies into a Carthage directory and create a Cartfile.resolved file.
  3. Ignore the Carthage directory from your git repository (you can copy the provided .gitignore file to your project root directory)
  4. Add Cartfile.resolved to your git repository
  5. Link the dependencies to your project (for more info look at Adding carthage dependency
Unmanaged dependencies

If you need to have other dependencies, that are not managed by Carthage and keep the project structure clean, you can create a folder Unmanaged to keep them there.

Automation setup

Sometimes it is easier to automate and protect few steps, just for convenience. If you want to do this, follow these steps:

  1. Add the provided scripts to your carthage working directory and commit them in your git repository
  2. Add new Run Script Phase to your project and call check_dependencies.sh from there
  3. run update_dependencies.sh
  4. build your project once more
  5. Ignore from your git repository the auto generated perform_dependency_check and Cartfile.resolved.state
Final working directory and project structure

At the end you should end up with somethign like this:

  • Cartfile - this is the Carthage configuration file, representing all dependencies
  • Cartfile.resolved - this is the Carthage configuration file, representing the current state of all dependencies. This file is autogenerated after you resolve your dependencies with carthage and should not be modified by hand.
  • resolve_dependencies.sh - this script resolves all dependencies to their current state.
  • update_dependencies.sh - this script updates all dependencies to latest version, according the Cartfile.
  • check_dependencies.sh - this script checks if dependencies needs to be updated.
  • configure_dependencies.rb - this script modifies all open source dependency project settings and perform configuration in order to reduce noise.
  • Carthage directory - this is the folder where all dependencies are stored upon resolution. This directory is automatically created and maintained by Carthage. This directory should not be commited into the repository and is explicitly ignored.
  • Carthage group - this is the group that wraps all dependency references. This group is only logical.
  • Unmanaged directory - this is the location where all unmanaged dependencies are physically and logically placed.

Carthage directory and Carthage group appears in the same location, but they do not represent the same thing. The group is intended to only wrap carthage managed references, where the folder contains the physical dependencies and is managed by Carthage itself.

Adding carthage dependency (using cehckout reference)

  1. Add the dependency to the configuration file
  2. Run update_dependencies.sh script
  3. Drag & Drop the project file (reference) to the Libraries folder (next to the other references)
  4. For every target:
    • add it to Target Dependencies build phase
    • add it to Link Binary With Libraries build phase
    • if it is an embedded framework - add it to Embedded Binaries in the General tab
  5. Make sure that
    • everytihng is working correctly
    • you are not commiting the contents of the Carthage folder
    • you are commiting the Carthage configuration files
  6. Instruct other team members to resolve their dependencies.

Removing carthage dependency

  1. Remove the dependency project reference from the project
  2. Remove the dependency entry from Cartfile
  3. Remove the dependency entry from Cartfile.resolved or run update_dependencies.sh
#Contents are based on:
#https://github.com/github/gitignore/blob/master/Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xcuserstate
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
## Legacy
.svn
.DS_Store
## Custom
Libraries/Carthage/
Libraries/perform_dependency_check
Libraries/Cartfile.resolved.state
*.log
*.xcscmblueprint
#!/bin/bash
#Use this script to check if dependencies needs to be updated
#exit codes:
# 0 - OK
# 1 - Missing dependency state
# 2 - Dependencies changed
#some vars
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
LIB_DIR="$SCRIPT_DIR"
#check if dependency check should be executed - it is not nececary when running from CI/CD tool
if [ ! -f $LIB_DIR/perform_dependency_check ]; then
exit 0
fi
#check if there is no sha calculated for Cartfile.resolved.state - this usually happens when the repository is freshly cloned
if [ ! -f $LIB_DIR/Cartfile.resolved.state ]; then
echo "${BASH_SOURCE[0]}:${LINENO}: error: Missing dependency state - you must resolve dependencies first."
exit 1
fi
#calcualte sha of Cartfile.resolved.state
CARTFILE_RESOLVED_STATE_SHA=$(openssl sha1 $LIB_DIR/Cartfile.resolved.state | awk '{print $2}')
#calcualte sha of Cartfile.resolved
CARTFILE_RESOLVED_SHA=$(openssl sha1 $LIB_DIR/Cartfile.resolved | awk '{print $2}')
#check if the sha calculated for Cartfile.resolved.state differs from the Cartfile.resolved - this usually hapens when dependencies were changed
if [ "$CARTFILE_RESOLVED_STATE_SHA" != "$CARTFILE_RESOLVED_SHA" ]; then
echo "${BASH_SOURCE[0]}:${LINENO}: error: Dependencies changed - you must resolve dependencies."
exit 2
fi
#everything is just fine
exit 0
#!/usr/bin/ruby
require 'xcodeproj'
#modifies every open source dependency project file
#the intention of this script is to reduce open source libs noise
#and optionally and eventually fine tune their settings if needed
folder = "#{File.dirname(__FILE__)}/Carthage/Checkouts"
xcode_project_file_paths = Dir.glob("#{folder}/**/*.xcodeproj")
xcode_project_file_paths.each do |project_path|
project = Xcodeproj::Project.open(project_path)
puts File.basename(project_path, ".xcodeproj") + " configured."
project.build_configurations.each do |config|
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] ||= 'YES'
config.build_settings['RUN_CLANG_STATIC_ANALYZER'] ||= 'NO'
end
project.save
end
#!/bin/bash
#Use this script when in order to resolve all dependencies to the latest state, as defined in the Cartfile.resolved, when:
# - you have just downloaded the project and you are missing all dependencies
# - dependencies have been updated and you have old versions of them
#some vars
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
LIB_DIR="$SCRIPT_DIR"
#importing /etc/paths
while read p; do
echo $p
export PATH=$p:$PATH
done < /etc/paths
#check if carthage is installed
if ! type "carthage" > /dev/null; then
>&2 echo "${BASH_SOURCE[0]}: line ${LINENO}: error: Carthage is required in order to resolve dependencies. Please install and add Carthage to /etc/paths"
exit 1
fi
#resolve dependencies
carthage checkout --project-directory $LIB_DIR
#configure dependencies
$LIB_DIR/configure_dependencies.rb
#copy the latest depencies state - used by check_dependencies.sh
touch $LIB_DIR/perform_dependency_check
cp $LIB_DIR/Cartfile.resolved $LIB_DIR/Cartfile.resolved.state
#!/bin/bash
#Use this scrip in order to update all dependencies to latest version, as defined in the Cartfile
#some vars
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
LIB_DIR="$SCRIPT_DIR"
#importing /etc/paths
while read p; do
echo $p
export PATH=$p:$PATH
done < /etc/paths
#check if carthage is installed
if ! type "carthage" > /dev/null; then
>&2 echo "${BASH_SOURCE[0]}: line ${LINENO}: error: Carthage is required in order to resolve dependencies. Please install and add Carthage to /etc/paths"
exit 1
fi
#resolve dependencies
carthage update --no-build --project-directory $LIB_DIR
#configure dependencies
$LIB_DIR/configure_dependencies.rb
#copy the latest depencies state - used by check_dependencies.sh
touch $LIB_DIR/perform_dependency_check
cp $LIB_DIR/Cartfile.resolved $LIB_DIR/Cartfile.resolved.state
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment