groundskeeper-bitcore 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +7 -0
- data/README.md +2 -2
- data/lib/groundskeeper/application.rb +4 -0
- data/lib/groundskeeper/changelog.rb +1 -1
- data/lib/groundskeeper/commands.rb +71 -27
- data/lib/groundskeeper/document.rb +10 -2
- data/lib/groundskeeper/git.rb +5 -0
- data/lib/groundskeeper/jira.rb +10 -0
- data/lib/groundskeeper/project.rb +26 -0
- data/lib/groundskeeper/rails_version.rb +74 -20
- data/lib/groundskeeper/repository.rb +2 -0
- data/lib/groundskeeper/rubygems.rb +2 -0
- data/lib/groundskeeper/semantic_version.rb +2 -0
- data/lib/groundskeeper/string_utils.rb +15 -0
- data/lib/groundskeeper/version.rb +1 -1
- data/lib/groundskeeper/website.rb +2 -0
- data/lib/groundskeeper.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a6720f0999695735f6151edd0cb2cfa7ee92d7b
|
4
|
+
data.tar.gz: a954fe744717b6e1217cb23ab23cff635b604e97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1858a09df13187ccbc4056426e8bc62978bacdb27ec3f4b4f4550a29b1bdb702f2074627249396a136c51cb958ea8f652d4e135a469520d7a070d51b85ca23bf
|
7
|
+
data.tar.gz: 52e5565e52a32663117d4fe68227fc8e2822168d0c3987a7aaa5fae48dbb1fd82260676b130559e1feafd3c66ce2c0fe84517fb846602c85d1226d23044bae36
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.3.2 - 2018-11-14
|
4
|
+
|
5
|
+
* GROUN-2 create the initial release of a Rails application (#80)
|
6
|
+
* GROUN-12 add nicer formatting to the deploy steps (#78)
|
7
|
+
* GROUN-6 display warning if tag is not found in repository
|
8
|
+
* Specify the scopes for the Sentry auth token. (#77)
|
9
|
+
|
3
10
|
## 0.3.1 - 2018-11-09
|
4
11
|
|
5
12
|
* GROUN-13 notify Sentry of a deployment to staging/production (#76)
|
data/README.md
CHANGED
@@ -31,8 +31,8 @@ one already.
|
|
31
31
|
export GITHUB_API_TOKEN="my-github-api-token"
|
32
32
|
```
|
33
33
|
|
34
|
-
For integration with Sentry, find
|
35
|
-
[from here](https://sentry.io/settings/account/api/auth-tokens/):
|
34
|
+
For integration with Sentry, find or create your auth token
|
35
|
+
[from here](https://sentry.io/settings/account/api/auth-tokens/) with the scopes `event:admin, event:read, member:read, org:read, project:read, project:releases, team:read`:
|
36
36
|
|
37
37
|
```bash
|
38
38
|
export SENTRY_AUTH_TOKEN="auth-token"
|
@@ -26,16 +26,20 @@ module Groundskeeper
|
|
26
26
|
commands.release
|
27
27
|
end
|
28
28
|
|
29
|
+
# :nocov:
|
29
30
|
desc "predeploy", "create configuration files for the project"
|
30
31
|
def predeploy
|
31
32
|
commands.info
|
32
33
|
commands.predeploy options
|
33
34
|
end
|
35
|
+
# :nocov:
|
34
36
|
|
37
|
+
# :nocov:
|
35
38
|
desc "deploy", "deploy the latest release"
|
36
39
|
def deploy
|
37
40
|
commands.info
|
38
41
|
commands.deploy options
|
39
42
|
end
|
43
|
+
# :nocov:
|
40
44
|
end
|
41
45
|
end
|
@@ -17,6 +17,7 @@ module Groundskeeper
|
|
17
17
|
PRODUCTION = "production"
|
18
18
|
DEFAULT_STAGE = STAGING
|
19
19
|
TAG = "tag"
|
20
|
+
INITIAL_VERSION = "0.0.1"
|
20
21
|
|
21
22
|
# rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
22
23
|
def self.build(console)
|
@@ -43,7 +44,7 @@ module Groundskeeper
|
|
43
44
|
repository: repository,
|
44
45
|
rubygems: Rubygems,
|
45
46
|
sentry: sentry,
|
46
|
-
version_file: RailsVersion.
|
47
|
+
version_file: RailsVersion.build,
|
47
48
|
website: website
|
48
49
|
)
|
49
50
|
end
|
@@ -80,6 +81,7 @@ module Groundskeeper
|
|
80
81
|
@version_file = version_file
|
81
82
|
@did_checkout_branch = false
|
82
83
|
@did_push_to_remote = false
|
84
|
+
@current_step = 1
|
83
85
|
end
|
84
86
|
# rubocop:enable Metrics/MethodLength,Metrics/ParameterLists
|
85
87
|
|
@@ -102,27 +104,31 @@ module Groundskeeper
|
|
102
104
|
end
|
103
105
|
# rubocop:enable Metrics/AbcSize
|
104
106
|
|
105
|
-
# rubocop:disable Metrics/AbcSize
|
107
|
+
# rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
|
106
108
|
def release
|
107
|
-
|
109
|
+
is_initial_release = !version_file.exists?
|
110
|
+
|
108
111
|
return missing_jira_credentials unless jira.credentials?
|
109
112
|
return unless check_groundskeeper_version
|
113
|
+
return unrecognized_version unless version_file.rails?
|
114
|
+
version_file.create_initial_version! unless version_file.exists?
|
110
115
|
pull_project_details
|
111
116
|
|
112
|
-
summarize_recent_commits
|
113
|
-
ask_next_version
|
117
|
+
summarize_recent_commits unless is_initial_release
|
118
|
+
ask_next_version(is_initial_release)
|
114
119
|
ask_new_branch
|
115
120
|
update_version_file
|
116
121
|
update_changelog
|
117
|
-
commit_changes_and_tag
|
122
|
+
commit_changes_and_tag(is_initial_release)
|
118
123
|
ask_create_jira_version
|
119
124
|
ask_push_with_tags
|
120
|
-
ask_add_version_to_jira_issues
|
125
|
+
ask_add_version_to_jira_issues unless is_initial_release
|
121
126
|
open_pull_request_page
|
122
127
|
end
|
123
|
-
# rubocop:enable Metrics/AbcSize
|
128
|
+
# rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity
|
124
129
|
# rubocop:enable Metrics/MethodLength
|
125
130
|
|
131
|
+
# :nocov:
|
126
132
|
def predeploy(options)
|
127
133
|
return unrecognized_version unless version_file.exists?
|
128
134
|
return unless check_groundskeeper_version
|
@@ -130,10 +136,12 @@ module Groundskeeper
|
|
130
136
|
|
131
137
|
mina "predeploy", options
|
132
138
|
end
|
139
|
+
# :nocov:
|
133
140
|
|
134
141
|
# rubocop:disable Metrics/AbcSize
|
135
142
|
def deploy(options)
|
136
143
|
return unrecognized_version unless version_file.exists?
|
144
|
+
return unrecognized_tag unless tag_present_in_git?(ENV[TAG])
|
137
145
|
return missing_jira_credentials unless jira.credentials?
|
138
146
|
return unless check_groundskeeper_version
|
139
147
|
pull_project_details
|
@@ -141,7 +149,7 @@ module Groundskeeper
|
|
141
149
|
ENV["whenever"] = "1" if project.uses_whenever?
|
142
150
|
|
143
151
|
mina "deploy", options
|
144
|
-
|
152
|
+
announce_step "Wait for deployed application to restart"
|
145
153
|
update_deployed_issues
|
146
154
|
add_version_to_sentry
|
147
155
|
end
|
@@ -153,10 +161,11 @@ module Groundskeeper
|
|
153
161
|
attr_reader :changelog, :console, :git, :git_hub, :jira, :project,
|
154
162
|
:repository, :rubygems, :sentry, :version_file, :website
|
155
163
|
# state
|
156
|
-
attr_reader :
|
157
|
-
:
|
164
|
+
attr_reader :current_step, :did_checkout_branch, :did_push_to_remote,
|
165
|
+
:next_version, :recent_commits
|
158
166
|
|
159
167
|
def mina(command, options)
|
168
|
+
announce_step "Run mina to deploy"
|
160
169
|
cmd = String.new command
|
161
170
|
cmd << " -s" if options[:simulate]
|
162
171
|
cmd << " -v" if options[:verbose]
|
@@ -165,9 +174,11 @@ module Groundskeeper
|
|
165
174
|
end
|
166
175
|
|
167
176
|
def pull_project_details
|
168
|
-
|
169
|
-
|
170
|
-
|
177
|
+
@pull_project_details ||= begin
|
178
|
+
announce_step("Updating ~/.project_details from "\
|
179
|
+
"#{git.remote_url('.project_details')}")
|
180
|
+
git.pull(".project_details")
|
181
|
+
end
|
171
182
|
end
|
172
183
|
|
173
184
|
# rubocop:disable Metrics/MethodLength
|
@@ -206,13 +217,16 @@ module Groundskeeper
|
|
206
217
|
console.say("")
|
207
218
|
end
|
208
219
|
|
209
|
-
def ask_next_version
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
220
|
+
def ask_next_version(is_initial_release)
|
221
|
+
if is_initial_release
|
222
|
+
@next_version = INITIAL_VERSION
|
223
|
+
else
|
224
|
+
type = console.ask("Major, minor, or patch release?",
|
225
|
+
:cyan,
|
226
|
+
limited_to: %w[M m p])
|
227
|
+
@next_version = repository.bumped_semantic_version(type)
|
228
|
+
end
|
229
|
+
|
216
230
|
console.say("next tag will be: #{next_version}", :green)
|
217
231
|
end
|
218
232
|
|
@@ -234,13 +248,15 @@ module Groundskeeper
|
|
234
248
|
console.say("# updated changelog", :green)
|
235
249
|
end
|
236
250
|
|
237
|
-
|
238
|
-
|
251
|
+
# rubocop:disable Metrics/AbcSize
|
252
|
+
def commit_changes_and_tag(is_initial_release)
|
253
|
+
is_initial_release ? git.add_all : git.add_update
|
239
254
|
git.commit(format(Repository::RELEASE_MESSAGE, next_version))
|
240
255
|
console.say("# committed changes", :green)
|
241
256
|
git.add_tag(next_version)
|
242
257
|
console.say("# tagged", :green)
|
243
258
|
end
|
259
|
+
# rubocop:enable Metrics/AbcSize
|
244
260
|
|
245
261
|
def ask_create_jira_version
|
246
262
|
create_jira_version =
|
@@ -265,8 +281,10 @@ module Groundskeeper
|
|
265
281
|
|
266
282
|
return unless add_version_to_jira_issues
|
267
283
|
|
284
|
+
# :nocov:
|
268
285
|
jira.add_version_to_remote_issues(next_jira_version_name, issue_ids)
|
269
286
|
console.say("# added version to Jira issues", :green)
|
287
|
+
# :nocov:
|
270
288
|
end
|
271
289
|
|
272
290
|
def next_jira_version_name
|
@@ -274,12 +292,24 @@ module Groundskeeper
|
|
274
292
|
end
|
275
293
|
|
276
294
|
def add_version_to_sentry
|
295
|
+
announce_step "Add release to Sentry and mark deployed"
|
277
296
|
sentry.create_release(ENV[TAG])
|
278
297
|
sentry.associate_commits(ENV[TAG])
|
279
298
|
sentry.deploy(ENV[TAG], self.class.stage)
|
280
299
|
console.say("# added version to Sentry", :green)
|
281
300
|
end
|
282
301
|
|
302
|
+
def tag_present_in_git?(tag)
|
303
|
+
git.list_tags.include? tag
|
304
|
+
end
|
305
|
+
|
306
|
+
def unrecognized_tag
|
307
|
+
console.say(
|
308
|
+
"Tag not found, try again with an existing tag.",
|
309
|
+
:red
|
310
|
+
)
|
311
|
+
end
|
312
|
+
|
283
313
|
def unrecognized_version
|
284
314
|
console.say(
|
285
315
|
"Unable to find version file, is this a Rails application?",
|
@@ -307,22 +337,29 @@ module Groundskeeper
|
|
307
337
|
def run_mina(arguments)
|
308
338
|
command = "mina #{arguments} -f #{RAKEFILE}"
|
309
339
|
Open3.popen3(command) do |_stdout, stderr, _status, _thread|
|
340
|
+
# :nocov:
|
310
341
|
# rubocop:disable Lint/AssignmentInCondition
|
311
342
|
while line = stderr.gets
|
312
343
|
puts line
|
313
344
|
end
|
314
345
|
# rubocop:enable Lint/AssignmentInCondition
|
346
|
+
# :nocov:
|
315
347
|
end
|
316
348
|
end
|
317
349
|
|
318
350
|
def update_deployed_issues
|
351
|
+
announce_step(
|
352
|
+
"Check deployed version at #{website.uri}/#{Website::VERSION_PATH}"
|
353
|
+
)
|
319
354
|
deployed_version = website.version
|
320
355
|
|
321
356
|
if deployed_version == ENV[TAG]
|
322
357
|
console.say("# deployment successful", :green)
|
323
358
|
transition_remote_issues deployed_version
|
324
359
|
else
|
360
|
+
# :nocov:
|
325
361
|
console.say("something went wrong", :red)
|
362
|
+
# :nocov:
|
326
363
|
end
|
327
364
|
end
|
328
365
|
|
@@ -331,13 +368,20 @@ module Groundskeeper
|
|
331
368
|
deployed_issues = jira.fetch_issues_by_fix_version(version_name)
|
332
369
|
action =
|
333
370
|
self.class.stage == PRODUCTION ? Jira::DELIVER : Jira::DEPLOY_TO_STAGING
|
334
|
-
|
335
|
-
"
|
336
|
-
|
337
|
-
:yellow
|
371
|
+
announce_step(
|
372
|
+
"Transitioning deployed issues in Jira: " \
|
373
|
+
"#{action} #{deployed_issues.join(', ')}"
|
338
374
|
)
|
339
375
|
jira.transition_remote_issues(action, deployed_issues)
|
340
376
|
end
|
377
|
+
|
378
|
+
def announce_step(message)
|
379
|
+
console.say(">>>", :magenta)
|
380
|
+
console.say(">>> #{@current_step}. #{message}", :magenta)
|
381
|
+
console.say(">>>", :magenta)
|
382
|
+
console.say("")
|
383
|
+
@current_step += 1
|
384
|
+
end
|
341
385
|
end
|
342
386
|
# rubocop:enable Metrics/ClassLength
|
343
387
|
end
|
@@ -10,7 +10,15 @@ module Groundskeeper
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def exists?
|
13
|
-
File.exist?
|
13
|
+
File.exist?(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def file?
|
17
|
+
File.file?(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def make_parent_directory!
|
21
|
+
Dir.mkdir(File.dirname(path))
|
14
22
|
end
|
15
23
|
|
16
24
|
# Returns the first captured expression or nil if it is not found.
|
@@ -47,7 +55,7 @@ module Groundskeeper
|
|
47
55
|
end
|
48
56
|
|
49
57
|
def read
|
50
|
-
return "" unless exists?
|
58
|
+
return "" unless exists? && file?
|
51
59
|
|
52
60
|
File.binread(path)
|
53
61
|
end
|
data/lib/groundskeeper/git.rb
CHANGED
@@ -15,6 +15,7 @@ module Groundskeeper
|
|
15
15
|
LATEST_CHANGES = "log %s..HEAD --oneline"
|
16
16
|
CREATE_AND_CHECKOUT_BRANCH = "checkout -b %s"
|
17
17
|
ADD_UPDATE = "add -u"
|
18
|
+
ADD_ALL = "add ."
|
18
19
|
COMMIT = "commit -m \"%s\""
|
19
20
|
ADD_TAG = "tag %s"
|
20
21
|
PUSH_HEAD_WITH_TAGS = "push origin head --tags"
|
@@ -78,6 +79,10 @@ module Groundskeeper
|
|
78
79
|
git.execute(ADD_UPDATE)
|
79
80
|
end
|
80
81
|
|
82
|
+
def add_all
|
83
|
+
git.execute(ADD_ALL)
|
84
|
+
end
|
85
|
+
|
81
86
|
def commit(message)
|
82
87
|
git.execute(format(COMMIT, message))
|
83
88
|
end
|
data/lib/groundskeeper/jira.rb
CHANGED
@@ -35,18 +35,23 @@ module Groundskeeper
|
|
35
35
|
)
|
36
36
|
end
|
37
37
|
|
38
|
+
# :nocov:
|
38
39
|
def create_version(name:, prefix:)
|
39
40
|
client.Version
|
40
41
|
.build
|
41
42
|
.save(name: name, project: prefix)
|
42
43
|
end
|
44
|
+
# :nocov:
|
43
45
|
|
46
|
+
# :nocov:
|
44
47
|
def add_version_to_issue(issue_id:, version_name:)
|
45
48
|
client.Issue
|
46
49
|
.find(issue_id)
|
47
50
|
.save(update: { fixVersions: [{ add: { name: version_name } }] })
|
48
51
|
end
|
52
|
+
# :nocov:
|
49
53
|
|
54
|
+
# :nocov:
|
50
55
|
def transition_issue(issue_id:, transition_id:)
|
51
56
|
client.Issue
|
52
57
|
.find(issue_id)
|
@@ -54,7 +59,9 @@ module Groundskeeper
|
|
54
59
|
.build
|
55
60
|
.save(transition: { id: transition_id })
|
56
61
|
end
|
62
|
+
# :nocov:
|
57
63
|
|
64
|
+
# :nocov:
|
58
65
|
def fetch_issues_by_fix_version(version:)
|
59
66
|
search_path = "/rest/api/2/search"
|
60
67
|
query = "fixVersion = \"#{version}\""
|
@@ -63,6 +70,7 @@ module Groundskeeper
|
|
63
70
|
|
64
71
|
JSON.parse(response)["issues"].map { |issue| issue["key"] }
|
65
72
|
end
|
73
|
+
# :nocov:
|
66
74
|
end
|
67
75
|
|
68
76
|
def self.build(prefix)
|
@@ -113,8 +121,10 @@ module Groundskeeper
|
|
113
121
|
end
|
114
122
|
end
|
115
123
|
|
124
|
+
# :nocov:
|
116
125
|
def fetch_issues_by_fix_version(version)
|
117
126
|
client.fetch_issues_by_fix_version(version: version)
|
118
127
|
end
|
128
|
+
# :nocov:
|
119
129
|
end
|
120
130
|
end
|
@@ -32,11 +32,13 @@ module Groundskeeper
|
|
32
32
|
)
|
33
33
|
end
|
34
34
|
|
35
|
+
# :nocov:
|
35
36
|
def self.available_applications
|
36
37
|
yaml = Document.new(DETAILS_PATH).read
|
37
38
|
projects = YAML.safe_load(yaml) || {}
|
38
39
|
projects.keys.join(", ")
|
39
40
|
end
|
41
|
+
# :nocov:
|
40
42
|
|
41
43
|
def initialize(projects_yaml:, servers_yaml:, repository_name:)
|
42
44
|
projects = YAML.safe_load(projects_yaml) || {}
|
@@ -61,54 +63,77 @@ module Groundskeeper
|
|
61
63
|
details.dig(FULL_DNS_KEY, stage.to_s) || ""
|
62
64
|
end
|
63
65
|
|
66
|
+
# :nocov:
|
64
67
|
def db_env_variables(stage)
|
65
68
|
details.dig(DB_ENV_VARIABLES_KEY, stage.to_s) || ""
|
66
69
|
end
|
70
|
+
# :nocov:
|
67
71
|
|
72
|
+
# :nocov:
|
68
73
|
def rvm_ruby_version
|
69
74
|
details[RVM_RUBY_VERSION_KEY] || ""
|
70
75
|
end
|
76
|
+
# :nocov:
|
71
77
|
|
78
|
+
# :nocov:
|
72
79
|
def sentry_dsn
|
73
80
|
details[SENTRY_DSN_KEY] || ""
|
74
81
|
end
|
82
|
+
# :nocov:
|
75
83
|
|
84
|
+
# :nocov:
|
76
85
|
def sentry_public_dsn
|
77
86
|
details[SENTRY_PUBLIC_DSN_KEY] || ""
|
78
87
|
end
|
88
|
+
# :nocov:
|
79
89
|
|
80
90
|
def sentry_project
|
81
91
|
details[SENTRY_PROJECT_KEY] || ""
|
82
92
|
end
|
83
93
|
|
94
|
+
# :nocov:
|
84
95
|
def ssl_certificate_file(stage)
|
85
96
|
details.dig(SSL_CERTIFICATE_FILE_KEY, stage.to_s) || ""
|
86
97
|
end
|
98
|
+
# :nocov:
|
87
99
|
|
100
|
+
# :nocov:
|
88
101
|
def ssl_certificate_chain_file(stage)
|
89
102
|
details.dig(SSL_CERTIFICATE_CHAIN_FILE_KEY, stage.to_s) || ""
|
90
103
|
end
|
104
|
+
# :nocov:
|
91
105
|
|
106
|
+
# :nocov:
|
92
107
|
def ssl_certificate_key_file(stage)
|
93
108
|
details.dig(SSL_CERTIFICATE_KEY_FILE_KEY, stage.to_s) || ""
|
94
109
|
end
|
110
|
+
# :nocov:
|
95
111
|
|
112
|
+
# :nocov:
|
96
113
|
def uses_whenever?
|
97
114
|
details[WHENEVER_KEY] == true
|
98
115
|
end
|
116
|
+
# :nocov:
|
99
117
|
|
118
|
+
# :nocov:
|
100
119
|
def server_config(stage)
|
101
120
|
servers[full_dns(stage)]
|
102
121
|
end
|
122
|
+
# :nocov:
|
103
123
|
|
124
|
+
# :nocov:
|
104
125
|
def repo_url
|
105
126
|
"git@github.com:#{source_control_username}/#{repo_name}.git"
|
106
127
|
end
|
128
|
+
# :nocov:
|
107
129
|
|
130
|
+
# :nocov:
|
108
131
|
def deploy_to
|
109
132
|
"/var/www/apps/#{repo_name}"
|
110
133
|
end
|
134
|
+
# :nocov:
|
111
135
|
|
136
|
+
# :nocov:
|
112
137
|
def tags
|
113
138
|
api_url = "https://api.github.com/repos/" \
|
114
139
|
"#{source_control_username}/#{repo_name}/tags"
|
@@ -121,5 +146,6 @@ module Groundskeeper
|
|
121
146
|
end
|
122
147
|
response.map { |h| h["name"] }
|
123
148
|
end
|
149
|
+
# :nocov:
|
124
150
|
end
|
125
151
|
end
|
@@ -4,15 +4,48 @@ module Groundskeeper
|
|
4
4
|
# The `version.rb` file in an application.
|
5
5
|
class RailsVersion
|
6
6
|
APPLICATION_CONFIG_FILE = "%sconfig/application.rb"
|
7
|
+
INITIAL_VERSION = "0.0.0"
|
7
8
|
MODULE_NAME_EXPRESSION = /module (\w+)/
|
8
|
-
|
9
|
+
NAMESPACE_FILE = "%slib/%s.rb"
|
10
|
+
MODULE_DIRECTORY = "%slib/%s"
|
11
|
+
VERSION_FILE = "#{MODULE_DIRECTORY}/version.rb"
|
9
12
|
VERSION_EXPRESSION = /(?<=VERSION = ")([^"]+)(?=")/
|
10
13
|
|
11
|
-
attr_reader :
|
14
|
+
attr_reader :config_file, :namespace_file, :project_name, :relative_path,
|
15
|
+
:version_file
|
12
16
|
|
13
|
-
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
18
|
+
def self.build(relative_path = "")
|
19
|
+
config_file_path = format(APPLICATION_CONFIG_FILE, relative_path)
|
20
|
+
config_file = Groundskeeper::Document.new(config_file_path)
|
21
|
+
project_name = config_file.match(MODULE_NAME_EXPRESSION)
|
22
|
+
folder_namespace = StringUtils.underscore(project_name)
|
23
|
+
namespace_file_path =
|
24
|
+
format(NAMESPACE_FILE, relative_path, folder_namespace)
|
25
|
+
version_file_path = format(VERSION_FILE, relative_path, folder_namespace)
|
26
|
+
|
27
|
+
new(
|
28
|
+
relative_path,
|
29
|
+
project_name: project_name,
|
30
|
+
config_file: config_file,
|
31
|
+
namespace_file: Groundskeeper::Document.new(namespace_file_path),
|
32
|
+
version_file: Groundskeeper::Document.new(version_file_path)
|
33
|
+
)
|
34
|
+
end
|
35
|
+
# rubocop:enable Metrics/MethodLength
|
36
|
+
|
37
|
+
def initialize(
|
38
|
+
relative_path = "",
|
39
|
+
project_name: "",
|
40
|
+
config_file: nil,
|
41
|
+
namespace_file:,
|
42
|
+
version_file: nil
|
43
|
+
)
|
14
44
|
@relative_path = relative_path
|
15
|
-
|
45
|
+
@project_name = project_name
|
46
|
+
@config_file = config_file || find_config_file
|
47
|
+
@namespace_file = namespace_file
|
48
|
+
@version_file = version_file || find_version_file
|
16
49
|
end
|
17
50
|
|
18
51
|
def current_version
|
@@ -23,40 +56,61 @@ module Groundskeeper
|
|
23
56
|
version_file.gsub_file VERSION_EXPRESSION, value
|
24
57
|
end
|
25
58
|
|
59
|
+
def rails?
|
60
|
+
config_file.exists?
|
61
|
+
end
|
62
|
+
|
26
63
|
def exists?
|
27
64
|
version_file.exists?
|
28
65
|
end
|
29
66
|
|
67
|
+
# rubocop:disable Metrics/MethodLength
|
68
|
+
def create_initial_version!
|
69
|
+
version_file.make_parent_directory!
|
70
|
+
version_file.write_file(
|
71
|
+
<<~RB
|
72
|
+
# frozen_string_literal: true
|
73
|
+
|
74
|
+
# Version string.
|
75
|
+
module #{project_name}
|
76
|
+
VERSION = "#{INITIAL_VERSION}"
|
77
|
+
end
|
78
|
+
RB
|
79
|
+
)
|
80
|
+
namespace_file.write_file(
|
81
|
+
<<~RB
|
82
|
+
# frozen_string_literal: true
|
83
|
+
|
84
|
+
require_relative "./#{folder_namespace}/version"
|
85
|
+
|
86
|
+
# nodoc
|
87
|
+
module #{project_name}
|
88
|
+
end
|
89
|
+
RB
|
90
|
+
)
|
91
|
+
end
|
92
|
+
# rubocop:enable Metrics/MethodLength
|
93
|
+
|
30
94
|
private
|
31
95
|
|
32
|
-
def
|
33
|
-
@
|
96
|
+
def find_config_file
|
97
|
+
@config_file = Groundskeeper::Document.new(config_file_path)
|
34
98
|
end
|
35
99
|
|
36
100
|
def find_version_file
|
37
|
-
find_module_file
|
38
101
|
@version_file = Groundskeeper::Document.new(version_file_path)
|
39
102
|
end
|
40
103
|
|
41
|
-
def
|
104
|
+
def config_file_path
|
42
105
|
format APPLICATION_CONFIG_FILE, relative_path
|
43
106
|
end
|
44
107
|
|
45
108
|
def version_file_path
|
46
|
-
format VERSION_FILE, relative_path,
|
109
|
+
format VERSION_FILE, relative_path, folder_namespace
|
47
110
|
end
|
48
111
|
|
49
|
-
def
|
50
|
-
underscore(
|
51
|
-
end
|
52
|
-
|
53
|
-
def underscore(word)
|
54
|
-
return "" unless word.respond_to?(:gsub)
|
55
|
-
|
56
|
-
word
|
57
|
-
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
58
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
59
|
-
.downcase
|
112
|
+
def folder_namespace
|
113
|
+
StringUtils.underscore(config_file.match(MODULE_NAME_EXPRESSION))
|
60
114
|
end
|
61
115
|
end
|
62
116
|
end
|
@@ -33,6 +33,7 @@ module Groundskeeper
|
|
33
33
|
git.status.include? UNSTAGED_CHANGES
|
34
34
|
end
|
35
35
|
|
36
|
+
# :nocov:
|
36
37
|
def status
|
37
38
|
@status ||= begin
|
38
39
|
git.fetch
|
@@ -40,6 +41,7 @@ module Groundskeeper
|
|
40
41
|
git.status
|
41
42
|
end
|
42
43
|
end
|
44
|
+
# :nocov:
|
43
45
|
|
44
46
|
def changes_since_latest_tag
|
45
47
|
git
|
@@ -7,11 +7,13 @@ module Groundskeeper
|
|
7
7
|
class Rubygems
|
8
8
|
VERSION_API = "https://rubygems.org/api/v1/versions/"
|
9
9
|
|
10
|
+
# :nocov:
|
10
11
|
def self.latest_groundskeeper_version
|
11
12
|
out = `curl #{VERSION_API}groundskeeper-bitcore/latest.json 2>/dev/null`
|
12
13
|
response = JSON.parse(out)
|
13
14
|
|
14
15
|
response["version"]
|
15
16
|
end
|
17
|
+
# :nocov:
|
16
18
|
end
|
17
19
|
end
|
@@ -10,11 +10,13 @@ module Groundskeeper
|
|
10
10
|
|
11
11
|
attr_reader :major, :minor, :patch
|
12
12
|
|
13
|
+
# :nocov:
|
13
14
|
def self.build(version)
|
14
15
|
return version if version.is_a?(SemanticVersion)
|
15
16
|
|
16
17
|
new(version)
|
17
18
|
end
|
19
|
+
# :nocov:
|
18
20
|
|
19
21
|
def initialize(version)
|
20
22
|
@major, @minor, @patch = version.split(".").map(&:to_i)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Groundskeeper
|
4
|
+
# Helpers for strings.
|
5
|
+
module StringUtils
|
6
|
+
def self.underscore(word)
|
7
|
+
return "" unless word.respond_to?(:gsub)
|
8
|
+
|
9
|
+
word
|
10
|
+
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
11
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
12
|
+
.downcase
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/groundskeeper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groundskeeper-bitcore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- BIT Core
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- certs/ericcf.pem
|
12
|
-
date: 2018-11-
|
12
|
+
date: 2018-11-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: jira-ruby
|
@@ -182,6 +182,7 @@ files:
|
|
182
182
|
- lib/groundskeeper/rubygems.rb
|
183
183
|
- lib/groundskeeper/semantic_version.rb
|
184
184
|
- lib/groundskeeper/sentry.rb
|
185
|
+
- lib/groundskeeper/string_utils.rb
|
185
186
|
- lib/groundskeeper/version.rb
|
186
187
|
- lib/groundskeeper/website.rb
|
187
188
|
- servers.yml
|