carthage_remote_cache 0.0.5 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/api.rb CHANGED
@@ -1,15 +1,45 @@
1
1
  class API
2
- def initialize(shell, networking, options)
2
+ def initialize(shell, config, networking, options)
3
3
  @shell = shell
4
+ @config = config
4
5
  @networking = networking
5
6
  @options = options
7
+ @unpack_mutex = Mutex.new
6
8
  end
7
9
 
8
- def version_file_matches_server?(carthage_dependency, version_file)
10
+ def verify_server_version
11
+ server_version = @networking.get_server_version
12
+ unless server_version == VERSION
13
+ raise ServerVersionMismatchError.new, version_mismatch_message(server_version)
14
+ end
15
+ end
16
+
17
+ def verify_build_dir_matches_cartfile_resolved
18
+ errors = []
19
+ for carthage_dependency in @config.carthage_resolved_dependencies
20
+ begin
21
+ version_file = carthage_dependency.new_version_file
22
+ carthage_dependency.verify_version_in_version_file(version_file)
23
+ rescue VersionFileDoesNotExistError => e
24
+ errors << OutdatedFrameworkBuildError.new(
25
+ carthage_dependency.guessed_framework_basename,
26
+ "-",
27
+ carthage_dependency.version
28
+ )
29
+ rescue OutdatedFrameworkBuildError => e
30
+ errors << e
31
+ end
32
+ end
33
+ if errors.count > 0
34
+ raise FrameworkValidationError.new(errors)
35
+ end
36
+ end
37
+
38
+ def version_file_matches_server?(carthage_dependency, version_file, platforms)
9
39
  if @options[:force]
10
40
  false
11
41
  else
12
- server_version_file = @networking.download_version_file(carthage_dependency)
42
+ server_version_file = @networking.download_version_file(carthage_dependency, platforms)
13
43
  result = version_file.same_content?(server_version_file)
14
44
  server_version_file.remove unless server_version_file.nil?
15
45
  result
@@ -19,7 +49,7 @@ class API
19
49
  # @return zip archive size in Bytes
20
50
  def create_and_upload_archive(carthage_dependency, framework_name, platform)
21
51
  archive = CarthageArchive.new(framework_name, platform)
22
- archive.create_archive(@shell, carthage_dependency.should_include_dsym)
52
+ archive.create_archive(@shell)
23
53
  archive_size = archive.archive_size
24
54
  begin
25
55
  checksum = crc32(archive.archive_path)
@@ -49,7 +79,10 @@ class API
49
79
  archive_size = archive.archive_size
50
80
  begin
51
81
  $LOG.debug("Downloaded #{archive.archive_path}")
52
- archive.unpack_archive(@shell)
82
+ # Can't unpack multiple archives concurrently.
83
+ @unpack_mutex.synchronize do
84
+ archive.unpack_archive(@shell)
85
+ end
53
86
  ensure
54
87
  archive.delete_archive
55
88
  end
@@ -58,6 +91,17 @@ class API
58
91
 
59
92
  private
60
93
 
94
+ def version_mismatch_message(server_version)
95
+ <<~EOS
96
+ Version mismatch:
97
+ Cache server version: #{server_version}
98
+ Client version: #{VERSION}
99
+
100
+ Please use the same version as cache server by running:
101
+ $ gem install carthage_remote_cache -v #{server_version}
102
+ EOS
103
+ end
104
+
61
105
  def checksum_error_message(path, remote, local)
62
106
  <<~EOS
63
107
  Checksums for '#{path}' do not match:
@@ -1,3 +1,5 @@
1
+ require "fileutils"
2
+
1
3
  class CarthageArchive
2
4
  attr_reader :archive_filename, :archive_path
3
5
 
@@ -15,7 +17,7 @@ class CarthageArchive
15
17
  # - Carthage/Build/iOS/Alamofire.framework/Alamofire
16
18
  # - Carthage/Build/iOS/618BEB79-4C7F-3692-B140-131FB983AC5E.bcsymbolmap
17
19
  # into Alamofire-iOS.zip
18
- def create_archive(shell, should_include_dsym, carthage_build_dir = CARTHAGE_BUILD_DIR)
20
+ def create_archive(shell, carthage_build_dir = CARTHAGE_BUILD_DIR)
19
21
  $LOG.debug("Archiving #{@framework_name} for #{@platform}")
20
22
 
21
23
  platform_path = File.join(carthage_build_dir, platform_to_carthage_dir_string(@platform))
@@ -25,12 +27,8 @@ class CarthageArchive
25
27
  # It's very likely, that binary releases don't contain DSYMs.
26
28
  dsym_path = File.join(platform_path, "#{@framework_name}.framework.dSYM")
27
29
  unless File.exist?(dsym_path)
28
- if should_include_dsym
29
- raise AppError.new, "DSYM File #{dsym_path} not found"
30
- else
31
- $LOG.error("DSYM File #{dsym_path} not found, continuing")
32
- dsym_path = nil
33
- end
30
+ $LOG.error("DSYM File #{dsym_path} not found, continuing")
31
+ dsym_path = nil
34
32
  end
35
33
 
36
34
  binary_path = File.join(framework_path, @framework_name)
@@ -50,8 +48,11 @@ class CarthageArchive
50
48
  $LOG.debug("Created #{@archive_path} archive, file size: #{formatted_archive_size}")
51
49
  end
52
50
 
53
- def unpack_archive(shell)
51
+ def unpack_archive(shell, carthage_build_dir = CARTHAGE_BUILD_DIR)
54
52
  raise AppError.new, "Archive #{@archive_path} is missing" unless File.exist?(@archive_path)
53
+
54
+ delete_existing_build_framework_if_exists(carthage_build_dir)
55
+
55
56
  $LOG.debug("Unpacking #{@archive_path}, file size: #{formatted_archive_size}")
56
57
  shell.unpack(@archive_path)
57
58
  end
@@ -85,4 +86,13 @@ class CarthageArchive
85
86
  def formatted_archive_size
86
87
  format_file_size(archive_size)
87
88
  end
89
+
90
+ def delete_existing_build_framework_if_exists(carthage_build_dir)
91
+ platform_path = File.join(carthage_build_dir, platform_to_carthage_dir_string(@platform))
92
+ framework_path = File.join(platform_path, "#{@framework_name}.framework")
93
+ if File.exist?(framework_path)
94
+ $LOG.debug("Deleting #{framework_path}")
95
+ FileUtils.rm_rf(framework_path)
96
+ end
97
+ end
88
98
  end
@@ -27,6 +27,10 @@ class CarthageDependency
27
27
  @version = args[:version]
28
28
  end
29
29
 
30
+ def new_version_file
31
+ VersionFile.new(version_filepath)
32
+ end
33
+
30
34
  # Since one Cartfile.resolved entry may produce multiple differently named frameworks,
31
35
  # this is an entry point to identifying a framework name.
32
36
  def guessed_framework_basename
@@ -52,38 +56,13 @@ class CarthageDependency
52
56
  File.join(CARTHAGE_BUILD_DIR, version_filename)
53
57
  end
54
58
 
55
- def should_include_dsym
56
- case @origin
57
- when :github
58
- true
59
- when :git
60
- true
61
- when :binary
62
- false
63
- else
64
- raise AppError.new, "Unrecognized origin '#{@origin}'"
65
- end
66
- end
67
-
68
- def validate_version_file(version_file)
59
+ def verify_version_in_version_file(version_file)
69
60
  if @version != version_file.version
70
- raise OutdatedFrameworkBuildError.new, version_validation_message(version_file)
61
+ raise OutdatedFrameworkBuildError.new(guessed_framework_basename, version_file.version, @version)
71
62
  end
72
63
  end
73
64
 
74
65
  def to_s
75
66
  "#{@origin.to_s} \"#{@source}\" \"#{@version}\""
76
67
  end
77
-
78
- private
79
-
80
- def version_validation_message(version_file)
81
- <<~EOS
82
- Outdated version of '#{guessed_framework_basename}' framework detected:
83
- Expected version '#{@version}'
84
- Found version '#{version_file.version}'
85
-
86
- Please run `carthage bootstrap` to build frameworks.
87
- EOS
88
- end
89
68
  end
@@ -1,16 +1,17 @@
1
1
  lib = File.expand_path("..", __FILE__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
- require 'api'
5
- require 'carthage_archive'
6
- require 'carthage_dependency'
7
- require 'constants'
8
- require 'configuration'
9
- require 'crc32'
10
- require 'errors'
11
- require 'log'
12
- require 'networking'
13
- require 'shell_wrapper'
14
- require 'utils'
15
- require 'version'
16
- require 'version_file'
4
+ require "api"
5
+ require "carthage_archive"
6
+ require "carthage_dependency"
7
+ require "constants"
8
+ require "configuration"
9
+ require "crc32"
10
+ require "errors"
11
+ require "log"
12
+ require "networking"
13
+ require "shell_wrapper"
14
+ require "table"
15
+ require "utils"
16
+ require "version"
17
+ require "version_file"
data/lib/commands.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  lib = File.expand_path("..", __FILE__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
- require 'commands/download_command'
5
- require 'commands/init_command'
6
- require 'commands/server_command'
7
- require 'commands/upload_command'
4
+ require "commands/download_command"
5
+ require "commands/init_command"
6
+ require "commands/server_command"
7
+ require "commands/upload_command"
8
+ require "commands/verify_command"
@@ -1,16 +1,17 @@
1
- require 'concurrent'
1
+ require "concurrent"
2
2
 
3
3
  class DownloadCommand
4
4
  def self.new_with_defaults(options)
5
5
  shell = ShellWrapper.new
6
6
  config = Configuration.new(shell)
7
- networking = Networking.new(config)
8
- api = API.new(shell, networking, options)
7
+ networking = Networking.new(config, options[:is_retry_enabled])
8
+ api = API.new(shell, config, networking, options)
9
9
 
10
10
  DownloadCommand.new(
11
11
  config: config,
12
12
  networking: networking,
13
13
  api: api,
14
+ platforms: options[:platforms],
14
15
  )
15
16
  end
16
17
 
@@ -18,17 +19,22 @@ class DownloadCommand
18
19
  @config = args[:config]
19
20
  @networking = args[:networking]
20
21
  @api = args[:api]
22
+ @platforms = args[:platforms]
21
23
  end
22
24
 
23
25
  def run
26
+ @config.ensure_shell_commands
27
+ @api.verify_server_version
28
+
24
29
  pool = Concurrent::FixedThreadPool.new(THREAD_POOL_SIZE)
25
30
 
31
+ @mutex = Mutex.new
26
32
  @number_of_downloaded_archives = 0
27
33
  @number_of_skipped_archives = 0
28
34
  @total_archive_size = 0
29
35
  errors = Concurrent::Array.new
30
36
 
31
- for carthage_dependency in @config.carthage_dependencies
37
+ for carthage_dependency in @config.carthage_resolved_dependencies
32
38
  pool.post(carthage_dependency) do |carthage_dependency|
33
39
  begin
34
40
  download(carthage_dependency)
@@ -53,27 +59,30 @@ class DownloadCommand
53
59
  private
54
60
 
55
61
  def download(carthage_dependency)
56
- local_version_file =
57
- if File.exist?(carthage_dependency.version_filepath)
58
- VersionFile.new(carthage_dependency.version_filepath)
62
+ local_version_file = if File.exist?(carthage_dependency.version_filepath)
63
+ carthage_dependency.new_version_file
59
64
  else
60
65
  nil
61
66
  end
62
67
 
63
- if !local_version_file.nil? && @api.version_file_matches_server?(carthage_dependency, local_version_file)
68
+ if !local_version_file.nil? && @api.version_file_matches_server?(carthage_dependency, local_version_file, @platforms)
64
69
  $LOG.debug("Version file #{local_version_file.path} matches server version, skipping download")
65
- @number_of_skipped_archives += local_version_file.number_of_frameworks
70
+ @mutex.synchronize do
71
+ @number_of_skipped_archives += local_version_file.number_of_frameworks
72
+ end
66
73
  return
67
74
  end
68
75
 
69
- version_file = @networking.download_version_file(carthage_dependency)
76
+ version_file = @networking.download_version_file(carthage_dependency, @platforms)
70
77
  raise AppError.new, "Version file #{carthage_dependency.version_filename} is not present on the server, please run `carthagerc upload` first" if version_file.nil?
71
78
 
72
79
  version_file.frameworks_by_platform.each do |platform, framework_names|
73
80
  for framework_name in framework_names
74
81
  archive_size = @api.download_and_unpack_archive(carthage_dependency, framework_name, platform)
75
- @number_of_downloaded_archives += 1
76
- @total_archive_size += archive_size
82
+ @mutex.synchronize do
83
+ @number_of_downloaded_archives += 1
84
+ @total_archive_size += archive_size
85
+ end
77
86
  end
78
87
  end
79
88
  version_file.move_to_build_dir
@@ -4,8 +4,8 @@ class ServerCommand
4
4
  end
5
5
 
6
6
  def run
7
- ENV['RACK_ENV'] = 'production'
8
- require 'server/server_app'
7
+ ENV["RACK_ENV"] = "production"
8
+ require "server/server_app"
9
9
  Rack::Handler::WEBrick.run(
10
10
  Sinatra::Application,
11
11
  :Port => @options[:server_port],
@@ -1,11 +1,11 @@
1
- require 'concurrent'
1
+ require "concurrent"
2
2
 
3
3
  class UploadCommand
4
4
  def self.new_with_defaults(options)
5
5
  shell = ShellWrapper.new
6
6
  config = Configuration.new(shell)
7
- networking = Networking.new(config)
8
- api = API.new(shell, networking, options)
7
+ networking = Networking.new(config, options[:is_retry_enabled])
8
+ api = API.new(shell, config, networking, options)
9
9
 
10
10
  UploadCommand.new(
11
11
  config: config,
@@ -21,16 +21,21 @@ class UploadCommand
21
21
  end
22
22
 
23
23
  def run
24
+ @config.ensure_shell_commands
25
+ @api.verify_server_version
26
+ @api.verify_build_dir_matches_cartfile_resolved
27
+
24
28
  pool = Concurrent::FixedThreadPool.new(THREAD_POOL_SIZE)
25
29
 
26
30
  $LOG.debug("Will upload frameworks: #{@config.all_framework_names}")
27
31
 
32
+ @mutex = Mutex.new
28
33
  @number_of_uploaded_archives = 0
29
34
  @number_of_skipped_archives = 0
30
35
  @total_archive_size = 0
31
36
  errors = Concurrent::Array.new
32
37
 
33
- for carthage_dependency in @config.carthage_dependencies
38
+ for carthage_dependency in @config.carthage_resolved_dependencies
34
39
  pool.post(carthage_dependency) do |carthage_dependency|
35
40
  begin
36
41
  upload(carthage_dependency)
@@ -55,13 +60,13 @@ class UploadCommand
55
60
  private
56
61
 
57
62
  def upload(carthage_dependency)
58
- version_file = VersionFile.new(carthage_dependency.version_filepath)
59
-
60
- carthage_dependency.validate_version_file(version_file)
63
+ version_file = carthage_dependency.new_version_file
61
64
 
62
- if @api.version_file_matches_server?(carthage_dependency, version_file)
65
+ if @api.version_file_matches_server?(carthage_dependency, version_file, nil)
63
66
  $LOG.debug("Version file #{version_file.path} matches server version, skipping upload")
64
- @number_of_skipped_archives += version_file.number_of_frameworks
67
+ @mutex.synchronize do
68
+ @number_of_skipped_archives += version_file.number_of_frameworks
69
+ end
65
70
  return
66
71
  end
67
72
 
@@ -70,8 +75,10 @@ class UploadCommand
70
75
  version_file.frameworks_by_platform.each do |platform, framework_names|
71
76
  for framework_name in framework_names
72
77
  archive_size = @api.create_and_upload_archive(carthage_dependency, framework_name, platform)
73
- @number_of_uploaded_archives += 1
74
- @total_archive_size += archive_size
78
+ @mutex.synchronize do
79
+ @number_of_uploaded_archives += 1
80
+ @total_archive_size += archive_size
81
+ end
75
82
  end
76
83
  end
77
84
  end
@@ -0,0 +1,18 @@
1
+ class VerifyCommand
2
+ def self.new_with_defaults(options)
3
+ shell = ShellWrapper.new
4
+ config = Configuration.new(shell)
5
+ networking = Networking.new(config, options[:is_retry_enabled])
6
+ api = API.new(shell, config, networking, options)
7
+
8
+ VerifyCommand.new(api: api)
9
+ end
10
+
11
+ def initialize(args)
12
+ @api = args[:api]
13
+ end
14
+
15
+ def run
16
+ @api.verify_build_dir_matches_cartfile_resolved
17
+ end
18
+ end
data/lib/configuration.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'uri'
1
+ require "uri"
2
2
 
3
3
  class Configuration
4
4
  class UserConfig
@@ -11,14 +11,15 @@ class Configuration
11
11
  yield(@@user_config)
12
12
  end
13
13
 
14
- attr_reader :xcodebuild_version, :swift_version, :carthage_dependencies, :server_uri
14
+ attr_reader :carthage_resolved_dependencies, :server_uri
15
15
 
16
16
  def self.new_with_defaults
17
17
  Configuration.new(ShellWrapper.new)
18
18
  end
19
19
 
20
20
  def initialize(shell)
21
- initialize_env(shell)
21
+ @shell = shell
22
+ initialize_cartfile_resolved
22
23
  initialize_cartrcfile
23
24
  end
24
25
 
@@ -26,16 +27,40 @@ class Configuration
26
27
  version_files.flat_map { |vf| vf.framework_names }.uniq.sort
27
28
  end
28
29
 
30
+ # Ensure, that these lazy properties are loaded before kicking off async code.
31
+ def ensure_shell_commands
32
+ xcodebuild_version
33
+ swift_version
34
+ end
35
+
36
+ def xcodebuild_version
37
+ if @xcodebuild_version.nil?
38
+ xcodebuild_raw_version = @shell.xcodebuild_version
39
+ @xcodebuild_version = xcodebuild_raw_version[/Build version (.*)$/, 1]
40
+ raise AppError.new, "Could not parse build version from '#{xcodebuild_raw_version}'" if @xcodebuild_version.nil?
41
+ end
42
+ @xcodebuild_version
43
+ end
44
+
45
+ def swift_version
46
+ if @swift_version.nil?
47
+ swift_raw_version = @shell.swift_version
48
+ @swift_version = swift_raw_version[/Apple Swift version (.*) \(/, 1]
49
+ raise AppError.new, "Could not parse swift version from '#{raw_swift_version}'" if @swift_version.nil?
50
+ end
51
+ @swift_version
52
+ end
53
+
29
54
  def to_s
30
55
  <<~EOS
31
- Xcodebuild: #{@xcodebuild_version}
56
+ Xcodebuild: #{xcodebuild_version}
32
57
  ---
33
- Swift: #{@swift_version}
58
+ Swift: #{swift_version}
34
59
  ---
35
60
  Server: #{@server_uri.to_s}
36
61
  ---
37
62
  Cartfile.resolved:
38
- #{@carthage_dependencies.join("\n")}
63
+ #{@carthage_resolved_dependencies.join("\n")}
39
64
  ---
40
65
  Local Build Frameworks:
41
66
  #{framework_names_with_platforms.join("\n")}
@@ -44,17 +69,9 @@ class Configuration
44
69
 
45
70
  private
46
71
 
47
- def initialize_env(shell)
48
- xcodebuild_raw_version = shell.xcodebuild_version
49
- @xcodebuild_version = xcodebuild_raw_version[/Build version (.*)$/, 1]
50
- raise AppError.new, "Could not parse build version from '#{xcodebuild_raw_version}'" if @xcodebuild_version.nil?
51
-
52
- swift_raw_version = shell.swift_version
53
- @swift_version = swift_raw_version[/Apple Swift version (.*) \(/, 1]
54
- raise AppError.new, "Could not parse swift version from '#{raw_swift_version}'" if @swift_version.nil?
55
-
72
+ def initialize_cartfile_resolved
56
73
  raise AppError.new, "Misssing #{CARTFILE_RESOLVED}" unless File.exist?(CARTFILE_RESOLVED)
57
- @carthage_dependencies = File.readlines(CARTFILE_RESOLVED)
74
+ @carthage_resolved_dependencies = File.readlines(CARTFILE_RESOLVED)
58
75
  .map { |line| CarthageDependency.parse_cartfile_resolved_line(line) }
59
76
  .compact
60
77
  end
@@ -79,6 +96,6 @@ class Configuration
79
96
  end
80
97
 
81
98
  def version_files
82
- @carthage_dependencies.map { |d| VersionFile.new(d.version_filepath) }
99
+ @carthage_resolved_dependencies.map { |d| d.new_version_file }
83
100
  end
84
101
  end