carthage_cache_res 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,134 @@
1
+ module CarthageCacheRes
2
+
3
+ class MissingConfigurationKey < Struct.new(:keyname, :solution)
4
+
5
+ def self.missing_bucket_name
6
+ solution = "You need to specify the AWS S3 bucket to be used.\n" \
7
+ "You can either pass the '--bucket-name' option or " \
8
+ " add ':bucket_name: YOUR_BUCKET_NAME' to " \
9
+ ".carthage_cache_res.yml file.\nYou can also run " \
10
+ "'carthage_cache_res config' to generate the config file."
11
+ self.new(:bucket_name, solution)
12
+ end
13
+
14
+ def self.missing_aws_key(keyname, name)
15
+ solution = "You need to specify the AWS #{name} to be used.\n" \
16
+ "You can either define a environmental variable " \
17
+ "AWS_REGION or add ':#{keyname}: YOUR_KEY_VALUE' " \
18
+ "under the :aws_s3_client_options: key in the " \
19
+ ".carthage_cache_res.yml file.\nYou can also run " \
20
+ "'carthage_cache_res config' to generate the config file."
21
+ self.new("aws_s3_client_options.#{keyname}", solution)
22
+ end
23
+
24
+ def self.missing_aws_region
25
+ missing_aws_key("region", "region")
26
+ end
27
+
28
+ def self.missing_aws_access_key_id
29
+ missing_aws_key("access_key_id", "access key ID")
30
+ end
31
+
32
+ def self.missing_aws_secret_access_key
33
+ missing_aws_key("secret_access_key", "secret access key")
34
+ end
35
+
36
+ end
37
+
38
+ class ValidationResult
39
+
40
+ def self.valid
41
+ self.new(nil)
42
+ end
43
+
44
+ def self.invalid(error)
45
+ self.new(error)
46
+ end
47
+
48
+ attr_reader :error
49
+
50
+ def initialize(error)
51
+ @error = error
52
+ end
53
+
54
+ def valid?
55
+ @error == nil
56
+ end
57
+
58
+ end
59
+
60
+ class ConfigurationValidator
61
+
62
+ attr_reader :config
63
+
64
+ def initialize(config)
65
+ @config = config
66
+ end
67
+
68
+ def valid?
69
+ validate.valid?
70
+ end
71
+
72
+ def read_only?
73
+ (config.aws_access_key_id.nil? || config.aws_secret_access_key.nil?) && config.aws_profile.nil?
74
+ end
75
+
76
+ def validate
77
+ return missing_bucket_name unless has_bucket_name?
78
+ return missing_aws_region unless has_aws_region?
79
+
80
+ return missing_aws_access_key_id if is_missing_aws_access_key_id?
81
+ return missing_aws_secret_access_key if is_missing_aws_secret_access_key?
82
+
83
+ ValidationResult.valid
84
+ end
85
+
86
+ private
87
+
88
+ def is_missing_aws_access_key_id?
89
+ !has_aws_profile? && !has_aws_access_key_id? && has_aws_secret_access_key?
90
+ end
91
+
92
+ def is_missing_aws_secret_access_key?
93
+ !has_aws_profile? && has_aws_access_key_id? && !has_aws_secret_access_key?
94
+ end
95
+
96
+ def has_bucket_name?
97
+ config.bucket_name
98
+ end
99
+
100
+ def has_aws_region?
101
+ config.aws_region
102
+ end
103
+
104
+ def has_aws_access_key_id?
105
+ config.aws_access_key_id
106
+ end
107
+
108
+ def has_aws_secret_access_key?
109
+ config.aws_secret_access_key
110
+ end
111
+
112
+ def has_aws_profile?
113
+ config.aws_profile
114
+ end
115
+
116
+ def missing_bucket_name
117
+ ValidationResult.invalid(MissingConfigurationKey.missing_bucket_name)
118
+ end
119
+
120
+ def missing_aws_region
121
+ ValidationResult.invalid(MissingConfigurationKey.missing_aws_region)
122
+ end
123
+
124
+ def missing_aws_access_key_id
125
+ ValidationResult.invalid(MissingConfigurationKey.missing_aws_access_key_id)
126
+ end
127
+
128
+ def missing_aws_secret_access_key
129
+ ValidationResult.invalid(MissingConfigurationKey.missing_aws_secret_access_key)
130
+ end
131
+
132
+ end
133
+
134
+ end
@@ -0,0 +1,79 @@
1
+ require "yaml"
2
+
3
+ module CarthageCacheRes
4
+
5
+ class Configurator
6
+
7
+ CONFIG_FILE_NAME = ".carthage_cache_res.yml"
8
+
9
+ attr_reader :config_file_path
10
+ attr_reader :base_config
11
+ attr_reader :terminal
12
+
13
+ def initialize(terminal, project_path, base_config = {})
14
+ @config_file_path = File.join(project_path, CONFIG_FILE_NAME)
15
+ @base_config = merge_config(base_config)
16
+ @terminal = terminal
17
+ end
18
+
19
+ def config
20
+ @config ||= load_config!
21
+ end
22
+
23
+ def save_config(config)
24
+ raise "Invalid configuration" unless config.valid?
25
+ File.open(config_file_path, 'w') { |f| f.write config.to_yaml }
26
+ end
27
+
28
+ private
29
+
30
+ def config_file_exist?
31
+ File.exist?(config_file_path)
32
+ end
33
+
34
+ def load_config!
35
+ config = load_config
36
+ validate!(config)
37
+ config
38
+ end
39
+
40
+ def load_config
41
+ if config_file_exist?
42
+ config = Configuration.parse(File.read(config_file_path))
43
+ config = base_config.merge(config)
44
+ else
45
+ base_config
46
+ end
47
+ end
48
+
49
+ def validate!(config)
50
+ validator = ConfigurationValidator.new(config)
51
+ result = validator.validate
52
+ unless result.valid?
53
+ terminal.error "error: #{result.error.solution}"
54
+ exit 1
55
+ end
56
+ end
57
+
58
+ def remove_nil_keys(hash)
59
+ hash.inject({}) do |new_hash, (k,v)|
60
+ unless v.nil? || (v.respond_to?(:empty?) && v.empty?)
61
+ if v.class == Hash
62
+ cleaned_hashed = remove_nil_keys(v)
63
+ new_hash[k] = cleaned_hashed unless cleaned_hashed.empty?
64
+ else
65
+ new_hash[k] = v
66
+ end
67
+ end
68
+ new_hash
69
+ end
70
+ end
71
+
72
+ def merge_config(config)
73
+ new_config = Configuration.default.hash_object.merge(config)
74
+ Configuration.new(remove_nil_keys(new_config))
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,49 @@
1
+ module CarthageCacheRes
2
+
3
+ class ConfiguratorWizard
4
+
5
+ def initialize(ask_proc, password_proc)
6
+ @ask_proc = ask_proc
7
+ @password_proc = password_proc
8
+ end
9
+
10
+ def start
11
+ config = Configuration.new
12
+ config.bucket_name = ask("What is the Amazon S3 bucket name?", ENV["CARTHAGE_CACHE_DEFAULT_BUCKET_NAME"])
13
+ config.archive_base_path = ask("What base path do you want to use as archive's prefix? (default none)", nil)
14
+ config.prune_on_publish = confirm("Do you want to prune unused framework when publishing?")
15
+ config.aws_region = ask("What is the Amazon S3 region?")
16
+ config.aws_access_key_id = password("What is the AWS access key?")
17
+ config.aws_secret_access_key = password(" What is the AWS secret access key?")
18
+ config.aws_session_token = ask("What is the AWS session token (optional)?", nil, "*")
19
+ config
20
+ end
21
+
22
+ private
23
+
24
+ def ask(message, default_value = nil, mask = nil)
25
+ message = "#{message} [#{default_value}]" if default_value
26
+ if mask
27
+ answer = @ask_proc.call(message) { |q| q.echo = mask }
28
+ else
29
+ answer = @ask_proc.call(message)
30
+ end
31
+
32
+ if answer.empty?
33
+ default_value
34
+ else
35
+ answer
36
+ end
37
+ end
38
+
39
+ def confirm(message)
40
+ ask("#{message} [N/y]", 'N').downcase == 'y'
41
+ end
42
+
43
+ def password(message)
44
+ @password_proc.call(message)
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,3 @@
1
+ module CarthageCacheRes
2
+ DESCRIPTION = "A tool that allows to cache Carthage/Build folder in Amazon S3."
3
+ end
@@ -0,0 +1,66 @@
1
+ module CarthageCacheRes
2
+
3
+ class Project
4
+
5
+ attr_reader :cartfile
6
+ attr_reader :project_path
7
+ attr_reader :archive_base_path
8
+ attr_reader :cache_dir_name
9
+ attr_reader :terminal
10
+ attr_reader :tmpdir_base_path
11
+
12
+ def initialize(project_path, cache_dir_name, archive_base_path, terminal, tmpdir, swift_version_resolver = SwiftVersionResolver.new)
13
+ @project_path = project_path
14
+ @cache_dir_name = cache_dir_name
15
+ @archive_base_path = archive_base_path
16
+ @terminal = terminal
17
+ @tmpdir_base_path = tmpdir
18
+ @cartfile = CartfileResolvedFile.new(cartfile_resolved_path, terminal, swift_version_resolver)
19
+ end
20
+
21
+ def archive_filename
22
+ @archive_filename ||= "#{archive_key}.zip"
23
+ end
24
+
25
+ def archive_path
26
+ if @archive_base_path.nil?
27
+ @archive_path ||= archive_filename
28
+ else
29
+ @archive_path ||= File.join(archive_base_path, archive_filename)
30
+ end
31
+ end
32
+
33
+ def archive_key
34
+ cartfile.digest
35
+ end
36
+
37
+ def tmpdir
38
+ @tmpdir ||= create_tmpdir
39
+ end
40
+
41
+ def carthage_build_directory
42
+ @carthage_build_directory ||= File.join(project_path, "Carthage", "Build")
43
+ end
44
+
45
+ def all_frameworks
46
+ cartfile.frameworks
47
+ end
48
+
49
+ private
50
+
51
+ def cartfile_resolved_path
52
+ @carfile_resolved_path ||= File.join(project_path, "Cartfile.resolved")
53
+ end
54
+
55
+ def create_tmpdir
56
+ dir = File.join(tmpdir_base_path, cache_dir_name)
57
+ unless File.exist?(dir)
58
+ terminal.vputs "Creating carthage cache directory at '#{dir}'."
59
+ FileUtils.mkdir_p(dir)
60
+ end
61
+ dir
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,58 @@
1
+ require "aws-sdk"
2
+
3
+ module CarthageCacheRes
4
+
5
+ class AWSRepository
6
+
7
+ attr_reader :client
8
+ attr_reader :bucket_name
9
+
10
+ def initialize(bucket_name, client_options = {})
11
+ @client = ::Aws::S3::Client.new(client_options)
12
+ @bucket_name = bucket_name
13
+ end
14
+
15
+ def archive_exist?(archive_filename)
16
+ ::Aws::S3::Object.new(bucket_name, archive_filename, client: client).exists?
17
+ end
18
+
19
+ def download(archive_filename, destination_path)
20
+ resp = client.get_object(
21
+ response_target: destination_path,
22
+ bucket: bucket_name,
23
+ key: archive_filename)
24
+ end
25
+
26
+ def upload(archive_filename, archive_path)
27
+ File.open(archive_path, 'rb') do |file|
28
+ client.put_object(bucket: bucket_name, key: archive_filename, body: file)
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ class HTTPRepository
35
+
36
+ attr_reader :base_url
37
+
38
+ def initialize(bucket_name, client_options = {})
39
+ region = client_options[:region]
40
+ bucket_name = bucket_name
41
+ @base_url = "https://s3-#{region}.amazonaws.com/#{bucket_name}"
42
+ end
43
+
44
+ def archive_exist?(archive_filename)
45
+ system "wget", "--method=HEAD", "#{base_url}/#{archive_filename}", "-q"
46
+ end
47
+
48
+ def download(archive_filename, destination_path)
49
+ system "wget", "--output-document=#{destination_path}", "#{base_url}/#{archive_filename}", "-q"
50
+ end
51
+
52
+ def upload(archive_filename, archive_path)
53
+ raise "carthage_cache_res is working in read-only mode. Please configure AWS credentials first"
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,11 @@
1
+ module CarthageCacheRes
2
+
3
+ class ShellCommandExecutor
4
+
5
+ def execute(command)
6
+ `#{command}`
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,17 @@
1
+ module CarthageCacheRes
2
+
3
+ class SwiftVersionResolver
4
+
5
+ def initialize(executor = ShellCommandExecutor.new)
6
+ @executor = executor
7
+ end
8
+
9
+ def swift_version
10
+ output = @executor.execute('xcrun swift -version').chomp
11
+ version_string = /(\d+\.)?(\d+\.)?(\d+)/.match(output).to_s
12
+ Gem::Version.new(version_string)
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,25 @@
1
+ module CarthageCacheRes
2
+
3
+ class Terminal
4
+
5
+ attr_reader :verbose
6
+
7
+ def initialize(verbose = false)
8
+ @verbose = verbose
9
+ end
10
+
11
+ def puts(message)
12
+ Kernel.puts(message)
13
+ end
14
+
15
+ def vputs(message)
16
+ puts(message) if verbose
17
+ end
18
+
19
+ def error(message)
20
+ STDERR.puts(message)
21
+ end
22
+
23
+ end
24
+
25
+ end