carthage_remote_cache 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d396754d9d36f42ce94e959a2a79060edcd08e62
4
- data.tar.gz: 16d69bfae6cd53c5465a7e92e398c7243acfbf33
3
+ metadata.gz: 99a24b3d5f791bcaeb20e54585407e069cef1315
4
+ data.tar.gz: f2142c1579c0be86a434b7145d6d0598724bb29d
5
5
  SHA512:
6
- metadata.gz: 0b3972b131d66bd5bd9bf6be8be8ebc037b72ee59dba515761db2d3c088851199deeeb9ef01a5e927af5d676879318a55ee2e322d9282a17e77f839966862a29
7
- data.tar.gz: bb6bc109ba2c95587e585d4577ac3bcb030a6a2d84b1b4d078a276c23da664277e97205d7a87a95f6a96c16465f9471c0371f64dab15ec4ee2c3bbbbc88a55af
6
+ metadata.gz: 959084abe1f980e686068760c818f4b138e03075cc88667fc47ea875dab38ab7eb21c5e5a94bb775654e2558a2aa98ed07126e89c4cbadfbb02b456d604494fb
7
+ data.tar.gz: 4469e11a247c273fc956ed1afac2d6f76a3404d6ee7a24ab387c9d2a1c0145868255b5af2c68f9417b0b1f1c222e5ebe27bfe65704133f118bd2cc48d0561052
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- carthage_remote_cache (0.0.2)
4
+ carthage_remote_cache (0.0.3)
5
5
  concurrent-ruby (~> 1.0.5)
6
6
  rack (~> 2.0.4)
7
7
  rest-client (~> 2.0.2)
@@ -47,7 +47,7 @@ GEM
47
47
  tilt (2.0.8)
48
48
  unf (0.1.4)
49
49
  unf_ext
50
- unf_ext (0.0.7.4)
50
+ unf_ext (0.0.7.5)
51
51
 
52
52
  PLATFORMS
53
53
  ruby
data/README.md CHANGED
@@ -1,13 +1,105 @@
1
1
  # CarthageRemoteCache
2
2
 
3
+ 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.
4
+
3
5
  ## Installation
4
6
 
5
7
  The gem is published at [rubygems.org](https://rubygems.org/gems/carthage_remote_cache), installation is as easy as:
6
8
 
7
9
  $ gem install carthage_remote_cache
8
10
 
11
+ ## Quickstart
12
+
13
+ 1. Run `carthagerc server` to start the cache on a remote server
14
+ 2. `cd` to your project's root folder
15
+ 3. Run `carthagerc init` to create `Cartrcfile` and point the server property to your running server URL
16
+ 4. Assuming your `Carthage` directory is already built, run `carthagerc upload` to populate remote cache
17
+ 5. Push your `Cartrcfile` and from a different machine run `cartrcfile download` to fetch frameworks into `Carthage/Build/` folder
18
+ 6. Build your app without having to wait for `carthage bootstrap`
19
+
9
20
  ## Usage
10
21
 
22
+ ### Init
23
+
24
+ Before running any other commands, it's required to initialize `carthagerc` in your project directory by running:
25
+
26
+ $ carthagerc init
27
+
28
+ Which produces a `Cartrcfile`. Configuration is done via plain `ruby` code, so it is as simple as:
29
+
30
+ Configuration.setup do |c|
31
+ c.server = "http://localhost:9292/"
32
+ end
33
+
34
+ `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.
35
+
36
+ ### Upload Workflow
37
+
38
+ Make sure that all your framework binaries have been built with `carthage`, otherwise there is nothing to upload.
39
+
40
+ $ carthage bootstrap
41
+
42
+ Start the upload with:
43
+
44
+ $ carthagerc upload
45
+
46
+ After couple of seconds you should be able to see confirmation in terminal:
47
+
48
+ Uploaded 53 archives, skipped 0.
49
+
50
+ #### Overwriting Existing Cache
51
+
52
+ Attempting to run `carthagerc upload` again will not upload any framework binaries, since all of them are already present on the cache server:
53
+
54
+ Uploaded 53 archives, skipped 53.
55
+
56
+ If your cache happen to be tainted by invalid framework binaries, you can overwrite existing cache with
57
+
58
+ $ carthagerc upload --force
59
+
60
+ #### Upgrading Xcode or Swift
61
+
62
+ 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.
63
+
64
+ ### Download Workflow
65
+
66
+ Once 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 respository before executing:
67
+
68
+ $ carthagerc download
69
+
70
+ You should expect to see following output on a machine with empty `Carthage` folder:
71
+
72
+ Downloaded and extracted 53 archives, skipped 0 archives.
73
+
74
+ Your project should be ready for building.
75
+
76
+ #### Overwriting Local Carthage Folder
77
+
78
+ In case you happen to change a file in `Carthage/Build` by accident, it's possible to force download all frameworks again with:
79
+
80
+ $ carthagerc download --force
81
+
82
+
83
+ ### Config
84
+
85
+ To get a quick overview on Xcode / Swift / Framework versions, execute
86
+
87
+ $ carthagerc config
88
+
89
+ Which will print similar information:
90
+
91
+ Xcodebuild: 9C40b
92
+ ---
93
+ Swift: 4.0.3
94
+ ---
95
+ Server: http://localhost:9292/
96
+ ---
97
+ Cartfile.resolved:
98
+ github "kayak/attributions" "0.3"
99
+ ---
100
+ Local Build Frameworks:
101
+ Attributions 0.3 [:iOS]
102
+
11
103
  ### Cache Server
12
104
 
13
105
  Start the server with
@@ -16,6 +108,8 @@ Start the server with
16
108
 
17
109
  and browse to [localhost:9292](http://localhost:9292/) where you should be able to see the default _Welcome_ message.
18
110
 
111
+ Framework binaries will be stored in `~/.carthagerc_server` folder.
112
+
19
113
  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.:
20
114
 
21
115
  $ carthage server -p9000
@@ -23,28 +117,49 @@ Server is bound to port 9292 by default. If you need to use different port, spec
23
117
 
24
118
  Don't forget to change port number in your version controlled `Cartrcfile`.
25
119
 
26
- ### Carthage Preparation
120
+ #### Launch Agent
27
121
 
28
- ### Init
122
+ You can also run the cache server as a launch agent. Copy the template [com.kayak.carthagerc.server.plist](https://github.com/kayak/carthage_remote_cache/blob/master/com.kayak.carthagerc.server.plist) file to `~/Library/LaunchAgents`, change log
123
+ paths to include your username and run:
29
124
 
30
- $ carthagerc init
125
+ $ launchctl load -w ~/Library/LaunchAgents/com.kayak.carthagerc.server.plist
31
126
 
32
- Example `Cartrcfile`:
127
+ If you want to stop the agent, run:
33
128
 
34
- Configuration.setup do |c|
35
- c.server = "http://localhost:9292/"
36
- end
129
+ $ launchctl unload ~/Library/LaunchAgents/com.kayak.carthagerc.server.plist
37
130
 
38
- ### Artifact Upload
39
- $ carthagerc upload
40
-
41
- ### Artifact Download
42
- $ carthagerc download
131
+ Check out official documentation on [Launch Agents](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html) for more info.
43
132
 
44
133
  ### Help
45
134
 
46
135
  Documentation is also available when running `carthagerc` or `carthagerc --help`. Both commands print list of available commands with brief description.
47
136
 
137
+ carthagerc COMMAND [OPTIONS]
138
+
139
+ ...
140
+
141
+ COMMANDS
142
+ config
143
+ prints environment information and Cartrcfile configuration
144
+
145
+ download [-f|--force] [-v|--verbose]
146
+ fetch missing frameworks into Carthage/Build
147
+
148
+ init
149
+ create initial Cartrcfile in current directory
150
+
151
+ upload [-f|--force] [-v|--verbose]
152
+ archive frameworks in Carthage/Build and upload them to the server
153
+
154
+ server [-pPORT|--port=PORT]
155
+ start cache server
156
+
157
+ OPTIONS
158
+ -f, --force Force upload/download of framework archives even if local and server .version files match
159
+ -h, --help Show help
160
+ -p, --port=PORT Server application port used when starting server, default port is 9292
161
+ -v, --verbose Show extra runtime information
162
+
48
163
  ## Development
49
164
 
50
165
  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.
@@ -57,25 +172,17 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
57
172
 
58
173
  ### Example Folder
59
174
 
60
- Repository is bundled with an example Carthage setup open the `example` folder, where you should be able to see following files, which are preconfigured to bring in a couple of frameworks:
175
+ Repository is bundled with an example Carthage setup for your experiments. Open the [example](https://github.com/kayak/carthage_remote_cache/blob/master/example) folder, where you should be able to see following files, which are preconfigured to bring in a couple of frameworks:
61
176
  - Cartfile
62
177
  - Cartfile.resolved
63
178
  - Cartrcfile
64
179
 
65
- #### Upload
66
-
67
- First of all, build Carthage dependencies:
180
+ Make sure to build these dependencies with `carthage bootstrap` before attempting to upload them.
68
181
 
69
- $ carthage update --no-build && carthage bootstrap
70
-
71
- After the `Carthage/Build` folder gets populated, execute:
182
+ Try out a few commands:
72
183
 
184
+ $ carthagerc config
73
185
  $ carthagerc upload
74
-
75
- You should be able to observe the `~/.carthage_remote_cache` folder filling.
76
-
77
- #### Download
78
-
79
186
  $ carthagerc download
80
187
 
81
188
  ## License
data/bin/carthagerc CHANGED
@@ -21,10 +21,10 @@ opt_parser = OptionParser.new do |opt|
21
21
  opt.separator "QUICKSTART"
22
22
  opt.separator " 1. Run `carthagerc server` to start the cache on a remote server"
23
23
  opt.separator " 2. `cd` to your project's root folder"
24
- opt.separator " 3. Run `carthagerc init` to create #{CARTRCFILE} and point the server property to your running server URL"
25
- opt.separator " 4. Assuming your #{CARTHAGE_DIR} directory is already built, run `carthagerc upload` to populate remote cache"
26
- opt.separator " 5. Push your `CARTRCFILE` and from a different machine run `cartrcfile download` to fetch frameworks into #{CARTHAGE_BUILD_DIR} folder"
27
- opt.separator " 6. Profit"
24
+ opt.separator " 3. Run `carthagerc init` to create `Cartrcfile` and point the server property to your running server URL"
25
+ opt.separator " 4. Assuming your `Carthage` directory is already built, run `carthagerc upload` to populate remote cache"
26
+ opt.separator " 5. Push your `Cartrcfile` and from a different machine run `cartrcfile download` to fetch frameworks into `Carthage/Build/` folder"
27
+ opt.separator " 6. Build your app without having to wait for `carthage bootstrap`"
28
28
  opt.separator ""
29
29
  opt.separator "COMMANDS"
30
30
  opt.separator " config"
@@ -80,6 +80,6 @@ begin
80
80
  else
81
81
  bail("Unsupported command #{command}, run with --help to show available commands")
82
82
  end
83
- rescue => e
83
+ rescue AppError => e
84
84
  bail(e.message)
85
85
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "carthage_remote_cache"
3
- spec.version = "0.0.2"
3
+ spec.version = "0.0.3"
4
4
 
5
5
  spec.summary = %q{Centralized cache to serve carthage frameworks. Useful for distributed CI setup with several build machines.}
6
6
  spec.description = spec.summary
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Label</key>
6
+ <string>com.kayak.carthagerc.server</string>
7
+ <key>ProgramArguments</key>
8
+ <array>
9
+ <string>/usr/local/bin/carthagerc</string>
10
+ <string>server</string>
11
+ <string>--port=9292</string>
12
+ </array>
13
+ <key>KeepAlive</key>
14
+ <true/>
15
+ <key>StandardOutPath</key>
16
+ <string>/Users/MY_USER/Library/Logs/carthagerc.server.stdout.log</string>
17
+ <key>StandardErrorPath</key>
18
+ <string>/Users/MY_USER/Library/Logs/carthagerc.server.stderr.log</string>
19
+ </dict>
20
+ </plist>
@@ -3,7 +3,7 @@ class CarthageArchive
3
3
  attr_reader :archive_filename, :archive_path
4
4
 
5
5
  def initialize(framework_name, platform)
6
- raise "Platform #{platform.inspect} needs to be a symbol" unless platform.kind_of?(Symbol)
6
+ raise AppError.new, "Platform #{platform.inspect} needs to be a symbol" unless platform.kind_of?(Symbol)
7
7
 
8
8
  @framework_name = framework_name
9
9
  @platform = platform
@@ -21,13 +21,13 @@ class CarthageArchive
21
21
 
22
22
  platform_path = File.join(CARTHAGE_BUILD_DIR, platform_to_carthage_dir_string(@platform))
23
23
  framework_path = File.join(platform_path, "#{@framework_name}.framework")
24
- raise "Archive can't be created, no framework directory at #{framework_path}" unless Dir.exist?(framework_path)
24
+ raise AppError.new, "Archive can't be created, no framework directory at #{framework_path}" unless Dir.exist?(framework_path)
25
25
 
26
26
  dsym_path = File.join(platform_path, "#{@framework_name}.framework.dSYM")
27
- raise "DSYM File #{dsym_path} is missing" unless File.exist?(dsym_path)
27
+ raise AppError.new, "DSYM File #{dsym_path} is missing" unless File.exist?(dsym_path)
28
28
 
29
29
  binary_path = File.join(framework_path, @framework_name)
30
- raise "Binary #{binary_path} is missing, failed to read .bcsymbolmap files" unless File.exist?(binary_path)
30
+ raise AppError.new, "Binary #{binary_path} is missing, failed to read .bcsymbolmap files" unless File.exist?(binary_path)
31
31
 
32
32
  bcsymbolmap_paths = find_bcsymbolmap_paths(platform_path, binary_path)
33
33
 
@@ -41,7 +41,7 @@ class CarthageArchive
41
41
  end
42
42
 
43
43
  def unpack_archive
44
- raise "Archive #{@archive_path} is missing" unless File.exist?(@archive_path)
44
+ raise AppError.new, "Archive #{@archive_path} is missing" unless File.exist?(@archive_path)
45
45
  $LOG.debug("Unpacking #{@archive_path}, file size: #{formatted_archive_size}")
46
46
  sh("unzip -o #{quote @archive_path}")
47
47
  end
@@ -30,7 +30,7 @@ class CarthageDependency
30
30
  when "github"
31
31
  repository.split("/").last
32
32
  else
33
- raise "Determining version_filename from #{@type} dependency is not yet supported"
33
+ raise AppError.new, "Determining version_filename from #{@type} dependency is not yet supported"
34
34
  end
35
35
  end
36
36
 
@@ -52,12 +52,12 @@ class DownloadCommand
52
52
  end
53
53
 
54
54
  version_file = @networking.download_version_file(carthage_dependency)
55
- raise "Version file #{carthage_dependency.version_filename} is not present on the server, please run `carthagerc upload` first" if version_file.nil?
55
+ raise AppError.new, "Version file #{carthage_dependency.version_filename} is not present on the server, please run `carthagerc upload` first" if version_file.nil?
56
56
 
57
57
  version_file.frameworks_by_platform.each do |platform, framework_names|
58
58
  for framework_name in framework_names do
59
59
  archive = @api.download_and_unpack_archive(carthage_dependency, framework_name, platform)
60
- raise "Failed to download framework #{carthage_dependency} – #{framework_name} (#{platform}). Please `upload` the framework first." if archive.nil?
60
+ raise AppError.new, "Failed to download framework #{carthage_dependency} – #{framework_name} (#{platform}). Please `upload` the framework first." if archive.nil?
61
61
  @number_of_downloaded_archives += 1
62
62
  end
63
63
  end
@@ -7,7 +7,7 @@ class InitCommand
7
7
  def run
8
8
  path = File.join(Dir.pwd, CARTRCFILE)
9
9
  if File.exist?(path)
10
- raise "File #{path} already exists"
10
+ raise AppError.new, "File #{path} already exists"
11
11
  else
12
12
  File.write(path, file_contents)
13
13
  end
data/lib/configuration.rb CHANGED
@@ -44,34 +44,35 @@ class Configuration
44
44
  def initialize_env
45
45
  xcodebuild_raw_version = sh("xcodebuild -version")
46
46
  @xcodebuild_version = xcodebuild_raw_version[/Build version (.*)$/, 1]
47
- raise "Could not parse build version from '#{xcodebuild_raw_version}'" if @xcodebuild_version.nil?
47
+ raise AppError.new, "Could not parse build version from '#{xcodebuild_raw_version}'" if @xcodebuild_version.nil?
48
48
 
49
49
  swift_raw_version = sh("swift -version")
50
50
  @swift_version = swift_raw_version[/Apple Swift version (.*) \(/, 1]
51
- raise "Could not parse swift version from '#{raw_swift_version}'" if @swift_version.nil?
51
+ raise AppError.new, "Could not parse swift version from '#{raw_swift_version}'" if @swift_version.nil?
52
52
 
53
- raise "Misssing #{CARTFILE_RESOLVED}" unless File.exist?(CARTFILE_RESOLVED)
53
+ raise AppError.new, "Misssing #{CARTFILE_RESOLVED}" unless File.exist?(CARTFILE_RESOLVED)
54
54
  @carthage_dependencies = File.readlines(CARTFILE_RESOLVED)
55
55
  .map { |line| CarthageDependency.parse_cartfile_resolved_line(line) }
56
56
  .compact
57
57
  end
58
58
 
59
59
  def initialize_cartrcfile
60
- raise "Configuration file #{CARTRCFILE} was not found, consider creating one by running `carthagerc init`" unless File.exist?(CARTRCFILE)
60
+ raise AppError.new, "Configuration file #{CARTRCFILE} was not found, consider creating one by running `carthagerc init`" unless File.exist?(CARTRCFILE)
61
61
 
62
62
  # Populate class variable @@user_config.
63
63
  load File.join(Dir.pwd, CARTRCFILE)
64
64
 
65
- raise "Missing 'server' configuration in #{CARTRCFILE}" if @@user_config.server.nil? || @@user_config.server.empty?
65
+ raise AppError.new, "Missing 'server' configuration in #{CARTRCFILE}" if @@user_config.server.nil? || @@user_config.server.empty?
66
66
  @server_uri = URI.parse(@@user_config.server)
67
67
  end
68
68
 
69
69
  def framework_names_with_platforms
70
- version_files.flat_map do |vf|
70
+ lines = version_files.flat_map do |vf|
71
71
  vf.platforms_by_framework.flat_map do |framework_name, platforms|
72
72
  "#{framework_name} #{vf.version} #{platforms}"
73
73
  end
74
74
  end
75
+ lines.sort
75
76
  end
76
77
 
77
78
  def version_files
data/lib/constants.rb CHANGED
@@ -5,4 +5,4 @@ CARTRCFILE = 'Cartrcfile'
5
5
  THREAD_POOL_SIZE = 8
6
6
 
7
7
  SERVER_DEFAULT_PORT = 9292
8
- SERVER_CACHE_DIR = File.join(Dir.home, '.carthage-remote-cache')
8
+ SERVER_CACHE_DIR = File.join(Dir.home, '.carthagerc_server')
data/lib/errors.rb CHANGED
@@ -1,4 +1,7 @@
1
- class MultipleErrorsError < StandardError
1
+ # Common type for all carthage_remote_cache Errors.
2
+ class AppError < StandardError; end
3
+
4
+ class MultipleErrorsError < AppError
2
5
 
3
6
  def initialize(errors)
4
7
  @errors = errors
@@ -10,4 +13,4 @@ class MultipleErrorsError < StandardError
10
13
 
11
14
  end
12
15
 
13
- class OutdatedFrameworkBuildError < StandardError; end
16
+ class OutdatedFrameworkBuildError < AppError; end
@@ -40,19 +40,6 @@ post versions_path do
40
40
  status(200)
41
41
  end
42
42
 
43
- # Check whether framework archive is already cached.
44
- head frameworks_path do
45
- dirname = params_to_framework_dir(params)
46
- archive = CarthageArchive.new(params[:framework_name], params[:platform].to_sym)
47
- filename = File.join(dirname, archive.archive_filename)
48
-
49
- if File.exist?(filename)
50
- status(200)
51
- else
52
- status(404)
53
- end
54
- end
55
-
56
43
  # Retrieve .zip framework archive.
57
44
  get frameworks_path do
58
45
  dirname = params_to_framework_dir(params)
data/lib/utils.rb CHANGED
@@ -27,7 +27,7 @@ def quote(input)
27
27
  .select { |e| !e.empty? }
28
28
  .join(' ')
29
29
  else
30
- raise "Unsupported type #{input}"
30
+ raise AppError.new, "Unsupported type #{input}"
31
31
  end
32
32
  end
33
33
 
@@ -42,7 +42,7 @@ def platform_to_api_string(platform)
42
42
  when :watchOS
43
43
  'watchOS'
44
44
  else
45
- raise "Unrecognized platform #{platform.inspect}"
45
+ raise AppError.new, "Unrecognized platform #{platform.inspect}"
46
46
  end
47
47
  end
48
48
 
@@ -57,6 +57,6 @@ def platform_to_carthage_dir_string(platform)
57
57
  when :watchOS
58
58
  'watchOS'
59
59
  else
60
- raise "Unrecognized platform #{platform.inspect}"
60
+ raise AppError.new, "Unrecognized platform #{platform.inspect}"
61
61
  end
62
62
  end
data/lib/version_file.rb CHANGED
@@ -63,13 +63,13 @@ class VersionFile
63
63
  private
64
64
 
65
65
  def parse
66
- raise "File #{path} doesn't exist, has carthage been bootstrapped?" unless File.exist?(@path)
66
+ raise AppError.new, "File #{path} doesn't exist, has carthage been bootstrapped?" unless File.exist?(@path)
67
67
 
68
68
  file = File.read(@path)
69
69
  json = JSON.parse(file)
70
70
 
71
71
  @version = json['commitish']
72
- raise "Version is missing in #{@path}" if @version.nil? || @version.empty?
72
+ raise AppError.new, "Version is missing in #{@path}" if @version.nil? || @version.empty?
73
73
 
74
74
  @frameworks_by_platform = {
75
75
  :iOS => parse_platform_array(json['iOS']),
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carthage_remote_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juraj Blahunka
@@ -125,6 +125,7 @@ files:
125
125
  - Rakefile
126
126
  - bin/carthagerc
127
127
  - carthage_remote_cache.gemspec
128
+ - com.kayak.carthagerc.server.plist
128
129
  - dev/console
129
130
  - dev/setup
130
131
  - dev/start_server