carthage_remote_cache 0.0.4 → 0.0.5

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
  SHA256:
3
- metadata.gz: 419b8edd1e39136269db80965bcffb2fe4e6207f7b83459e549a37f4beac9f7c
4
- data.tar.gz: 0c83197b67a7e6b5ef504a1811a533a082c98152e07315414d346eb97049a9fc
3
+ metadata.gz: 76eb34fe905eb5fce02802b6b3d7a764b144cc4ab20b6f67d2068215c6605811
4
+ data.tar.gz: ce2786ceae18cdc95d4c21360044b21838f839879d5a69f883d7b8c8d2040f15
5
5
  SHA512:
6
- metadata.gz: 5b4aaad19ca7a53f5ce85fa801c22fe019c66a3281ecb6d239516d8d0c94418201b1974d149ff44fc2e22b6a5085227f9280680b0aef1bc0700ea480fa4a1310
7
- data.tar.gz: 5fd1d49c2c75c9ffa64fc36cad248ee4cb670abab779f821582cdfc8b656ba175ece52608a6017022d2ffabd1997bda53c442229d14b876041f557929396bbc9
6
+ metadata.gz: a128b2d782cee56f2ddfc018a8f4e4e3275dd87b1337d6420861ee376edd0ea468655739951667768855721d0f91a7176a4102a4f20a2cc92e363e617bebe2d8
7
+ data.tar.gz: ffead6c5c29416ed7d12e2fdbd26f465127deedb80fb3af261904de35b2a22245a9302427081ff5e86585e2426db4a4444bbac57680e0726b7b3d2d9809f2e8d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- carthage_remote_cache (0.0.4)
4
+ carthage_remote_cache (0.0.5)
5
5
  concurrent-ruby (~> 1.0.5)
6
6
  rack (~> 2.0.4)
7
7
  rest-client (~> 2.0.2)
data/lib/api.rb CHANGED
@@ -22,17 +22,30 @@ class API
22
22
  archive.create_archive(@shell, carthage_dependency.should_include_dsym)
23
23
  archive_size = archive.archive_size
24
24
  begin
25
- @networking.upload_framework_archive(archive.archive_path, carthage_dependency, framework_name, platform)
25
+ checksum = crc32(archive.archive_path)
26
+ @networking.upload_framework_archive(archive.archive_path, carthage_dependency, framework_name, platform, checksum)
26
27
  ensure
27
28
  archive.delete_archive
28
29
  end
29
30
  archive_size
30
31
  end
31
32
 
32
- # @return zip archive size in Bytes or nil if archive download failed
33
+ # @return zip archive size in Bytes
34
+ # @raise AppError if download or checksum validation fails
33
35
  def download_and_unpack_archive(carthage_dependency, framework_name, platform)
34
- archive = @networking.download_framework_archive(carthage_dependency, framework_name, platform)
35
- return nil if archive.nil?
36
+ result = @networking.download_framework_archive(carthage_dependency, framework_name, platform)
37
+ if result.nil?
38
+ raise AppError.new, "Failed to download framework #{carthage_dependency} – #{framework_name} (#{platform}). Please `upload` the framework first."
39
+ end
40
+
41
+ archive = result[:archive]
42
+ remote_checksum = result[:checksum]
43
+ local_checksum = crc32(archive.archive_path)
44
+
45
+ if local_checksum != remote_checksum
46
+ raise AppError.new, checksum_error_message(archive.archive_path, remote_checksum, local_checksum)
47
+ end
48
+
36
49
  archive_size = archive.archive_size
37
50
  begin
38
51
  $LOG.debug("Downloaded #{archive.archive_path}")
@@ -42,4 +55,14 @@ class API
42
55
  end
43
56
  archive_size
44
57
  end
58
+
59
+ private
60
+
61
+ def checksum_error_message(path, remote, local)
62
+ <<~EOS
63
+ Checksums for '#{path}' do not match:
64
+ Remote: #{remote}
65
+ Local: #{local}
66
+ EOS
67
+ end
45
68
  end
@@ -6,6 +6,7 @@ require 'carthage_archive'
6
6
  require 'carthage_dependency'
7
7
  require 'constants'
8
8
  require 'configuration'
9
+ require 'crc32'
9
10
  require 'errors'
10
11
  require 'log'
11
12
  require 'networking'
@@ -72,12 +72,8 @@ class DownloadCommand
72
72
  version_file.frameworks_by_platform.each do |platform, framework_names|
73
73
  for framework_name in framework_names
74
74
  archive_size = @api.download_and_unpack_archive(carthage_dependency, framework_name, platform)
75
- if archive_size.nil?
76
- raise AppError.new, "Failed to download framework #{carthage_dependency} – #{framework_name} (#{platform}). Please `upload` the framework first."
77
- else
78
- @number_of_downloaded_archives += 1
79
- @total_archive_size += archive_size
80
- end
75
+ @number_of_downloaded_archives += 1
76
+ @total_archive_size += archive_size
81
77
  end
82
78
  end
83
79
  version_file.move_to_build_dir
data/lib/constants.rb CHANGED
@@ -6,3 +6,7 @@ THREAD_POOL_SIZE = 8
6
6
 
7
7
  SERVER_DEFAULT_PORT = 9292
8
8
  SERVER_CACHE_DIR = File.join(Dir.home, '.carthagerc_server')
9
+
10
+ ARCHIVE_CHECKSUM_HEADER_REST_CLIENT = :archive_checksum
11
+ ARCHIVE_CHECKSUM_HEADER_SINATRA_IN = 'HTTP_ARCHIVE_CHECKSUM'
12
+ ARCHIVE_CHECKSUM_HEADER_SINATRA_OUT = 'Archive-Checksum'
data/lib/crc32.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'digest'
2
+ require 'zlib'
3
+
4
+ class Digest::CRC32 < Digest::Class
5
+ include Digest::Instance
6
+
7
+ def initialize
8
+ reset
9
+ end
10
+
11
+ def reset
12
+ @crc32 = 0
13
+ end
14
+
15
+ def update(str)
16
+ @crc32 = Zlib.crc32(str, @crc32)
17
+ end
18
+
19
+ def finish
20
+ [@crc32].pack('N')
21
+ end
22
+ end
data/lib/errors.rb CHANGED
@@ -1,6 +1,14 @@
1
1
  # Common type for all carthage_remote_cache Errors.
2
2
  class AppError < StandardError; end
3
3
 
4
+ class CmdError < StandardError
5
+ attr_reader :command
6
+
7
+ def initialize(command)
8
+ @command = command
9
+ end
10
+ end
11
+
4
12
  class MultipleErrorsError < AppError
5
13
  def initialize(errors)
6
14
  @errors = errors
data/lib/networking.rb CHANGED
@@ -8,6 +8,7 @@ class Networking
8
8
 
9
9
  # Version Files
10
10
 
11
+ # @return VersionFile or nil
11
12
  def download_version_file(carthage_dependency)
12
13
  url = new_version_file_url(carthage_dependency)
13
14
  $LOG.debug("Downloading version file from #{url}")
@@ -22,14 +23,20 @@ class Networking
22
23
  version_file
23
24
  end
24
25
 
26
+ # @raise AppError on upload failure
25
27
  def upload_version_file(carthage_dependency)
26
28
  url = new_version_file_url(carthage_dependency)
27
29
  $LOG.debug("Uploading #{carthage_dependency.version_filename}")
28
- RestClient.post(url, :version_file => File.new(carthage_dependency.version_filepath))
30
+ RestClient.post(url, :version_file => File.new(carthage_dependency.version_filepath)) do |response, request, result|
31
+ unless response.code == 200
32
+ raise AppError.new, "Version file upload #{carthage_dependency.version_filename} failed, response:\n #{response[0..300]}"
33
+ end
34
+ end
29
35
  end
30
36
 
31
37
  # Archives
32
38
 
39
+ # @return Hash with CarthageArchive and checksum or nil
33
40
  def download_framework_archive(carthage_dependency, framework_name, platform)
34
41
  url = new_framework_url(carthage_dependency, framework_name, platform)
35
42
  $LOG.debug("Downloading framework from #{url}")
@@ -37,7 +44,7 @@ class Networking
37
44
  if response.code == 200
38
45
  archive = CarthageArchive.new(framework_name, platform)
39
46
  File.write(archive.archive_path, response.to_s)
40
- archive
47
+ {:archive => archive, :checksum => response.headers[ARCHIVE_CHECKSUM_HEADER_REST_CLIENT]}
41
48
  else
42
49
  nil
43
50
  end
@@ -45,10 +52,17 @@ class Networking
45
52
  archive
46
53
  end
47
54
 
48
- def upload_framework_archive(zipfile_name, carthage_dependency, framework_name, platform)
55
+ # @raise AppError when upload fails
56
+ def upload_framework_archive(zipfile_name, carthage_dependency, framework_name, platform, checksum)
49
57
  url = new_framework_url(carthage_dependency, framework_name, platform)
50
- $LOG.debug("Uploading framework to #{url}")
51
- RestClient.post(url, :framework_file => File.new(zipfile_name))
58
+ params = {:framework_file => File.new(zipfile_name)}
59
+ headers = {ARCHIVE_CHECKSUM_HEADER_REST_CLIENT => checksum}
60
+ $LOG.debug("Uploading framework to #{url}, headers: #{headers}")
61
+ RestClient.post(url, params, headers) do |response, request, result|
62
+ unless response.code == 200
63
+ raise AppError.new, "Framework upload #{zipfile_name} failed, response:\n #{response[0..300]}"
64
+ end
65
+ end
52
66
  end
53
67
 
54
68
  private
@@ -47,15 +47,18 @@ get frameworks_path do
47
47
  filename = File.join(dirname, archive.archive_filename)
48
48
 
49
49
  if File.exist?(filename)
50
+ headers[ARCHIVE_CHECKSUM_HEADER_SINATRA_OUT] = crc32(filename)
50
51
  status(200)
51
52
  send_file(filename)
52
53
  else
53
54
  status(404)
55
+ "Missing framework archive at '#{filename}'"
54
56
  end
55
57
  end
56
58
 
57
59
  # Upload framework archive. Overwrites already cached archive if exists.
58
60
  post frameworks_path do
61
+ expected_checksum = request.env[ARCHIVE_CHECKSUM_HEADER_SINATRA_IN]
59
62
  filename = params[:framework_file][:filename]
60
63
  source_file = params[:framework_file][:tempfile]
61
64
 
@@ -70,7 +73,16 @@ post frameworks_path do
70
73
  target_file.write(source_file.read)
71
74
  end
72
75
 
73
- status(200)
76
+ checksum = crc32(target_filename)
77
+ if checksum == expected_checksum
78
+ status(200)
79
+ else
80
+ File.delete(target_filename)
81
+ message = "Checksums for '#{target_filename}' don't match. Expected '#{expected_checksum}', got '#{checksum}'"
82
+ $LOG.error(message)
83
+ status(500)
84
+ message
85
+ end
74
86
  end
75
87
 
76
88
  private
data/lib/shell_wrapper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'open3'
2
+
1
3
  class ShellWrapper
2
4
  # @return
3
5
  # Xcode 9.2
@@ -29,4 +31,17 @@ class ShellWrapper
29
31
  def unpack(archive_path)
30
32
  sh("unzip -o #{quote archive_path}")
31
33
  end
34
+
35
+ private
36
+
37
+ # @return command output if successful
38
+ # @raise CmdError
39
+ def sh(command)
40
+ stdout, stderr, status = Open3.capture3(command)
41
+ if status.success?
42
+ stdout.strip
43
+ else
44
+ raise CmdError.new(command), "Command '#{command}' failed, error output:\n#{stderr.strip}"
45
+ end
46
+ end
32
47
  end
data/lib/utils.rb CHANGED
@@ -1,19 +1,15 @@
1
- # Execute arbitrary system command.
2
- # @return command output, bails on failure
3
- def sh(cmd)
4
- output = `#{cmd}`
5
- bail("Command `#{cmd}` failed!") unless $?.success?
6
- output.strip
7
- end
8
-
9
- # Exits Ruby process, only to be called:
10
- # 1. If sh / system calls fail
11
- # 2. From top level `carthagerc` script
1
+ # Exits Ruby process, only to be called from top level `carthagerc` script
12
2
  def bail(message, code = 1)
13
3
  $stderr.puts(message.strip + "\n")
14
4
  Process.exit(code)
15
5
  end
16
6
 
7
+ def crc32(filename)
8
+ checksum = Digest::CRC32.file(filename).hexdigest
9
+ $LOG.debug("CRC32 checksum for '#{filename}': #{checksum}")
10
+ checksum
11
+ end
12
+
17
13
  # Quote command line arguments with double quotes.
18
14
  # Useful for file paths with spaces.
19
15
  def quote(input)
data/lib/version.rb CHANGED
@@ -1 +1 @@
1
- VERSION = '0.0.4'
1
+ VERSION = '0.0.5'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carthage_remote_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juraj Blahunka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-08 00:00:00.000000000 Z
11
+ date: 2018-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -212,6 +212,7 @@ files:
212
212
  - lib/commands/upload_command.rb
213
213
  - lib/configuration.rb
214
214
  - lib/constants.rb
215
+ - lib/crc32.rb
215
216
  - lib/errors.rb
216
217
  - lib/log.rb
217
218
  - lib/networking.rb