gemstash 1.0.0.pre.1-java → 2.6.0-java
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/CHANGELOG.md +303 -0
- data/exe/gemstash +3 -0
- data/lib/gemstash/api_key_authorization.rb +32 -0
- data/lib/gemstash/authorization.rb +15 -8
- data/lib/gemstash/cache.rb +42 -2
- data/lib/gemstash/cli/authorize.rb +52 -9
- data/lib/gemstash/cli/base.rb +14 -6
- data/lib/gemstash/cli/setup.rb +67 -39
- data/lib/gemstash/cli/start.rb +6 -2
- data/lib/gemstash/cli/status.rb +3 -1
- data/lib/gemstash/cli/stop.rb +4 -1
- data/lib/gemstash/cli.rb +59 -1
- data/lib/gemstash/config.ru +4 -3
- data/lib/gemstash/configuration.rb +61 -8
- data/lib/gemstash/db/authorization.rb +5 -3
- data/lib/gemstash/db/cached_rubygem.rb +20 -0
- data/lib/gemstash/db/dependency.rb +2 -0
- data/lib/gemstash/db/rubygem.rb +3 -0
- data/lib/gemstash/db/upstream.rb +15 -0
- data/lib/gemstash/db/version.rb +25 -2
- data/lib/gemstash/db.rb +5 -0
- data/lib/gemstash/dependencies.rb +6 -2
- data/lib/gemstash/env.rb +44 -13
- data/lib/gemstash/gem_fetcher.rb +5 -3
- data/lib/gemstash/gem_pusher.rb +25 -18
- data/lib/gemstash/gem_source/dependency_caching.rb +4 -4
- data/lib/gemstash/gem_source/private_source.rb +34 -50
- data/lib/gemstash/gem_source/rack_middleware.rb +3 -0
- data/lib/gemstash/gem_source/upstream_source.rb +71 -27
- data/lib/gemstash/gem_source.rb +4 -2
- data/lib/gemstash/gem_yanker.rb +14 -4
- data/lib/gemstash/health.rb +55 -0
- data/lib/gemstash/http_client.rb +15 -5
- data/lib/gemstash/logging.rb +19 -7
- data/lib/gemstash/man/gemstash-authorize.1 +54 -0
- data/lib/gemstash/man/gemstash-authorize.1.txt +52 -0
- data/lib/gemstash/man/gemstash-configuration.5 +186 -0
- data/lib/gemstash/man/gemstash-configuration.5.txt +208 -0
- data/lib/gemstash/man/gemstash-customize.7 +273 -0
- data/lib/gemstash/man/gemstash-customize.7.txt +184 -0
- data/lib/gemstash/man/gemstash-debugging.7 +30 -0
- data/lib/gemstash/man/gemstash-debugging.7.txt +27 -0
- data/lib/gemstash/man/gemstash-deploy.7 +63 -0
- data/lib/gemstash/man/gemstash-deploy.7.txt +57 -0
- data/lib/gemstash/man/gemstash-mirror.7 +34 -0
- data/lib/gemstash/man/gemstash-mirror.7.txt +31 -0
- data/lib/gemstash/man/gemstash-multiple-sources.7 +131 -0
- data/lib/gemstash/man/gemstash-multiple-sources.7.txt +116 -0
- data/lib/gemstash/man/gemstash-private-gems.7 +191 -0
- data/lib/gemstash/man/gemstash-private-gems.7.txt +154 -0
- data/lib/gemstash/man/gemstash-readme.7 +199 -0
- data/lib/gemstash/man/gemstash-readme.7.txt +177 -0
- data/lib/gemstash/man/gemstash-setup.1 +38 -0
- data/lib/gemstash/man/gemstash-setup.1.txt +38 -0
- data/lib/gemstash/man/gemstash-start.1 +23 -0
- data/lib/gemstash/man/gemstash-start.1.txt +24 -0
- data/lib/gemstash/man/gemstash-status.1 +17 -0
- data/lib/gemstash/man/gemstash-status.1.txt +20 -0
- data/lib/gemstash/man/gemstash-stop.1 +17 -0
- data/lib/gemstash/man/gemstash-stop.1.txt +20 -0
- data/lib/gemstash/man/gemstash-version.1 +17 -0
- data/lib/gemstash/man/gemstash-version.1.txt +19 -0
- data/lib/gemstash/migrations/01_gem_dependencies.rb +11 -9
- data/lib/gemstash/migrations/02_authorizations.rb +4 -2
- data/lib/gemstash/migrations/03_cached_gems.rb +26 -0
- data/lib/gemstash/migrations/04_health_tests.rb +10 -0
- data/lib/gemstash/migrations/05_authorization_names.rb +10 -0
- data/lib/gemstash/puma.rb +5 -3
- data/lib/gemstash/rack_env_rewriter.rb +11 -2
- data/lib/gemstash/specs_builder.rb +25 -15
- data/lib/gemstash/storage.rb +175 -32
- data/lib/gemstash/upstream.rb +43 -8
- data/lib/gemstash/version.rb +4 -2
- data/lib/gemstash/web.rb +13 -8
- data/lib/gemstash.rb +6 -2
- metadata +135 -110
- data/.gitignore +0 -10
- data/.rspec +0 -2
- data/.rubocop-bundler.yml +0 -92
- data/.rubocop-relax.yml +0 -11
- data/.rubocop.yml +0 -8
- data/.travis.yml +0 -20
- data/Gemfile +0 -4
- data/README.md +0 -139
- data/Rakefile +0 -35
- data/bin/console +0 -14
- data/bin/gemstash +0 -3
- data/bin/setup +0 -5
- data/docs/config.md +0 -136
- data/docs/debug.md +0 -24
- data/docs/deploy.md +0 -30
- data/docs/mirror.md +0 -30
- data/docs/multiple_sources.md +0 -68
- data/docs/private_gems.md +0 -140
- data/docs/reference.md +0 -308
- data/gemstash.gemspec +0 -47
- data/gemstash.png +0 -0
- data/lib/gemstash/gem_unyanker.rb +0 -61
data/lib/gemstash/cli/base.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
|
|
3
5
|
module Gemstash
|
|
@@ -21,25 +23,31 @@ module Gemstash
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def check_rubygems_version
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
unless Gem::Requirement.new(">= 2.4").satisfied_by?(Gem::Version.new(Gem::VERSION))
|
|
27
|
+
@cli.say(@cli.set_color("Rubygems version is too old, " \
|
|
28
|
+
"please update rubygems by running: " \
|
|
29
|
+
"gem update --system", :red))
|
|
30
|
+
end
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
def store_config
|
|
31
34
|
config = Gemstash::Configuration.new(file: @cli.options[:config_file])
|
|
32
35
|
gemstash_env.config = config
|
|
36
|
+
rescue Gemstash::Configuration::MissingFileError => e
|
|
37
|
+
raise Gemstash::CLI::Error.new(@cli, e.message)
|
|
33
38
|
end
|
|
34
39
|
|
|
35
40
|
def check_gemstash_version
|
|
36
41
|
version = Gem::Version.new(Gemstash::Storage.metadata[:gemstash_version])
|
|
37
42
|
return if Gem::Requirement.new("<= #{Gemstash::VERSION}").satisfied_by?(Gem::Version.new(version))
|
|
38
|
-
|
|
43
|
+
|
|
44
|
+
raise Gemstash::CLI::Error.new(@cli, "Gemstash version #{Gemstash::VERSION} does not support version " \
|
|
45
|
+
"#{version}.\nIt appears you may have downgraded Gemstash, please " \
|
|
46
|
+
"install version #{version} or later.")
|
|
39
47
|
end
|
|
40
48
|
|
|
41
49
|
def pidfile_args
|
|
42
|
-
["--pidfile", gemstash_env.
|
|
50
|
+
["--pidfile", gemstash_env.pidfile]
|
|
43
51
|
end
|
|
44
52
|
end
|
|
45
53
|
end
|
data/lib/gemstash/cli/setup.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
require "fileutils"
|
|
3
5
|
require "yaml"
|
|
@@ -22,6 +24,8 @@ module Gemstash
|
|
|
22
24
|
ask_storage
|
|
23
25
|
ask_cache
|
|
24
26
|
ask_database
|
|
27
|
+
ask_protected_fetch
|
|
28
|
+
ask_timeout
|
|
25
29
|
check_cache
|
|
26
30
|
check_storage
|
|
27
31
|
check_database
|
|
@@ -42,9 +46,27 @@ module Gemstash
|
|
|
42
46
|
|
|
43
47
|
def say_current_config(option, label)
|
|
44
48
|
return if gemstash_env.config.default?(option)
|
|
49
|
+
|
|
45
50
|
@cli.say "#{label}: #{gemstash_env.config[option]}"
|
|
46
51
|
end
|
|
47
52
|
|
|
53
|
+
def ask_with_default(prompt, options, default)
|
|
54
|
+
raise "The options must all be lower case" if options.any? {|x| x.downcase != x }
|
|
55
|
+
|
|
56
|
+
result = nil
|
|
57
|
+
displayed_options = options.map {|x| x == default ? x.upcase : x }
|
|
58
|
+
prompt = "#{prompt} [#{displayed_options.join(", ")}]"
|
|
59
|
+
|
|
60
|
+
until result
|
|
61
|
+
result = @cli.ask prompt
|
|
62
|
+
result = result.downcase
|
|
63
|
+
result = default if result.empty?
|
|
64
|
+
result = nil unless options.include?(result)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
result
|
|
68
|
+
end
|
|
69
|
+
|
|
48
70
|
def ask_storage
|
|
49
71
|
say_current_config(:base_path, "Current base path")
|
|
50
72
|
path = @cli.ask "Where should files go? [~/.gemstash]", path: true
|
|
@@ -54,18 +76,9 @@ module Gemstash
|
|
|
54
76
|
|
|
55
77
|
def ask_cache
|
|
56
78
|
say_current_config(:cache_type, "Current cache")
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
until cache
|
|
61
|
-
cache = @cli.ask "Cache with what? [MEMORY, memcached]"
|
|
62
|
-
cache = cache.downcase
|
|
63
|
-
cache = "memory" if cache.empty?
|
|
64
|
-
cache = nil unless options.include?(cache)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
@config[:cache_type] = cache
|
|
68
|
-
ask_memcached_details if cache == "memcached"
|
|
79
|
+
@config[:cache_type] = ask_with_default("Cache with what?", %w[memory memcached redis], "memory")
|
|
80
|
+
ask_memcached_details if @config[:cache_type] == "memcached"
|
|
81
|
+
ask_redis_details if @config[:cache_type] == "redis"
|
|
69
82
|
end
|
|
70
83
|
|
|
71
84
|
def ask_memcached_details
|
|
@@ -75,29 +88,26 @@ module Gemstash
|
|
|
75
88
|
@config[:memcached_servers] = servers
|
|
76
89
|
end
|
|
77
90
|
|
|
91
|
+
def ask_redis_details
|
|
92
|
+
say_current_config(:redis_servers, "Current Redis servers")
|
|
93
|
+
servers = @cli.ask "What is the comma-separated list of Redis servers? [localhost:6379]"
|
|
94
|
+
servers = "localhost:6379" if servers.empty?
|
|
95
|
+
@config[:redis_servers] = servers
|
|
96
|
+
end
|
|
97
|
+
|
|
78
98
|
def ask_database
|
|
79
99
|
say_current_config(:db_adapter, "Current database adapter")
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
until database
|
|
84
|
-
database = @cli.ask "What database adapter? [SQLITE3, postgres]"
|
|
85
|
-
database = database.downcase
|
|
86
|
-
database = "sqlite3" if database.empty?
|
|
87
|
-
database = nil unless options.include?(database)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
@config[:db_adapter] = database
|
|
91
|
-
ask_postgres_details if database == "postgres"
|
|
100
|
+
@config[:db_adapter] = ask_with_default("What database adapter?", %w[sqlite3 postgres mysql mysql2], "sqlite3")
|
|
101
|
+
ask_database_details(@config[:db_adapter]) unless @config[:db_adapter] == "sqlite3"
|
|
92
102
|
end
|
|
93
103
|
|
|
94
|
-
def
|
|
104
|
+
def ask_database_details(database)
|
|
95
105
|
say_current_config(:db_url, "Current database url")
|
|
96
106
|
|
|
97
|
-
if RUBY_PLATFORM == "java"
|
|
98
|
-
|
|
107
|
+
default_value = if RUBY_PLATFORM == "java"
|
|
108
|
+
"jdbc:#{database}:///gemstash"
|
|
99
109
|
else
|
|
100
|
-
|
|
110
|
+
"#{database}:///gemstash"
|
|
101
111
|
end
|
|
102
112
|
|
|
103
113
|
url = @cli.ask "Where is the database? [#{default_value}]"
|
|
@@ -105,20 +115,27 @@ module Gemstash
|
|
|
105
115
|
@config[:db_url] = url
|
|
106
116
|
end
|
|
107
117
|
|
|
118
|
+
def ask_protected_fetch
|
|
119
|
+
say_current_config(:protected_fetch, "Protected Fetch enabled")
|
|
120
|
+
|
|
121
|
+
value = @cli.yes? "Use Protected Fetch for Private Gems? [y/N]"
|
|
122
|
+
value = Gemstash::Configuration::DEFAULTS[:protected_fetch] if value.is_a?(String) && value.empty?
|
|
123
|
+
@config[:protected_fetch] = value
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def ask_timeout
|
|
127
|
+
say_current_config(:fetch_timeout, "Fetch timeout")
|
|
128
|
+
timeout = @cli.ask "How many seconds to wait when fetching a gem? [20]"
|
|
129
|
+
timeout = Gemstash::Configuration::DEFAULTS[:fetch_timeout] if timeout.to_i < 1
|
|
130
|
+
@config[:fetch_timeout] = timeout.to_i
|
|
131
|
+
end
|
|
132
|
+
|
|
108
133
|
def check_cache
|
|
109
|
-
|
|
110
|
-
with_new_config { gemstash_env.cache_client.alive! }
|
|
111
|
-
rescue => e
|
|
112
|
-
say_error "Cache error", e
|
|
113
|
-
raise Gemstash::CLI::Error.new(@cli, "The cache is not available")
|
|
134
|
+
try("cache") { gemstash_env.cache_client.alive! }
|
|
114
135
|
end
|
|
115
136
|
|
|
116
137
|
def check_database
|
|
117
|
-
|
|
118
|
-
with_new_config { gemstash_env.db.test_connection }
|
|
119
|
-
rescue => e
|
|
120
|
-
say_error "Database error", e
|
|
121
|
-
raise Gemstash::CLI::Error.new(@cli, "The database is not available")
|
|
138
|
+
try("database") { gemstash_env.db.test_connection }
|
|
122
139
|
end
|
|
123
140
|
|
|
124
141
|
def check_storage
|
|
@@ -130,8 +147,10 @@ module Gemstash
|
|
|
130
147
|
# we don't want to store metadata just yet
|
|
131
148
|
metadata_file = gemstash_env.base_file("metadata.yml")
|
|
132
149
|
break unless File.exist?(metadata_file)
|
|
150
|
+
|
|
133
151
|
version = Gem::Version.new(YAML.load_file(metadata_file)[:gemstash_version])
|
|
134
152
|
break if Gem::Requirement.new("<= #{Gemstash::VERSION}").satisfied_by?(Gem::Version.new(version))
|
|
153
|
+
|
|
135
154
|
raise Gemstash::CLI::Error.new(@cli, "The base path already exists with a newer version of Gemstash")
|
|
136
155
|
else
|
|
137
156
|
@cli.say "Creating the file storage path '#{dir}'"
|
|
@@ -143,7 +162,7 @@ module Gemstash
|
|
|
143
162
|
def store_config
|
|
144
163
|
config_dir = File.dirname(config_file)
|
|
145
164
|
FileUtils.mkpath(config_dir) unless Dir.exist?(config_dir)
|
|
146
|
-
|
|
165
|
+
gemstash_env.atomic_write(config_file) {|f| f.write(YAML.dump(@config)) }
|
|
147
166
|
end
|
|
148
167
|
|
|
149
168
|
def save_metadata
|
|
@@ -155,6 +174,7 @@ module Gemstash
|
|
|
155
174
|
|
|
156
175
|
def say_error(title, error)
|
|
157
176
|
return unless @cli.options[:debug]
|
|
177
|
+
|
|
158
178
|
@cli.say @cli.set_color("#{title}: #{error}", :red)
|
|
159
179
|
|
|
160
180
|
error.backtrace.each do |line|
|
|
@@ -168,6 +188,14 @@ module Gemstash
|
|
|
168
188
|
ensure
|
|
169
189
|
gemstash_env.reset
|
|
170
190
|
end
|
|
191
|
+
|
|
192
|
+
def try(thing, &block)
|
|
193
|
+
@cli.say "Checking that the #{thing} is available"
|
|
194
|
+
with_new_config(&block)
|
|
195
|
+
rescue StandardError => e
|
|
196
|
+
say_error "Error checking #{thing}", e
|
|
197
|
+
raise Gemstash::CLI::Error.new(@cli, "The #{thing} is not available")
|
|
198
|
+
end
|
|
171
199
|
end
|
|
172
200
|
end
|
|
173
201
|
end
|
data/lib/gemstash/cli/start.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
require "puma/cli"
|
|
3
5
|
|
|
@@ -10,6 +12,7 @@ module Gemstash
|
|
|
10
12
|
prepare
|
|
11
13
|
setup_logging
|
|
12
14
|
store_daemonized
|
|
15
|
+
@cli.say("Starting gemstash!", :green)
|
|
13
16
|
Puma::CLI.new(args, Gemstash::Logging::StreamLogger.puma_events).run
|
|
14
17
|
end
|
|
15
18
|
|
|
@@ -17,7 +20,8 @@ module Gemstash
|
|
|
17
20
|
|
|
18
21
|
def setup_logging
|
|
19
22
|
return unless daemonize?
|
|
20
|
-
|
|
23
|
+
|
|
24
|
+
Gemstash::Logging.setup_logger(gemstash_env.log_file)
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
def store_daemonized
|
|
@@ -29,7 +33,7 @@ module Gemstash
|
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
def puma_config
|
|
32
|
-
File.expand_path("
|
|
36
|
+
File.expand_path("../puma.rb", __dir__)
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
def args
|
data/lib/gemstash/cli/status.rb
CHANGED
data/lib/gemstash/cli/stop.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
require "puma/control_cli"
|
|
3
5
|
|
|
@@ -9,12 +11,13 @@ module Gemstash
|
|
|
9
11
|
def run
|
|
10
12
|
prepare
|
|
11
13
|
Puma::ControlCLI.new(args).run
|
|
14
|
+
@cli.say("Gemstash stopped successfully!", :green)
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
private
|
|
15
18
|
|
|
16
19
|
def args
|
|
17
|
-
pidfile_args + %w
|
|
20
|
+
pidfile_args + %w[stop]
|
|
18
21
|
end
|
|
19
22
|
end
|
|
20
23
|
end
|
data/lib/gemstash/cli.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
require "thor"
|
|
3
5
|
require "thor/error"
|
|
@@ -23,13 +25,40 @@ module Gemstash
|
|
|
23
25
|
true
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
def self.start(args = ARGV)
|
|
29
|
+
help_flags = %w[-h --help]
|
|
30
|
+
|
|
31
|
+
if args.any? {|a| help_flags.include?(a) }
|
|
32
|
+
super(%w[help] + args.reject {|a| help_flags.include?(a) })
|
|
33
|
+
else
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def help(command = nil)
|
|
39
|
+
command ||= "readme"
|
|
40
|
+
page = manpage(command)
|
|
41
|
+
|
|
42
|
+
if page && which("man")
|
|
43
|
+
exec "man", page
|
|
44
|
+
elsif page
|
|
45
|
+
puts File.read("#{page}.txt")
|
|
46
|
+
else
|
|
47
|
+
super
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc "authorize [PERMISSIONS...]", "Add authorizations to push/yank private gems"
|
|
27
52
|
method_option :remove, :type => :boolean, :default => false, :desc =>
|
|
28
53
|
"Remove an authorization key"
|
|
54
|
+
method_option :list, :type => :boolean, :default => false, :desc =>
|
|
55
|
+
"List existing authorization keys"
|
|
29
56
|
method_option :config_file, :type => :string, :desc =>
|
|
30
57
|
"Config file to save to"
|
|
31
58
|
method_option :key, :type => :string, :desc =>
|
|
32
59
|
"Authorization key to create/update/delete (optional unless deleting)"
|
|
60
|
+
method_option :name, :type => :string, :desc =>
|
|
61
|
+
"Name of the key (optional)"
|
|
33
62
|
def authorize(*args)
|
|
34
63
|
Gemstash::CLI::Authorize.new(self, *args).run
|
|
35
64
|
end
|
|
@@ -67,5 +96,34 @@ module Gemstash
|
|
|
67
96
|
def stop
|
|
68
97
|
Gemstash::CLI::Stop.new(self).run
|
|
69
98
|
end
|
|
99
|
+
|
|
100
|
+
desc "version", "Prints gemstash version information"
|
|
101
|
+
def version
|
|
102
|
+
say "Gemstash version #{Gemstash::VERSION}"
|
|
103
|
+
end
|
|
104
|
+
map %w[-v --version] => :version
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def manpage(command)
|
|
109
|
+
page = File.expand_path("../man/gemstash-#{command}", __FILE__)
|
|
110
|
+
return page if File.file?(page)
|
|
111
|
+
|
|
112
|
+
1.upto(8) do |section|
|
|
113
|
+
page = File.expand_path("../man/gemstash-#{command}.#{section}", __FILE__)
|
|
114
|
+
return page if File.file?(page)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
nil
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def which(executable)
|
|
121
|
+
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
|
122
|
+
exe_path = File.join(path, executable)
|
|
123
|
+
return exe_path if File.file?(exe_path) && File.executable?(exe_path)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
nil
|
|
127
|
+
end
|
|
70
128
|
end
|
|
71
129
|
end
|
data/lib/gemstash/config.ru
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
require "puma/commonlogger"
|
|
3
5
|
|
|
4
6
|
use Rack::Deflater
|
|
5
7
|
use Gemstash::Logging::RackMiddleware
|
|
6
8
|
|
|
7
|
-
if Gemstash::Env.daemonized?
|
|
8
|
-
use Puma::CommonLogger, Gemstash::Logging::StreamLogger.for_stdout
|
|
9
|
-
end
|
|
9
|
+
use Puma::CommonLogger, Gemstash::Logging::StreamLogger.for_stdout if Gemstash::Env.daemonized?
|
|
10
10
|
|
|
11
11
|
use Gemstash::Env::RackMiddleware, Gemstash::Env.current
|
|
12
12
|
use Gemstash::GemSource::RackMiddleware
|
|
13
|
+
use Gemstash::Health::RackMiddleware
|
|
13
14
|
run Gemstash::Web.new(gemstash_env: Gemstash::Env.current)
|
|
@@ -1,28 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "yaml"
|
|
4
|
+
require "erb"
|
|
2
5
|
|
|
3
6
|
module Gemstash
|
|
4
|
-
|
|
7
|
+
# :nodoc:
|
|
5
8
|
class Configuration
|
|
6
9
|
DEFAULTS = {
|
|
7
|
-
:
|
|
8
|
-
:
|
|
9
|
-
:
|
|
10
|
-
:
|
|
11
|
-
:
|
|
10
|
+
cache_type: "memory",
|
|
11
|
+
base_path: File.expand_path("~/.gemstash"),
|
|
12
|
+
db_adapter: "sqlite3",
|
|
13
|
+
bind: "tcp://0.0.0.0:9292",
|
|
14
|
+
rubygems_url: "https://rubygems.org",
|
|
15
|
+
ignore_gemfile_source: false,
|
|
16
|
+
protected_fetch: false,
|
|
17
|
+
fetch_timeout: 20,
|
|
18
|
+
# Actual default for db_connection_options is dynamic based on the adapter
|
|
19
|
+
db_connection_options: {},
|
|
20
|
+
puma_threads: 16,
|
|
21
|
+
puma_workers: 1,
|
|
22
|
+
cache_expiration: 30 * 60,
|
|
23
|
+
cache_max_size: 500
|
|
12
24
|
}.freeze
|
|
13
25
|
|
|
14
26
|
DEFAULT_FILE = File.expand_path("~/.gemstash/config.yml").freeze
|
|
15
27
|
|
|
28
|
+
# This error is thrown when a config file is explicitly specified that
|
|
29
|
+
# doesn't exist.
|
|
30
|
+
class MissingFileError < StandardError
|
|
31
|
+
def initialize(file)
|
|
32
|
+
super("Missing config file: #{file}")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
16
36
|
def initialize(file: nil, config: nil)
|
|
17
37
|
if config
|
|
18
38
|
@config = DEFAULTS.merge(config).freeze
|
|
19
39
|
return
|
|
20
40
|
end
|
|
21
41
|
|
|
22
|
-
file
|
|
42
|
+
raise MissingFileError, file if file && !File.exist?(file)
|
|
43
|
+
|
|
44
|
+
file ||= default_file
|
|
23
45
|
|
|
24
46
|
if File.exist?(file)
|
|
25
|
-
@config =
|
|
47
|
+
@config = parse_config(file)
|
|
26
48
|
@config = DEFAULTS.merge(@config)
|
|
27
49
|
@config.freeze
|
|
28
50
|
else
|
|
@@ -37,5 +59,36 @@ module Gemstash
|
|
|
37
59
|
def [](key)
|
|
38
60
|
@config[key]
|
|
39
61
|
end
|
|
62
|
+
|
|
63
|
+
# @return [Hash] Sequel connection configuration hash
|
|
64
|
+
def database_connection_config
|
|
65
|
+
case self[:db_adapter]
|
|
66
|
+
when "sqlite3"
|
|
67
|
+
{ max_connections: 1 }.merge(self[:db_connection_options])
|
|
68
|
+
when "postgres", "mysql", "mysql2"
|
|
69
|
+
{ max_connections: (self[:puma_workers] * self[:puma_threads]) + 1 }.merge(self[:db_connection_options])
|
|
70
|
+
else
|
|
71
|
+
raise "Unsupported DB adapter: '#{self[:db_adapter]}'"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def default_file
|
|
78
|
+
# Support the config file being specified via environment variable
|
|
79
|
+
gemstash_config = ENV["GEMSTASH_CONFIG"]
|
|
80
|
+
return gemstash_config if gemstash_config
|
|
81
|
+
|
|
82
|
+
# If no environment variable is used, fall back to the normal defaults
|
|
83
|
+
File.exist?("#{DEFAULT_FILE}.erb") ? "#{DEFAULT_FILE}.erb" : DEFAULT_FILE
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def parse_config(file)
|
|
87
|
+
if file.end_with?(".erb")
|
|
88
|
+
YAML.load(ERB.new(File.read(file)).result) || {}
|
|
89
|
+
else
|
|
90
|
+
YAML.load_file(file) || {}
|
|
91
|
+
end
|
|
92
|
+
end
|
|
40
93
|
end
|
|
41
94
|
end
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
|
|
3
5
|
module Gemstash
|
|
4
6
|
module DB
|
|
5
7
|
# Sequel model for authorizations table.
|
|
6
8
|
class Authorization < Sequel::Model
|
|
7
|
-
def self.insert_or_update(auth_key, permissions)
|
|
9
|
+
def self.insert_or_update(auth_key, permissions, name = nil)
|
|
8
10
|
db.transaction do
|
|
9
11
|
record = self[auth_key: auth_key]
|
|
10
12
|
|
|
11
13
|
if record
|
|
12
|
-
record.update(permissions: permissions)
|
|
14
|
+
record.update(permissions: permissions, name: name)
|
|
13
15
|
else
|
|
14
|
-
create(auth_key: auth_key, permissions: permissions)
|
|
16
|
+
create(auth_key: auth_key, permissions: permissions, name: name)
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "gemstash"
|
|
4
|
+
|
|
5
|
+
module Gemstash
|
|
6
|
+
module DB
|
|
7
|
+
# Sequel model for cached_rubygems table.
|
|
8
|
+
class CachedRubygem < Sequel::Model
|
|
9
|
+
def self.store(upstream, gem_name, resource_type)
|
|
10
|
+
db.transaction do
|
|
11
|
+
upstream_id = Gemstash::DB::Upstream.find_or_insert(upstream)
|
|
12
|
+
record = self[upstream_id: upstream_id, name: gem_name.name, resource_type: resource_type.to_s]
|
|
13
|
+
return record.id if record
|
|
14
|
+
|
|
15
|
+
new(upstream_id: upstream_id, name: gem_name.name, resource_type: resource_type.to_s).tap(&:save).id
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/gemstash/db/rubygem.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
|
|
3
5
|
module Gemstash
|
|
@@ -7,6 +9,7 @@ module Gemstash
|
|
|
7
9
|
def self.find_or_insert(spec)
|
|
8
10
|
record = self[name: spec.name]
|
|
9
11
|
return record.id if record
|
|
12
|
+
|
|
10
13
|
new(name: spec.name).tap(&:save).id
|
|
11
14
|
end
|
|
12
15
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gemstash
|
|
4
|
+
module DB
|
|
5
|
+
# Sequel model for upstreams table.
|
|
6
|
+
class Upstream < Sequel::Model
|
|
7
|
+
def self.find_or_insert(upstream)
|
|
8
|
+
record = self[uri: upstream.to_s]
|
|
9
|
+
return record.id if record
|
|
10
|
+
|
|
11
|
+
new(uri: upstream.to_s, host_id: upstream.host_id).tap(&:save).id
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/gemstash/db/version.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
|
|
3
5
|
module Gemstash
|
|
@@ -19,8 +21,28 @@ module Gemstash
|
|
|
19
21
|
[rubygem.name, Gem::Version.new(number), platform]
|
|
20
22
|
end
|
|
21
23
|
|
|
22
|
-
def self.
|
|
23
|
-
|
|
24
|
+
def self.slug(params)
|
|
25
|
+
version = params[:version]
|
|
26
|
+
platform = params[:platform]
|
|
27
|
+
|
|
28
|
+
if platform.to_s.empty?
|
|
29
|
+
version
|
|
30
|
+
else
|
|
31
|
+
"#{version}-#{platform}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.for_spec_collection(prerelease: false, latest: false)
|
|
36
|
+
versions = where(indexed: true, prerelease: prerelease).association_join(:rubygem)
|
|
37
|
+
latest ? select_latest(versions) : versions
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.select_latest(versions)
|
|
41
|
+
versions.
|
|
42
|
+
all.
|
|
43
|
+
group_by {|version| [version.rubygem_id, version.platform] }.
|
|
44
|
+
values.
|
|
45
|
+
map {|gem_versions| gem_versions.max_by {|version| Gem::Version.new(version.number) } }
|
|
24
46
|
end
|
|
25
47
|
|
|
26
48
|
def self.find_by_spec(gem_id, spec)
|
|
@@ -32,6 +54,7 @@ module Gemstash
|
|
|
32
54
|
def self.find_by_full_name(full_name)
|
|
33
55
|
result = self[full_name: full_name]
|
|
34
56
|
return result if result
|
|
57
|
+
|
|
35
58
|
# Try again with the default platform, in case it is implied
|
|
36
59
|
self[full_name: "#{full_name}-ruby"]
|
|
37
60
|
end
|
data/lib/gemstash/db.rb
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "gemstash"
|
|
2
4
|
|
|
3
5
|
module Gemstash
|
|
4
6
|
# Module containing the DB models.
|
|
5
7
|
module DB
|
|
6
8
|
raise "Gemstash::DB cannot be loaded until the Gemstash::Env is available" unless Gemstash::Env.available?
|
|
9
|
+
|
|
7
10
|
Sequel::Model.db = Gemstash::Env.current.db
|
|
8
11
|
Sequel::Model.raise_on_save_failure = true
|
|
9
12
|
Sequel::Model.plugin :timestamps, update_on_create: true
|
|
10
13
|
autoload :Authorization, "gemstash/db/authorization"
|
|
14
|
+
autoload :CachedRubygem, "gemstash/db/cached_rubygem"
|
|
11
15
|
autoload :Dependency, "gemstash/db/dependency"
|
|
12
16
|
autoload :Rubygem, "gemstash/db/rubygem"
|
|
17
|
+
autoload :Upstream, "gemstash/db/upstream"
|
|
13
18
|
autoload :Version, "gemstash/db/version"
|
|
14
19
|
end
|
|
15
20
|
end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "cgi"
|
|
2
4
|
require "set"
|
|
3
5
|
|
|
4
6
|
module Gemstash
|
|
5
|
-
|
|
7
|
+
# :nodoc:
|
|
6
8
|
class Dependencies
|
|
7
9
|
def self.for_private
|
|
8
10
|
new(scope: "private", db_model: Gemstash::DB::Dependency)
|
|
@@ -22,7 +24,7 @@ module Gemstash
|
|
|
22
24
|
Fetcher.new(gems, @scope, @http_client, @db_model).fetch
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
# :nodoc:
|
|
26
28
|
class Fetcher
|
|
27
29
|
include Gemstash::Env::Helper
|
|
28
30
|
include Gemstash::Logging
|
|
@@ -59,6 +61,7 @@ module Gemstash
|
|
|
59
61
|
def fetch_from_database
|
|
60
62
|
return if done?
|
|
61
63
|
return unless @db_model
|
|
64
|
+
|
|
62
65
|
log.info "Querying dependencies: #{@gems.to_a.join(", ")}"
|
|
63
66
|
|
|
64
67
|
@db_model.fetch(@gems) do |gem, value|
|
|
@@ -71,6 +74,7 @@ module Gemstash
|
|
|
71
74
|
def fetch_from_web
|
|
72
75
|
return if done?
|
|
73
76
|
return unless @http_client
|
|
77
|
+
|
|
74
78
|
log.info "Fetching dependencies: #{@gems.to_a.join(", ")}"
|
|
75
79
|
gems_param = @gems.map {|gem| CGI.escape(gem) }.join(",")
|
|
76
80
|
fetched = @http_client.get("api/v1/dependencies?gems=#{gems_param}")
|