carthage_remote_cache 0.0.8 → 0.0.11
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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +38 -0
- data/.ruby-version +2 -0
- data/.travis.yml +1 -1
- data/Dockerfile +7 -0
- data/Gemfile.lock +41 -41
- data/Guardfile +2 -2
- data/README.md +38 -5
- data/Rakefile +2 -2
- data/bin/carthagerc +18 -8
- data/carthage_remote_cache.gemspec +4 -4
- data/dev/start_server +1 -1
- data/lib/api.rb +10 -10
- data/lib/carthage_archive.rb +13 -51
- data/lib/carthage_remote_cache.rb +18 -14
- data/lib/commands/download_command.rb +10 -9
- data/lib/commands/server_command.rb +2 -2
- data/lib/commands/upload_command.rb +6 -6
- data/lib/commands/verify_command.rb +1 -1
- data/lib/commands.rb +5 -5
- data/lib/configuration.rb +1 -1
- data/lib/constants.rb +9 -7
- data/lib/crc32.rb +3 -3
- data/lib/errors.rb +12 -1
- data/lib/framework.rb +19 -0
- data/lib/framework_carthage_archive.rb +57 -0
- data/lib/log.rb +1 -1
- data/lib/networking.rb +81 -41
- data/lib/server/config.ru +3 -3
- data/lib/server/server_app.rb +69 -12
- data/lib/shell_wrapper.rb +1 -1
- data/lib/table.rb +4 -4
- data/lib/utils.rb +26 -12
- data/lib/version.rb +1 -1
- data/lib/version_file.rb +66 -20
- data/lib/xcframework.rb +29 -0
- data/lib/xcframework_carthage_archive.rb +17 -0
- metadata +36 -18
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
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)
|
7
|
+
networking = Networking.new(config, options[:is_retry_enabled])
|
8
8
|
api = API.new(shell, config, networking, options)
|
9
9
|
|
10
10
|
UploadCommand.new(
|
@@ -62,7 +62,7 @@ class UploadCommand
|
|
62
62
|
def upload(carthage_dependency)
|
63
63
|
version_file = carthage_dependency.new_version_file
|
64
64
|
|
65
|
-
if @api.version_file_matches_server?(carthage_dependency, version_file)
|
65
|
+
if @api.version_file_matches_server?(carthage_dependency, version_file, nil)
|
66
66
|
$LOG.debug("Version file #{version_file.path} matches server version, skipping upload")
|
67
67
|
@mutex.synchronize do
|
68
68
|
@number_of_skipped_archives += version_file.number_of_frameworks
|
@@ -72,9 +72,9 @@ class UploadCommand
|
|
72
72
|
|
73
73
|
@networking.upload_version_file(carthage_dependency)
|
74
74
|
|
75
|
-
version_file.frameworks_by_platform.each do |platform,
|
76
|
-
for
|
77
|
-
archive_size = @api.create_and_upload_archive(carthage_dependency,
|
75
|
+
version_file.frameworks_by_platform.each do |platform, frameworks|
|
76
|
+
for framework in frameworks
|
77
|
+
archive_size = @api.create_and_upload_archive(carthage_dependency, framework, platform)
|
78
78
|
@mutex.synchronize do
|
79
79
|
@number_of_uploaded_archives += 1
|
80
80
|
@total_archive_size += archive_size
|
@@ -2,7 +2,7 @@ class VerifyCommand
|
|
2
2
|
def self.new_with_defaults(options)
|
3
3
|
shell = ShellWrapper.new
|
4
4
|
config = Configuration.new(shell)
|
5
|
-
networking = Networking.new(config)
|
5
|
+
networking = Networking.new(config, options[:is_retry_enabled])
|
6
6
|
api = API.new(shell, config, networking, options)
|
7
7
|
|
8
8
|
VerifyCommand.new(api: api)
|
data/lib/commands.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
lib = File.expand_path("..", __FILE__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
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"
|
data/lib/configuration.rb
CHANGED
data/lib/constants.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
CARTHAGE_DIR =
|
2
|
-
CARTHAGE_BUILD_DIR = File.join(CARTHAGE_DIR,
|
3
|
-
CARTFILE_RESOLVED =
|
4
|
-
CARTRCFILE =
|
1
|
+
CARTHAGE_DIR = "Carthage"
|
2
|
+
CARTHAGE_BUILD_DIR = File.join(CARTHAGE_DIR, "Build")
|
3
|
+
CARTFILE_RESOLVED = "Cartfile.resolved"
|
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,
|
8
|
+
SERVER_CACHE_DIR = File.join(Dir.home, ".carthagerc_server")
|
9
9
|
|
10
10
|
ARCHIVE_CHECKSUM_HEADER_REST_CLIENT = :archive_checksum
|
11
|
-
ARCHIVE_CHECKSUM_HEADER_SINATRA_IN =
|
12
|
-
ARCHIVE_CHECKSUM_HEADER_SINATRA_OUT =
|
11
|
+
ARCHIVE_CHECKSUM_HEADER_SINATRA_IN = "HTTP_ARCHIVE_CHECKSUM"
|
12
|
+
ARCHIVE_CHECKSUM_HEADER_SINATRA_OUT = "Archive-Checksum"
|
13
|
+
|
14
|
+
PLATFORMS = [:iOS, :macOS, :tvOS, :watchOS]
|
data/lib/crc32.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "digest"
|
2
|
+
require "zlib"
|
3
3
|
|
4
4
|
class Digest::CRC32 < Digest::Class
|
5
5
|
include Digest::Instance
|
@@ -17,6 +17,6 @@ class Digest::CRC32 < Digest::Class
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def finish
|
20
|
-
[@crc32].pack(
|
20
|
+
[@crc32].pack("N")
|
21
21
|
end
|
22
22
|
end
|
data/lib/errors.rb
CHANGED
@@ -51,7 +51,7 @@ class FrameworkValidationError < AppError
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def to_s
|
54
|
-
header = [
|
54
|
+
header = ["Framework", CARTHAGE_BUILD_DIR, CARTFILE_RESOLVED]
|
55
55
|
rows = @errors.map { |e| [e.framework_name, e.build_version, e.cartfile_resolved_version] }
|
56
56
|
table = Table.new(header, rows)
|
57
57
|
<<~EOS
|
@@ -69,3 +69,14 @@ end
|
|
69
69
|
class MissingFrameworkDirectoryError < AppError; end
|
70
70
|
|
71
71
|
class ServerVersionMismatchError < AppError; end
|
72
|
+
|
73
|
+
class PlatformMismatchError < AppError
|
74
|
+
def initialize(platform)
|
75
|
+
@platform = platform
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_s
|
79
|
+
platforms = PLATFORMS.map(&:to_s).join(", ")
|
80
|
+
"Platform '#{@platform}' doesn't match any of: #{platforms}"
|
81
|
+
end
|
82
|
+
end
|
data/lib/framework.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Example data:
|
2
|
+
# - "name" : "Sentry",
|
3
|
+
# - "linking" : "dynamic"
|
4
|
+
class Framework
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def self.parse(json)
|
8
|
+
Framework.new(json["name"], json["linking"])
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(name, linking)
|
12
|
+
@name = name
|
13
|
+
@linking = linking
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_archive(platform)
|
17
|
+
FrameworkCarthageArchive.new(name, platform)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
class FrameworkCarthageArchive < CarthageArchive
|
4
|
+
|
5
|
+
# Aggregate following files:
|
6
|
+
# - Carthage/Build/iOS/Alamofire.framework
|
7
|
+
# - Carthage/Build/iOS/Alamofire.framework/Alamofire
|
8
|
+
# - Carthage/Build/iOS/618BEB79-4C7F-3692-B140-131FB983AC5E.bcsymbolmap
|
9
|
+
# into Alamofire-iOS.zip
|
10
|
+
def compress_archive(shell, carthage_build_dir = CARTHAGE_BUILD_DIR)
|
11
|
+
$LOG.debug("Archiving #{@framework_name} for #{@platform}")
|
12
|
+
|
13
|
+
platform_path = File.join(carthage_build_dir, platform_to_carthage_dir_string(@platform))
|
14
|
+
framework_path = File.join(platform_path, "#{@framework_name}.framework")
|
15
|
+
raise MissingFrameworkDirectoryError.new, "Archive can't be created, no framework directory at #{framework_path}" unless Dir.exist?(framework_path)
|
16
|
+
|
17
|
+
# It's very likely, that binary releases don't contain DSYMs.
|
18
|
+
dsym_path = File.join(platform_path, "#{@framework_name}.framework.dSYM")
|
19
|
+
unless File.exist?(dsym_path)
|
20
|
+
$LOG.error("DSYM File #{dsym_path} not found, continuing")
|
21
|
+
dsym_path = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
binary_path = File.join(framework_path, @framework_name)
|
25
|
+
raise AppError.new, "Binary #{binary_path} is missing, failed to read .bcsymbolmap files" unless File.exist?(binary_path)
|
26
|
+
|
27
|
+
bcsymbolmap_paths = find_bcsymbolmap_paths(shell, platform_path, binary_path)
|
28
|
+
|
29
|
+
input_paths = []
|
30
|
+
input_paths << framework_path
|
31
|
+
input_paths << dsym_path unless dsym_path.nil?
|
32
|
+
input_paths += bcsymbolmap_paths
|
33
|
+
|
34
|
+
$LOG.debug("Adding > #{input_paths.inspect}")
|
35
|
+
|
36
|
+
delete_archive
|
37
|
+
shell.archive(input_paths, @archive_path)
|
38
|
+
$LOG.debug("Created #{@archive_path} archive, file size: #{formatted_archive_size}")
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def find_bcsymbolmap_paths(shell, platform_path, binary_path)
|
44
|
+
raw_dwarfdump = shell.dwarfdump(binary_path)
|
45
|
+
uuids = parse_uuids(raw_dwarfdump)
|
46
|
+
bcsymbolmap_paths = uuids.map { |uuid| File.join(platform_path, "#{uuid}.bcsymbolmap") }.select { |path| File.exist?(path) }
|
47
|
+
bcsymbolmap_paths
|
48
|
+
end
|
49
|
+
|
50
|
+
# Example dwarfdump link:
|
51
|
+
# UUID: 618BEB79-4C7F-3692-B140-131FB983AC5E (i386) Carthage/Build/iOS/CocoaLumberjackSwift.framework/CocoaLumberjackSwift
|
52
|
+
def parse_uuids(raw_dwarfdump)
|
53
|
+
lines = raw_dwarfdump.split("\n")
|
54
|
+
uuids = lines.map { |line| line[/^UUID: ([A-Z0-9\-]+)\s+\(.*$/, 1] }
|
55
|
+
uuids.compact
|
56
|
+
end
|
57
|
+
end
|
data/lib/log.rb
CHANGED
data/lib/networking.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "rest-client"
|
2
|
+
require "uri"
|
3
3
|
|
4
4
|
class Networking
|
5
|
-
def initialize(config)
|
5
|
+
def initialize(config, is_retry_enabled)
|
6
6
|
@config = config
|
7
|
+
@is_retry_enabled = is_retry_enabled
|
7
8
|
end
|
8
9
|
|
9
10
|
# Version
|
@@ -11,11 +12,13 @@ class Networking
|
|
11
12
|
def get_server_version
|
12
13
|
url = new_version_url
|
13
14
|
$LOG.debug("Fetching server version from #{url}")
|
14
|
-
server_version =
|
15
|
-
|
16
|
-
response.
|
17
|
-
|
18
|
-
|
15
|
+
server_version = perform_network_request do
|
16
|
+
RestClient.get(url) do |response, request, result|
|
17
|
+
if response.code == 200
|
18
|
+
response.strip
|
19
|
+
else
|
20
|
+
raise AppError.new, "Failed to read server version from #{url}, response:\n #{response[0...300]}"
|
21
|
+
end
|
19
22
|
end
|
20
23
|
end
|
21
24
|
server_version
|
@@ -24,15 +27,22 @@ class Networking
|
|
24
27
|
# Version Files
|
25
28
|
|
26
29
|
# @return VersionFile or nil
|
27
|
-
def download_version_file(carthage_dependency)
|
30
|
+
def download_version_file(carthage_dependency, platforms)
|
28
31
|
url = new_version_file_url(carthage_dependency)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
params = {}
|
33
|
+
unless platforms.nil?
|
34
|
+
params[:platform] = platforms.map(&:to_s).join(",")
|
35
|
+
end
|
36
|
+
|
37
|
+
version_file = perform_network_request do
|
38
|
+
$LOG.debug("Downloading version file from #{url}, params: #{params}")
|
39
|
+
RestClient.get(url, { params: params }) do |response, request, result|
|
40
|
+
if response.code == 200
|
41
|
+
File.write(carthage_dependency.version_filename, response.to_s)
|
42
|
+
VersionFile.new(carthage_dependency.version_filename)
|
43
|
+
else
|
44
|
+
nil
|
45
|
+
end
|
36
46
|
end
|
37
47
|
end
|
38
48
|
version_file
|
@@ -41,10 +51,12 @@ class Networking
|
|
41
51
|
# @raise AppError on upload failure
|
42
52
|
def upload_version_file(carthage_dependency)
|
43
53
|
url = new_version_file_url(carthage_dependency)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
54
|
+
perform_network_request do
|
55
|
+
$LOG.debug("Uploading #{carthage_dependency.version_filename}")
|
56
|
+
RestClient.post(url, :version_file => File.new(carthage_dependency.version_filepath)) do |response, request, result|
|
57
|
+
unless response.code == 200
|
58
|
+
raise AppError.new, "Version file upload #{carthage_dependency.version_filename} failed, response:\n #{response[0..300]}"
|
59
|
+
end
|
48
60
|
end
|
49
61
|
end
|
50
62
|
end
|
@@ -52,16 +64,18 @@ class Networking
|
|
52
64
|
# Archives
|
53
65
|
|
54
66
|
# @return Hash with CarthageArchive and checksum or nil
|
55
|
-
def download_framework_archive(carthage_dependency,
|
56
|
-
url = new_framework_url(carthage_dependency,
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
67
|
+
def download_framework_archive(carthage_dependency, framework, platform)
|
68
|
+
url = new_framework_url(carthage_dependency, framework.name, platform)
|
69
|
+
archive = perform_network_request do
|
70
|
+
$LOG.debug("Downloading framework from #{url}")
|
71
|
+
RestClient.get(url) do |response, request, result|
|
72
|
+
if response.code == 200
|
73
|
+
archive = framework.make_archive(platform)
|
74
|
+
File.write(archive.archive_path, response.to_s)
|
75
|
+
{ :archive => archive, :checksum => response.headers[ARCHIVE_CHECKSUM_HEADER_REST_CLIENT] }
|
76
|
+
else
|
77
|
+
nil
|
78
|
+
end
|
65
79
|
end
|
66
80
|
end
|
67
81
|
archive
|
@@ -70,12 +84,14 @@ class Networking
|
|
70
84
|
# @raise AppError when upload fails
|
71
85
|
def upload_framework_archive(zipfile_name, carthage_dependency, framework_name, platform, checksum)
|
72
86
|
url = new_framework_url(carthage_dependency, framework_name, platform)
|
73
|
-
params = {:framework_file => File.new(zipfile_name)}
|
74
|
-
headers = {ARCHIVE_CHECKSUM_HEADER_REST_CLIENT => checksum}
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
87
|
+
params = { :framework_file => File.new(zipfile_name) }
|
88
|
+
headers = { ARCHIVE_CHECKSUM_HEADER_REST_CLIENT => checksum }
|
89
|
+
perform_network_request do
|
90
|
+
$LOG.debug("Uploading framework to #{url}, headers: #{headers}")
|
91
|
+
RestClient.post(url, params, headers) do |response, request, result|
|
92
|
+
unless response.code == 200
|
93
|
+
raise AppError.new, "Framework upload #{zipfile_name} failed, response:\n #{response[0..300]}"
|
94
|
+
end
|
79
95
|
end
|
80
96
|
end
|
81
97
|
end
|
@@ -83,12 +99,12 @@ class Networking
|
|
83
99
|
private
|
84
100
|
|
85
101
|
def new_version_url
|
86
|
-
new_server_url([
|
102
|
+
new_server_url(["version"])
|
87
103
|
end
|
88
104
|
|
89
105
|
def new_version_file_url(carthage_dependency)
|
90
106
|
new_server_url([
|
91
|
-
|
107
|
+
"versions",
|
92
108
|
@config.xcodebuild_version,
|
93
109
|
@config.swift_version,
|
94
110
|
carthage_dependency.guessed_framework_basename,
|
@@ -99,7 +115,7 @@ class Networking
|
|
99
115
|
|
100
116
|
def new_framework_url(carthage_dependency, framework_name, platform)
|
101
117
|
new_server_url([
|
102
|
-
|
118
|
+
"frameworks",
|
103
119
|
@config.xcodebuild_version,
|
104
120
|
@config.swift_version,
|
105
121
|
carthage_dependency.guessed_framework_basename,
|
@@ -115,13 +131,37 @@ class Networking
|
|
115
131
|
:scheme => @config.server_uri.scheme,
|
116
132
|
:host => @config.server_uri.host,
|
117
133
|
:port => @config.server_uri.port,
|
118
|
-
:path =>
|
134
|
+
:path => "/" + sanitized_path_slices.join("/"),
|
119
135
|
)
|
120
136
|
uri.to_s
|
121
137
|
end
|
122
138
|
|
123
139
|
# Mangle identifiers for URL paths.
|
124
140
|
def sanitized(input)
|
125
|
-
input.gsub(/\//,
|
141
|
+
input.gsub(/\//, "_")
|
142
|
+
end
|
143
|
+
|
144
|
+
def perform_network_request
|
145
|
+
if @is_retry_enabled
|
146
|
+
retries_remaining = 3
|
147
|
+
sleep_time_seconds = 5
|
148
|
+
begin
|
149
|
+
result = yield
|
150
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
151
|
+
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
152
|
+
if retries_remaining > 0
|
153
|
+
$LOG.warn("Network request failed - remaining retries: #{retries_remaining}, sleeping for: #{sleep_time_seconds}s, error: #{e.message}")
|
154
|
+
sleep(sleep_time_seconds)
|
155
|
+
retries_remaining -= 1
|
156
|
+
sleep_time_seconds *= 3
|
157
|
+
retry
|
158
|
+
else
|
159
|
+
raise e
|
160
|
+
end
|
161
|
+
end
|
162
|
+
result
|
163
|
+
else
|
164
|
+
yield
|
165
|
+
end
|
126
166
|
end
|
127
167
|
end
|
data/lib/server/config.ru
CHANGED
data/lib/server/server_app.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
require "json"
|
2
|
+
require "sinatra"
|
3
|
+
require "fileutils"
|
4
|
+
require "carthage_remote_cache"
|
5
|
+
|
6
|
+
get "/" do
|
7
|
+
<<-eos
|
8
|
+
<html>
|
9
|
+
<p>Welcome to <strong>carthage_remote_cache</strong> (#{VERSION})</p>
|
10
|
+
<p>To browse cache contents visit <a href="/browser/">/browser/</a></p>
|
11
|
+
</html>
|
12
|
+
eos
|
7
13
|
end
|
8
14
|
|
9
|
-
version_path =
|
10
|
-
versions_path =
|
11
|
-
frameworks_path =
|
15
|
+
version_path = "/version"
|
16
|
+
versions_path = "/versions/:xcodebuild_version/:swift_version/:dependency_name/:version/:version_filename"
|
17
|
+
frameworks_path = "/frameworks/:xcodebuild_version/:swift_version/:dependency_name/:version/:framework_name/:platform"
|
18
|
+
browser_path = "/browser/*"
|
12
19
|
|
13
20
|
get version_path do
|
14
21
|
status(200)
|
@@ -16,13 +23,25 @@ get version_path do
|
|
16
23
|
end
|
17
24
|
|
18
25
|
get versions_path do
|
26
|
+
if params.key?(:platform)
|
27
|
+
begin
|
28
|
+
platforms = platform_to_symbols(params[:platform])
|
29
|
+
rescue AppError => e
|
30
|
+
status(400)
|
31
|
+
return JSON.pretty_generate({ "error" => e.message })
|
32
|
+
end
|
33
|
+
else
|
34
|
+
platforms = PLATFORMS
|
35
|
+
end
|
36
|
+
|
19
37
|
dirname = params_to_framework_dir(params)
|
20
38
|
filename = params[:version_filename]
|
21
39
|
filepath = File.join(dirname, filename)
|
22
40
|
|
23
41
|
if File.exist?(filepath)
|
24
42
|
status(200)
|
25
|
-
|
43
|
+
version_file = VersionFile.new(filepath, platforms)
|
44
|
+
JSON.pretty_generate(version_file.json)
|
26
45
|
else
|
27
46
|
status(404)
|
28
47
|
end
|
@@ -39,7 +58,7 @@ post versions_path do
|
|
39
58
|
File.delete(target_filename) if File.exist?(target_filename)
|
40
59
|
|
41
60
|
$LOG.info("Writing: #{target_filename}")
|
42
|
-
File.open(target_filename,
|
61
|
+
File.open(target_filename, "wb") do |target_file|
|
43
62
|
target_file.write(source_file.read)
|
44
63
|
end
|
45
64
|
|
@@ -75,7 +94,7 @@ post frameworks_path do
|
|
75
94
|
File.delete(target_filename) if File.exist?(target_filename)
|
76
95
|
|
77
96
|
$LOG.info("Writing: #{target_filename}")
|
78
|
-
File.open(target_filename,
|
97
|
+
File.open(target_filename, "wb") do |target_file|
|
79
98
|
target_file.write(source_file.read)
|
80
99
|
end
|
81
100
|
|
@@ -91,6 +110,44 @@ post frameworks_path do
|
|
91
110
|
end
|
92
111
|
end
|
93
112
|
|
113
|
+
# Full blown file browser.
|
114
|
+
get browser_path do
|
115
|
+
url_path = "/" + params["splat"][0]
|
116
|
+
path = File.join(SERVER_CACHE_DIR, url_path)
|
117
|
+
|
118
|
+
if File.file?(path)
|
119
|
+
status(200)
|
120
|
+
send_file(path)
|
121
|
+
else
|
122
|
+
html = "<html>"
|
123
|
+
|
124
|
+
# Current directory
|
125
|
+
html += "<h2>#{url_path}</h2>"
|
126
|
+
|
127
|
+
# ".." link
|
128
|
+
if url_path != "/"
|
129
|
+
parent = File.dirname(url_path)
|
130
|
+
parent += "/" if parent != "/"
|
131
|
+
html += "<p><a href=\"/browser#{parent}\">..</a></p>"
|
132
|
+
end
|
133
|
+
|
134
|
+
# Child links
|
135
|
+
for name in Dir.children(path).select { |name| name != ".DS_Store" }.sort
|
136
|
+
child_path = File.join(path, name)
|
137
|
+
html += "<p>"
|
138
|
+
if File.file?(child_path)
|
139
|
+
html += "<a href=\"#{name}\">#{name}</a> #{format_file_size(File.size(child_path))}"
|
140
|
+
else
|
141
|
+
html += "<a href=\"#{name}/\">#{name}/</a>"
|
142
|
+
end
|
143
|
+
html += " <span style=\"color:#777\">#{File.ctime(child_path).to_s}</span>"
|
144
|
+
html += "</p>"
|
145
|
+
end
|
146
|
+
|
147
|
+
html
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
94
151
|
private
|
95
152
|
|
96
153
|
def params_to_framework_dir(params)
|
data/lib/shell_wrapper.rb
CHANGED
data/lib/table.rb
CHANGED
@@ -32,8 +32,8 @@ class Table
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def separator_line
|
35
|
-
dashes = @column_sizes.map { |size|
|
36
|
-
|
35
|
+
dashes = @column_sizes.map { |size| "-" * size }
|
36
|
+
"+" + dashes.join("+") + "+"
|
37
37
|
end
|
38
38
|
|
39
39
|
def header_line
|
@@ -41,7 +41,7 @@ class Table
|
|
41
41
|
column_size = @column_sizes[index] - 1
|
42
42
|
" %-#{column_size}.#{column_size}s" % column
|
43
43
|
end
|
44
|
-
|
44
|
+
"|" + columns.join("|") + "|"
|
45
45
|
end
|
46
46
|
|
47
47
|
def row_line(row)
|
@@ -53,6 +53,6 @@ class Table
|
|
53
53
|
"%#{column_size}.#{column_size}s " % column
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
"|" + columns.join("|") + "|"
|
57
57
|
end
|
58
58
|
end
|
data/lib/utils.rb
CHANGED
@@ -15,7 +15,7 @@ end
|
|
15
15
|
def quote(input)
|
16
16
|
if input.is_a? String
|
17
17
|
if input.empty?
|
18
|
-
|
18
|
+
""
|
19
19
|
else
|
20
20
|
'"' + input + '"'
|
21
21
|
end
|
@@ -23,7 +23,7 @@ def quote(input)
|
|
23
23
|
input
|
24
24
|
.map { |e| quote(e) }
|
25
25
|
.select { |e| !e.empty? }
|
26
|
-
.join(
|
26
|
+
.join(" ")
|
27
27
|
else
|
28
28
|
raise AppError.new, "Unsupported type #{input}"
|
29
29
|
end
|
@@ -32,13 +32,13 @@ end
|
|
32
32
|
def platform_to_api_string(platform)
|
33
33
|
case platform
|
34
34
|
when :iOS
|
35
|
-
|
35
|
+
"iOS"
|
36
36
|
when :macOS
|
37
|
-
|
37
|
+
"macOS"
|
38
38
|
when :tvOS
|
39
|
-
|
39
|
+
"tvOS"
|
40
40
|
when :watchOS
|
41
|
-
|
41
|
+
"watchOS"
|
42
42
|
else
|
43
43
|
raise AppError.new, "Unrecognized platform #{platform.inspect}"
|
44
44
|
end
|
@@ -47,20 +47,34 @@ end
|
|
47
47
|
def platform_to_carthage_dir_string(platform)
|
48
48
|
case platform
|
49
49
|
when :iOS
|
50
|
-
|
50
|
+
"iOS"
|
51
51
|
when :macOS
|
52
|
-
|
52
|
+
"Mac"
|
53
53
|
when :tvOS
|
54
|
-
|
54
|
+
"tvOS"
|
55
55
|
when :watchOS
|
56
|
-
|
56
|
+
"watchOS"
|
57
57
|
else
|
58
58
|
raise AppError.new, "Unrecognized platform #{platform.inspect}"
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
def platform_to_symbols(string)
|
63
|
+
platforms = string.split(",").map(&:to_sym)
|
64
|
+
for platform in platforms
|
65
|
+
if !PLATFORMS.include?(platform)
|
66
|
+
raise PlatformMismatchError.new(platform)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
platforms
|
70
|
+
end
|
71
|
+
|
62
72
|
# @return string in "x.y MB" format
|
63
73
|
def format_file_size(bytes)
|
64
|
-
|
65
|
-
|
74
|
+
if bytes == 0
|
75
|
+
"0.0 MB"
|
76
|
+
else
|
77
|
+
megabytes = [0.1, bytes / 1000.0 / 1000.0].max
|
78
|
+
"#{megabytes.round(1)} MB"
|
79
|
+
end
|
66
80
|
end
|
data/lib/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION =
|
1
|
+
VERSION = "0.0.11"
|