gemnasium 3.2.1
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/.gitignore +18 -0
- data/.rvmrc +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +52 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +157 -0
- data/Rakefile +6 -0
- data/bin/gemnasium +43 -0
- data/features/gemnasium.feature +58 -0
- data/features/gemnasium_create.feature +13 -0
- data/features/gemnasium_install.feature +119 -0
- data/features/step_definitions/gemnasium_steps.rb +52 -0
- data/features/support/env.rb +7 -0
- data/gemnasium.gemspec +24 -0
- data/lib/gemnasium.rb +328 -0
- data/lib/gemnasium/configuration.rb +110 -0
- data/lib/gemnasium/connection.rb +42 -0
- data/lib/gemnasium/dependency_files.rb +55 -0
- data/lib/gemnasium/errors.rb +16 -0
- data/lib/gemnasium/options.rb +107 -0
- data/lib/gemnasium/version.rb +3 -0
- data/lib/templates/gemnasium.rake +24 -0
- data/lib/templates/gemnasium.yml +10 -0
- data/lib/templates/post-commit +7 -0
- data/spec/gemnasium/configuration_spec.rb +195 -0
- data/spec/gemnasium/connection_spec.rb +47 -0
- data/spec/gemnasium/dependency_files_spec.rb +80 -0
- data/spec/gemnasium/options_spec.rb +135 -0
- data/spec/gemnasium_spec.rb +520 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/gemnasium_helper.rb +86 -0
- metadata +177 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
Then /^it should create the config directory$/ do
|
2
|
+
steps %{
|
3
|
+
Then the output should match:
|
4
|
+
"""
|
5
|
+
Creating config directory
|
6
|
+
"""
|
7
|
+
And a directory named "config" should exist
|
8
|
+
}
|
9
|
+
end
|
10
|
+
Then /^it should create the config file$/ do
|
11
|
+
steps %{
|
12
|
+
Then the output should match:
|
13
|
+
"""
|
14
|
+
File created in .*\/config\/gemnasium\.yml
|
15
|
+
Please fill configuration file with accurate values\.
|
16
|
+
"""
|
17
|
+
And a file named "config/gemnasium.yml" should exist
|
18
|
+
}
|
19
|
+
end
|
20
|
+
Then /^it should create the post-commit hook$/ do
|
21
|
+
steps %{
|
22
|
+
Then the output should match:
|
23
|
+
"""
|
24
|
+
File created in .*\/.git\/hooks\/post-commit
|
25
|
+
"""
|
26
|
+
And a file named ".git/hooks/post-commit" should exist
|
27
|
+
}
|
28
|
+
end
|
29
|
+
Then /^it should create the task file$/ do
|
30
|
+
steps %{
|
31
|
+
Then the output should match:
|
32
|
+
"""
|
33
|
+
File created in .*\/lib\/tasks\/gemnasium.rake
|
34
|
+
"""
|
35
|
+
And the output should contain:
|
36
|
+
"""
|
37
|
+
Usage:
|
38
|
+
rake gemnasium:push - to push your dependency files
|
39
|
+
rake gemnasium:create - to create your project on Gemnasium
|
40
|
+
"""
|
41
|
+
And a file named "lib/tasks/gemnasium.rake" should exist
|
42
|
+
}
|
43
|
+
end
|
44
|
+
Then /^it should create the tasks directory$/ do
|
45
|
+
steps %{
|
46
|
+
Then the output should match:
|
47
|
+
"""
|
48
|
+
Creating lib/tasks directory.
|
49
|
+
"""
|
50
|
+
And a directory named "lib/tasks" should exist
|
51
|
+
}
|
52
|
+
end
|
data/gemnasium.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require './lib/gemnasium/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.authors = ["Tech-Angels"]
|
5
|
+
gem.email = ["contact@tech-angels.com"]
|
6
|
+
gem.description = "Safely upload your dependency files on gemnasium.com to track dependencies and get notified about updates and security advisories." +
|
7
|
+
"WARNING! This gem has been deprecated and support will be discontinued. Please use Gemnasium Toolbelt (https://github.com/gemnasium/toolbelt) instead."
|
8
|
+
gem.summary = gem.description
|
9
|
+
gem.homepage = "https://gemnasium.com/"
|
10
|
+
gem.license = 'MIT'
|
11
|
+
|
12
|
+
gem.files = `git ls-files`.split($\)
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "gemnasium"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.executables = ["gemnasium"]
|
17
|
+
gem.version = Gemnasium::VERSION
|
18
|
+
|
19
|
+
gem.add_development_dependency 'rake', '~>10.3.1'
|
20
|
+
gem.add_development_dependency 'rspec', '~>3.0'
|
21
|
+
gem.add_development_dependency 'cucumber'
|
22
|
+
gem.add_development_dependency 'aruba'
|
23
|
+
gem.add_development_dependency 'webmock'
|
24
|
+
end
|
data/lib/gemnasium.rb
ADDED
@@ -0,0 +1,328 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'gemnasium/connection'
|
3
|
+
require 'gemnasium/configuration'
|
4
|
+
require 'gemnasium/dependency_files'
|
5
|
+
require 'gemnasium/errors'
|
6
|
+
|
7
|
+
module Gemnasium
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Push dependency files to Gemnasium
|
11
|
+
# @param options [Hash] Parsed options from the command line. Options supported:
|
12
|
+
# * :project_path - Path to the project (required)
|
13
|
+
def push options
|
14
|
+
@config = load_config(options[:project_path])
|
15
|
+
ensure_config_is_up_to_date!
|
16
|
+
|
17
|
+
unless current_branch == @config.project_branch
|
18
|
+
if options[:ignore_branch]
|
19
|
+
notify "Not on tracked branch (#{@config.project_branch}), but ignore-branch option set to true. Continuing.\n", :blue
|
20
|
+
elsif options[:silence_branch]
|
21
|
+
notify "Not on tracked branch (#{@config.project_branch}). Exiting silently.\n", :blue
|
22
|
+
return
|
23
|
+
else
|
24
|
+
quit_because_of("Not on tracked branch (#{@config.project_branch})")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
unless has_project_slug?
|
29
|
+
quit_because_of('Project slug not defined. Please create a new project or "resolve" the name of an existing project.')
|
30
|
+
end
|
31
|
+
|
32
|
+
dependency_files_hashes = DependencyFiles.get_sha1s_hash(options[:project_path])
|
33
|
+
quit_because_of("No supported dependency files detected.") if dependency_files_hashes.empty?
|
34
|
+
notify "#{dependency_files_hashes.keys.count} supported dependency file(s) found: #{dependency_files_hashes.keys.join(', ')}"
|
35
|
+
|
36
|
+
# Ask to Gemnasium server which dependency file should be uploaded (new or modified)
|
37
|
+
comparison_results = request("#{connection.api_path_for('dependency_files')}/compare", dependency_files_hashes)
|
38
|
+
files_to_upload = comparison_results['to_upload']
|
39
|
+
deleted_files = comparison_results['deleted']
|
40
|
+
notify "#{deleted_files.count} deleted file(s): #{deleted_files.join(', ')}", :blue unless deleted_files.empty?
|
41
|
+
|
42
|
+
unless files_to_upload.empty?
|
43
|
+
notify "#{files_to_upload.count} file(s) to upload: #{files_to_upload.join(', ')}"
|
44
|
+
|
45
|
+
# Upload requested dependency files content
|
46
|
+
upload_summary = request("#{connection.api_path_for('dependency_files')}/upload", DependencyFiles.get_content_to_upload(options[:project_path], files_to_upload))
|
47
|
+
notify "Added dependency files: #{upload_summary['added']}", :green
|
48
|
+
notify "Updated dependency files: #{upload_summary['updated']}", :green
|
49
|
+
notify "Unchanged dependency files: #{upload_summary['unchanged']}", :blue unless upload_summary['unchanged'].empty?
|
50
|
+
notify "Unsupported dependency files: #{upload_summary['unsupported']}", :blue unless upload_summary['unsupported'].empty?
|
51
|
+
else
|
52
|
+
notify "The project's dependency files are up-to-date.", :blue
|
53
|
+
end
|
54
|
+
rescue => exception
|
55
|
+
quit_because_of(exception.message)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Install needed file(s) to run gemnasium command
|
59
|
+
#
|
60
|
+
# @param options [Hash] Parsed options from the command line. Options supported:
|
61
|
+
# * :install_rake_task - Install a rake task to the project
|
62
|
+
# * :install_git_hook - Install a git post-commit hook
|
63
|
+
# * :project_path - Path to the project (required)
|
64
|
+
def install options
|
65
|
+
require 'fileutils'
|
66
|
+
|
67
|
+
# Install config file
|
68
|
+
config_file_dir = "#{options[:project_path]}/config"
|
69
|
+
|
70
|
+
unless File.exists? config_file_dir
|
71
|
+
notify "Creating config directory"
|
72
|
+
FileUtils.mkdir_p config_file_dir
|
73
|
+
end
|
74
|
+
|
75
|
+
# Try to add config/gemnasium.yml to .gitignore
|
76
|
+
if File.exists? "#{options[:project_path]}/.gitignore"
|
77
|
+
File.open("#{options[:project_path]}/.gitignore", 'a+') do |f|
|
78
|
+
f.write("\n# Gemnasium gem configuration file\nconfig/gemnasium.yml") unless f.read.include? 'config/gemnasium.yml'
|
79
|
+
notify "Configuration file added to your project's .gitignore."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
notify 'Please fill configuration file with accurate values.', :blue if copy_template('gemnasium.yml', "#{config_file_dir}/gemnasium.yml")
|
84
|
+
|
85
|
+
# Install git hook
|
86
|
+
if options[:install_git_hook]
|
87
|
+
notify ''
|
88
|
+
if File.exists? "#{options[:project_path]}/.git/hooks"
|
89
|
+
copy_template('post-commit', "#{options[:project_path]}/.git/hooks/post-commit")
|
90
|
+
else
|
91
|
+
notify "#{options[:project_path]} is not a git repository. Try to run `git init`.", :red
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Install rake task
|
96
|
+
if options[:install_rake_task]
|
97
|
+
notify ''
|
98
|
+
if !File.exists? "#{options[:project_path]}/Rakefile"
|
99
|
+
notify "Rakefile not found.", :red
|
100
|
+
else
|
101
|
+
rake_file_dir = "#{options[:project_path]}/lib/tasks"
|
102
|
+
|
103
|
+
unless File.exists? rake_file_dir
|
104
|
+
notify "Creating lib/tasks directory"
|
105
|
+
FileUtils.mkdir_p rake_file_dir
|
106
|
+
end
|
107
|
+
|
108
|
+
if copy_template('gemnasium.rake', "#{rake_file_dir}/gemnasium.rake")
|
109
|
+
notify 'Usage:', :blue
|
110
|
+
notify "\trake gemnasium:push \t\t- to push your dependency files", :blue
|
111
|
+
notify "\trake gemnasium:create \t\t- to create your project on Gemnasium", :blue
|
112
|
+
notify "\trake gemnasium:migrate \t\t- to migrate your configuration file", :blue
|
113
|
+
notify "\trake gemnasium:resolve \t\t- to resolve the project name to an existing project", :blue
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Create the project on Gemnasium
|
120
|
+
#
|
121
|
+
# @param options [Hash] Parsed options from the command line. Options supported:
|
122
|
+
# * :project_path - Path to the project (required)
|
123
|
+
def create_project options
|
124
|
+
@config = load_config(options[:project_path])
|
125
|
+
ensure_config_is_up_to_date!
|
126
|
+
|
127
|
+
if has_project_slug?
|
128
|
+
quit_because_of("You already have a project slug refering to an existing project. Please remove this project slug from your configuration file to create a new project.")
|
129
|
+
end
|
130
|
+
|
131
|
+
project_params = { name: @config.project_name, branch: @config.project_branch}
|
132
|
+
|
133
|
+
result = request("#{connection.api_path_for('projects')}", project_params)
|
134
|
+
project_name, project_slug, remaining_slot_count = result.values_at 'name', 'slug', 'remaining_slot_count'
|
135
|
+
|
136
|
+
notify "Project `#{ project_name }` successfully created.", :green
|
137
|
+
notify "Project slug is `#{ project_slug }`.", :green
|
138
|
+
notify "Remaining private slots: #{ remaining_slot_count }", :blue
|
139
|
+
|
140
|
+
if @config.writable?
|
141
|
+
@config.store_value!(:project_slug, project_slug, "This unique project slug has been set by `gemnasium create`.")
|
142
|
+
notify "Your configuration file has been updated."
|
143
|
+
else
|
144
|
+
notify "Configuration file cannot be updated. Please edit the file and update the project slug manually."
|
145
|
+
end
|
146
|
+
|
147
|
+
rescue => exception
|
148
|
+
quit_because_of(exception.message)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Migrate the configuration file
|
152
|
+
#
|
153
|
+
# @param options [Hash] Parsed options from the command line. Options supported:
|
154
|
+
# * :project_path - Path to the project (required)
|
155
|
+
#
|
156
|
+
def migrate options
|
157
|
+
@config = load_config(options[:project_path])
|
158
|
+
|
159
|
+
if @config.needs_to_migrate?
|
160
|
+
@config.migrate!
|
161
|
+
notify "Your configuration has been updated.", :green
|
162
|
+
notify "Run `gemnasium resolve` if your config is related to an existing project."
|
163
|
+
notify "Run `gemnasium create` if you want to create a new project on Gemnasium."
|
164
|
+
else
|
165
|
+
notify "Your configuration file is already up-to-date.", :green
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Find and store the project slug matching the given project name.
|
170
|
+
#
|
171
|
+
# @param options [Hash] Parsed options from the command line. Options supported:
|
172
|
+
# * :project_path - Path to the project (required)
|
173
|
+
#
|
174
|
+
def resolve_project options
|
175
|
+
@config = load_config(options[:project_path])
|
176
|
+
ensure_config_is_up_to_date!
|
177
|
+
|
178
|
+
# REFACTOR: similar code in #create_project
|
179
|
+
if has_project_slug?
|
180
|
+
quit_because_of("You already have a project slug refering to an existing project. Please remove this project slug from your configuration file.")
|
181
|
+
end
|
182
|
+
|
183
|
+
project_name = @config.project_name
|
184
|
+
project_branch = @config.project_branch || 'master'
|
185
|
+
projects = request("#{connection.api_path_for('projects')}")
|
186
|
+
|
187
|
+
candidates = projects.select do |project|
|
188
|
+
project['name'] == project_name && project['origin'] == 'offline' && project['branch'] == project_branch
|
189
|
+
end
|
190
|
+
|
191
|
+
criterias = "name `#{ project_name }` and branch `#{ project_branch }`"
|
192
|
+
if candidates.size == 0
|
193
|
+
quit_because_of("You have no off-line project matching #{ criterias }.")
|
194
|
+
elsif candidates.size > 1
|
195
|
+
quit_because_of("You have more than one off-line project matching #{ criterias }.")
|
196
|
+
end
|
197
|
+
|
198
|
+
project = candidates.first
|
199
|
+
project_slug = project['slug']
|
200
|
+
notify "Project slug is `#{ project_slug }`.", :green
|
201
|
+
|
202
|
+
# REFACTOR: similar code in #create_project
|
203
|
+
if @config.writable?
|
204
|
+
@config.store_value!(:project_slug, project_slug, "This unique project slug has been set by `gemnasium resolve`.")
|
205
|
+
notify "Your configuration file has been updated."
|
206
|
+
else
|
207
|
+
notify "Configuration file cannot be updated. Please edit the file and update the project slug manually."
|
208
|
+
end
|
209
|
+
|
210
|
+
rescue => exception
|
211
|
+
quit_because_of(exception.message)
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
def config
|
216
|
+
@config || quit_because_of('No configuration file loaded')
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
220
|
+
|
221
|
+
def has_project_slug?
|
222
|
+
!@config.project_slug.nil?
|
223
|
+
end
|
224
|
+
|
225
|
+
# Quit with an error message if the config file needs a migration.
|
226
|
+
#
|
227
|
+
def ensure_config_is_up_to_date!
|
228
|
+
if @config.needs_to_migrate?
|
229
|
+
quit_because_of('Your configuration file is not compatible with this version. Please run the `migrate` command first.')
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# Issue a HTTP request
|
234
|
+
#
|
235
|
+
# @params path [String] Path of the request
|
236
|
+
# parameters [Hash] Parameters to send a POST request
|
237
|
+
def request(path, parameters = {})
|
238
|
+
if parameters.empty?
|
239
|
+
response = connection.get(path)
|
240
|
+
else
|
241
|
+
response = connection.post(path, JSON.generate(parameters))
|
242
|
+
end
|
243
|
+
|
244
|
+
raise Gemnasium::InvalidApiKeyError if response.code.to_i == 401
|
245
|
+
|
246
|
+
response_body = JSON.parse(response.body)
|
247
|
+
|
248
|
+
if response.code.to_i / 100 == 2
|
249
|
+
return {} if response_body.empty?
|
250
|
+
result = response_body
|
251
|
+
else
|
252
|
+
if error = "#{response_body['error']}_error".split('_').collect(&:capitalize).join
|
253
|
+
raise Gemnasium.const_get(error), response_body['message']
|
254
|
+
else
|
255
|
+
quit_because_of 'An unknown error has been returned by the server. Please contact Gemnasium support : http://support.gemnasium.com'
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Create a connection
|
261
|
+
def connection
|
262
|
+
@connection ||= Connection.new
|
263
|
+
end
|
264
|
+
|
265
|
+
# Load config from config file
|
266
|
+
#
|
267
|
+
# @param config_file [String] path to the project
|
268
|
+
# @return [Hash] config options
|
269
|
+
def load_config project_path
|
270
|
+
@config ||= Configuration.new("#{project_path}/config/gemnasium.yml")
|
271
|
+
rescue => exception
|
272
|
+
quit_because_of(exception.message)
|
273
|
+
end
|
274
|
+
|
275
|
+
# Puts a message to the standard output
|
276
|
+
#
|
277
|
+
# @param message [String] message to display
|
278
|
+
def notify message, color = nil
|
279
|
+
if $stdout.tty? && !color.nil?
|
280
|
+
color_code = { red: "\e[31m", green: "\e[32m", blue: "\e[34m" }
|
281
|
+
reset_color = "\e[0m"
|
282
|
+
|
283
|
+
message = color_code[color] + message + reset_color
|
284
|
+
end
|
285
|
+
|
286
|
+
$stdout.puts message
|
287
|
+
end
|
288
|
+
|
289
|
+
# Abort the program and colorize the message if $stderr is tty
|
290
|
+
#
|
291
|
+
# @param error_message [String] message to be puts to $stderr
|
292
|
+
def quit_because_of(error_message)
|
293
|
+
error_message = "\e[31m#{error_message}\e[0m" if $stderr.tty?
|
294
|
+
abort error_message
|
295
|
+
end
|
296
|
+
|
297
|
+
# Get the current git branch
|
298
|
+
#
|
299
|
+
# @return [String] name of the current branch
|
300
|
+
def current_branch
|
301
|
+
branch = `git branch 2>/dev/null`.split("\n").delete_if { |branch| branch.chars.first != "*" }.first
|
302
|
+
branch.gsub("* ","") unless branch.nil?
|
303
|
+
end
|
304
|
+
|
305
|
+
# Copy a template file
|
306
|
+
#
|
307
|
+
# @param file [String] template to copy
|
308
|
+
# target_path [String] location where to copy the template
|
309
|
+
def copy_template(file, target_path)
|
310
|
+
if File.exists? target_path
|
311
|
+
notify "The file #{target_path} already exists"
|
312
|
+
else
|
313
|
+
template_file = File.expand_path("#{File.dirname(__FILE__)}/templates/#{file}")
|
314
|
+
FileUtils.cp template_file, target_path
|
315
|
+
|
316
|
+
if File.exists? target_path
|
317
|
+
notify "File created in #{target_path}", :green
|
318
|
+
|
319
|
+
return true
|
320
|
+
else
|
321
|
+
notify "Could not install #{file} file.", :red
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
false
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module Gemnasium
|
5
|
+
class Configuration
|
6
|
+
attr_accessor :site, :api_key, :use_ssl, :api_version, :project_branch, :ignored_paths
|
7
|
+
|
8
|
+
attr_accessor :project_name # Name is required only to create the project, make it mandatory.
|
9
|
+
attr_accessor :project_slug # Slug is required only to push the dependency files, make it optional.
|
10
|
+
attr_accessor :profile_name # Keep profile name for backward compatibility with version =< 2.0
|
11
|
+
|
12
|
+
DEFAULT_CONFIG = { 'site' => 'gemnasium.com',
|
13
|
+
'use_ssl' => true,
|
14
|
+
'api_version' => 'v3',
|
15
|
+
'ignored_paths' => [] }
|
16
|
+
|
17
|
+
# Initialize the configuration object from a YAML file
|
18
|
+
#
|
19
|
+
# @param config_file [String] path to the configuration file
|
20
|
+
def initialize config_file
|
21
|
+
unless File.file?(config_file)
|
22
|
+
raise Errno::ENOENT,
|
23
|
+
"Configuration file (#{config_file}) does not exist.\nPlease run `gemnasium install`."
|
24
|
+
end
|
25
|
+
@path = config_file
|
26
|
+
|
27
|
+
config_hash = DEFAULT_CONFIG.merge(YAML.load(ERB.new(File.read(config_file)).result))
|
28
|
+
config_hash.each do |k, v|
|
29
|
+
writer_method = "#{k}="
|
30
|
+
if respond_to?(writer_method)
|
31
|
+
v = convert_ignored_paths_to_regexp(v) if k.to_s == 'ignored_paths'
|
32
|
+
send(writer_method, v)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
raise 'Your configuration file does not contain all mandatory parameters or contain invalid values. Please check the documentation.' unless is_valid?
|
37
|
+
end
|
38
|
+
|
39
|
+
# Store a key-value pair in the configuration file with an optional comment.
|
40
|
+
# Try to preserve the comments and the indentation of the file.
|
41
|
+
# We assume the configuration file already features the given key.
|
42
|
+
#
|
43
|
+
# @param key [String] key
|
44
|
+
# @param value [String] value to store for given key
|
45
|
+
# @param comment [String] optional comment
|
46
|
+
#
|
47
|
+
def store_value!(key, value, comment = nil)
|
48
|
+
pattern = /\A#{ key }:.*\Z/
|
49
|
+
new_line = "#{ key }: #{ value }"
|
50
|
+
new_line += " # #{ comment }" if comment
|
51
|
+
|
52
|
+
content = File.readlines(path).map do |line|
|
53
|
+
line.rstrip.sub pattern, new_line
|
54
|
+
end.join("\n") + "\n"
|
55
|
+
|
56
|
+
File.write path, content
|
57
|
+
end
|
58
|
+
|
59
|
+
def writable?
|
60
|
+
File.writable? path
|
61
|
+
end
|
62
|
+
|
63
|
+
def needs_to_migrate?
|
64
|
+
!profile_name.nil?
|
65
|
+
end
|
66
|
+
|
67
|
+
def migrate!
|
68
|
+
# replace profile_name key with project_slug key (no value)
|
69
|
+
content = File.readlines(path).map do |line|
|
70
|
+
if line =~ /\Aprofile_name:.*\Z/
|
71
|
+
"project_slug:"
|
72
|
+
else
|
73
|
+
line
|
74
|
+
end
|
75
|
+
end.map{ |l| l.rstrip }.join("\n") + "\n"
|
76
|
+
|
77
|
+
File.write path, content
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
attr_reader :path
|
83
|
+
|
84
|
+
# Check that mandatory parameters are not nil and contain valid values
|
85
|
+
#
|
86
|
+
# @return [Boolean] if configuration is valid
|
87
|
+
def is_valid?
|
88
|
+
site_option_valid = !site.nil? && !site.empty?
|
89
|
+
api_key_option_valid = !api_key.nil? && !api_key.empty?
|
90
|
+
use_ssl_option_valid = !use_ssl.nil? && !!use_ssl == use_ssl # Check this is a boolean
|
91
|
+
api_version_option_valid = !api_version.nil? && !api_version.empty?
|
92
|
+
project_name_option_valid = !project_name.nil? && !project_name.empty?
|
93
|
+
ignored_paths_option_valid = ignored_paths.kind_of?(Array)
|
94
|
+
|
95
|
+
site_option_valid && api_key_option_valid && use_ssl_option_valid && api_version_option_valid &&
|
96
|
+
project_name_option_valid && ignored_paths_option_valid
|
97
|
+
end
|
98
|
+
|
99
|
+
def convert_ignored_paths_to_regexp(paths)
|
100
|
+
return [] unless paths.kind_of? Array
|
101
|
+
|
102
|
+
paths.inject([]) do |regexp_array, path|
|
103
|
+
path = path.insert(0,'^') # All path start from app root
|
104
|
+
.gsub('*','[^/]+') # Replace `*` to whatever char except slash
|
105
|
+
.gsub('.','\.') # Escape dots
|
106
|
+
regexp_array << Regexp.new(path)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|