firespring_dev_commands 2.1.7 → 2.1.10.pre.alpha.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47ab0dc4450826feb67e1f072fa18d3d0708151f9e6a36b9b8f76813a7f9276c
4
- data.tar.gz: ab7dd713555030e929b7d6fa8166fd235aba8556bc28eca1de9e89d128c0b704
3
+ metadata.gz: d5d6f684466e6dde383089a4206db4858b6aa353cf2160a26209a57406048e67
4
+ data.tar.gz: 72b604e125b342ac714ee18099af6474b96e248002ca6b6869ebe18df51e01c1
5
5
  SHA512:
6
- metadata.gz: f717584922e1df9aafea9d36625f57c73b7c7573bc86eebc3cc08cf77252b7c93dde773fe4c7e9f6ab5d498b751b49520a0803112048e6628643997764cd473f
7
- data.tar.gz: 4f0c6a5f3aefe93903d9a3c94bdd39bc12efcb53b316cc6358f6952ceb3466df85b66dfa12408fdbd68b84b558416cc77fcffffaa986aa513e367ff678fb3b72
6
+ metadata.gz: 499014ee023457b5981445bfe2334b3749bffc705e27c5359c79ead81d8a794f1aabb4ce85878da108fa2bdb6d5c4b25cba6c8945c7abd1e62a8d0040f725059
7
+ data.tar.gz: a1c35a8c9015ebe42e0cd5882ffe3585cda6389af35fdedb5f711c2f2187466e85c99c5cb00f659685b28b815d97cb014d99afc457e8608c2beabcdbdca39e60
@@ -41,7 +41,7 @@ module Dev
41
41
  # If the user answers 'y' then the block is executed.
42
42
  # If the user answers 'n' then the block is skipped.
43
43
  def with_confirmation(message, default = 'y', color_message: true)
44
- message = "\n #{message}? "
44
+ message = "\n #{message}" << '? '.light_green
45
45
  message = message.light_green if color_message
46
46
  print message
47
47
  print '('.light_green << 'y'.light_yellow << '/'.light_green << 'n'.light_yellow << ') '.light_green
@@ -203,7 +203,7 @@ module Dev
203
203
 
204
204
  # Checks out the given branch in the given repo
205
205
  # Defaults to the current directory
206
- def checkout(branch, dir: default_project_dir)
206
+ def checkout(branch, dir: default_project_dir, raise_errors: false)
207
207
  raise 'branch is required' if branch.to_s.strip.empty?
208
208
  return unless File.exist?(dir)
209
209
 
@@ -224,12 +224,14 @@ module Dev
224
224
  indent g.pull('origin', actual_branch)
225
225
  true
226
226
  rescue ::Git::GitExecuteError => e
227
+ raise e if raise_errors
228
+
227
229
  print_errors(e.message)
228
230
  false
229
231
  end
230
232
 
231
233
  # Create the given branch in the given repo
232
- def create_branch(branch, dir: default_project_dir)
234
+ def create_branch(branch, dir: default_project_dir, raise_errors: false)
233
235
  raise 'branch is required' if branch.to_s.strip.empty?
234
236
  raise "refusing to create protected branch '#{branch}'" if %w(master develop).any?(branch.to_s.strip)
235
237
  return unless File.exist?(dir)
@@ -240,7 +242,7 @@ module Dev
240
242
  g = ::Git.open(dir)
241
243
  g.fetch('origin', prune: true)
242
244
 
243
- puts "Fetching the latest changes for base branch #{staging_branch}"
245
+ puts "Fetching the latest changes for base branch \"#{staging_branch}\""
244
246
  g.checkout(staging_branch)
245
247
  g.pull('origin', staging_branch)
246
248
 
@@ -251,6 +253,19 @@ module Dev
251
253
  g.config("branch.#{branch}.merge", "refs/heads/#{branch}")
252
254
  puts
253
255
  rescue ::Git::GitExecuteError => e
256
+ raise e if raise_errors
257
+
258
+ print_errors(e.message)
259
+ false
260
+ end
261
+
262
+ def add(*paths, dir: default_project_dir, raise_errors: false)
263
+ g = ::Git.open(dir)
264
+ indent g.add(paths)
265
+ true
266
+ rescue ::Git::GitExecuteError => e
267
+ raise e if raise_errors
268
+
254
269
  print_errors(e.message)
255
270
  false
256
271
  end
@@ -277,7 +292,7 @@ module Dev
277
292
  end
278
293
 
279
294
  # Merge the given branch into the given repo
280
- def merge(branch, dir: default_project_dir)
295
+ def merge(branch, dir: default_project_dir, raise_errors: false)
281
296
  raise 'branch is required' if branch.to_s.strip.empty?
282
297
  return unless File.exist?(dir)
283
298
 
@@ -296,6 +311,8 @@ module Dev
296
311
  indent g.merge(branch)
297
312
  true
298
313
  rescue ::Git::GitExecuteError => e
314
+ raise e if raise_errors
315
+
299
316
  print_errors(e.message)
300
317
  false
301
318
  end
@@ -320,7 +337,7 @@ module Dev
320
337
  end
321
338
 
322
339
  # Pull the given repo
323
- def pull(dir: default_project_dir)
340
+ def pull(dir: default_project_dir, raise_errors: false)
324
341
  return unless File.exist?(dir)
325
342
 
326
343
  g = ::Git.open(dir)
@@ -331,6 +348,8 @@ module Dev
331
348
  indent g.pull('origin', branch)
332
349
  true
333
350
  rescue ::Git::GitExecuteError => e
351
+ raise e if raise_errors
352
+
334
353
  print_errors(e.message)
335
354
  false
336
355
  end
@@ -355,7 +374,7 @@ module Dev
355
374
  end
356
375
 
357
376
  # Push the given repo
358
- def push(dir: default_project_dir)
377
+ def push(dir: default_project_dir, raise_errors: false)
359
378
  return unless File.exist?(dir)
360
379
 
361
380
  g = ::Git.open(dir)
@@ -366,6 +385,8 @@ module Dev
366
385
  indent g.push('origin', branch)
367
386
  true
368
387
  rescue ::Git::GitExecuteError => e
388
+ raise e if raise_errors
389
+
369
390
  print_errors(e.message)
370
391
  false
371
392
  end
@@ -378,7 +399,7 @@ module Dev
378
399
  # Clones the repo_name into the dir
379
400
  # Optionally specify a repo_org
380
401
  # Optionally specify a branch to check out (defaults to the repository default branch)
381
- def clone_repo(dir:, repo_name:, repo_org: 'firespring', branch: nil)
402
+ def clone_repo(dir:, repo_name:, repo_org: 'firespring', branch: nil, depth: nil)
382
403
  if Dir.exist?("#{dir}/.git")
383
404
  puts "#{dir} already cloned".light_green
384
405
  return
@@ -390,6 +411,7 @@ module Dev
390
411
 
391
412
  opts = {}
392
413
  opts[:branch] = branch unless branch.to_s.strip.empty?
414
+ opts[:depth] = depth unless depth.to_s.strip.empty?
393
415
  g = ::Git.clone(ssh_repo_url(repo_name, repo_org), dir, opts)
394
416
  g.fetch('origin', prune: true)
395
417
  end
@@ -0,0 +1,13 @@
1
+ module Dev
2
+ class TargetProcess
3
+ class Project
4
+ attr_accessor :id, :type, :name
5
+
6
+ def initialize(data)
7
+ @id = data['Id']
8
+ @type = data['ResourceType']
9
+ @name = data['Name']
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,70 @@
1
+ module Dev
2
+ class TargetProcess
3
+ class Query
4
+ attr_accessor :where, :incl, :take
5
+
6
+ def initialize
7
+ @where = []
8
+ @incl = []
9
+ @take = 250
10
+ end
11
+
12
+ def <<(item)
13
+ where << item
14
+ end
15
+
16
+ def where=(item)
17
+ if item.is_a?(Array)
18
+ where.concat(item)
19
+ else
20
+ where << item
21
+ end
22
+ end
23
+
24
+ def include=(item)
25
+ if item.is_a?(Array)
26
+ incl.concat(item)
27
+ else
28
+ incl << item
29
+ end
30
+ end
31
+
32
+ def generate
33
+ {}.tap do |clause|
34
+ clause[:where] = where.join(' and ') unless where.nil? || where.empty?
35
+ clause[:include] = "[#{incl.join(',')}]" unless incl.nil? || incl.empty?
36
+ clause[:take] = take if take.to_i.positive?
37
+ end
38
+ end
39
+
40
+ def to_s
41
+ generate
42
+ end
43
+
44
+ def filter_by_user_story_ids(user_story_ids)
45
+ self << "(Id in ('#{user_story_ids.join("', '")}'))"
46
+ end
47
+
48
+ def filter_by_project(projects)
49
+ self << "(Project.Name in ('#{projects.join("', '")}'))"
50
+ end
51
+
52
+ def filter_by_states(states)
53
+ self << "(EntityState.Name in ('#{states.join("', '")}'))" unless states.nil? || states.empty?
54
+ end
55
+
56
+ def filter_by_final
57
+ self << "(EntityState.IsFinal eq 'true')"
58
+ end
59
+
60
+ def filter_by_end_dates(start_date, end_date)
61
+ self << "(EndDate gt '#{start_date}')" if start_date
62
+ self << "(EndDate lt '#{end_date}')" if end_date
63
+ end
64
+
65
+ def filter_by_missing_tests
66
+ self << '(LinkedTestPlan is nil)'
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,13 @@
1
+ module Dev
2
+ class TargetProcess
3
+ class Release
4
+ attr_accessor :id, :type, :name
5
+
6
+ def initialize(data)
7
+ @id = data['Id']
8
+ @type = data['ResourceType']
9
+ @name = data['Name']
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Dev
2
+ class TargetProcess
3
+ class Team
4
+ attr_accessor :id, :type, :name
5
+
6
+ def initialize(data)
7
+ @id = data['Id']
8
+ @type = data['ResourceType']
9
+ @name = data['Name']
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Dev
2
+ class TargetProcess
3
+ class User
4
+ attr_accessor :id, :type, :name, :login
5
+
6
+ def initialize(data)
7
+ @id = data['Id']
8
+ @type = data['ResourceType']
9
+ @name = data['FullName']
10
+ @login = data['Login']
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,45 @@
1
+ module Dev
2
+ class TargetProcess
3
+ class UserStory
4
+ PATH = '/UserStories'.freeze
5
+
6
+ attr_accessor :type, :id, :name, :description, :start_date, :end_date, :create_date, :modify_date, :tags, :effort, :time_spent, :last_state_change_date, :project,
7
+ :owner, :creator, :release, :team, :priority, :state, :original_data
8
+
9
+ def initialize(data)
10
+ @id = data['Id']
11
+ @type = data['ResourceType']
12
+ @name = data['Name']
13
+ @description = data['Description']
14
+ @state = data['EntityState']['Name']
15
+ @project = Project.new(data['Project']) if data['Project']
16
+ @owner = User.new(data['Owner']) if data['Owner']
17
+ @creator = User.new(data['Creator']) if data['Creator']
18
+ @release = Release.new(data['Release']) if data['Release']
19
+ @team = Team.new(data['Team']) if data['Team']
20
+ @start_date = parse_time(data['StartDate'])
21
+ @end_date = parse_time(data['EndDate'])
22
+ @create_date = parse_time(data['CreateDate'])
23
+ @modify_date = parse_time(data['ModifyDate'])
24
+ @tags = data['Tags']
25
+ @effort = data['Effort']
26
+ @time_spent = data['TimeSpent']
27
+ @last_state_change_date = parse_time(data['LastStateChangeDate'])
28
+ @original_data = original_data
29
+ end
30
+
31
+ # Parse the dot net time representation into something that ruby can use
32
+ def parse_time(string)
33
+ return nil unless string && !string.empty?
34
+
35
+ Time.at(string.slice(6, 10).to_i)
36
+ end
37
+
38
+ def cycle_time
39
+ return 1.0 unless start_date && end_date
40
+
41
+ (end_date - start_date).to_f
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,101 @@
1
+ require 'net/http'
2
+
3
+ module Dev
4
+ class TargetProcess
5
+ CONFIG_FILE = "#{Dir.home}/.env.tp".freeze
6
+
7
+ TP_USERNAME = 'TP_USERNAME'.freeze
8
+
9
+ TP_PASSWORD = 'TP_PASSWORD'.freeze
10
+
11
+ TP_URL = 'TP_URL'.freeze
12
+
13
+ Config = Struct.new(:username, :password, :url, :http_debug) do
14
+ def initialize
15
+ Dotenv.load(CONFIG_FILE) if File.exist?(CONFIG_FILE)
16
+
17
+ self.username = ENV.fetch(TP_USERNAME, nil)
18
+ self.password = ENV.fetch(TP_PASSWORD, nil)
19
+ self.url = ENV.fetch(TP_URL, nil)
20
+ self.http_debug = false
21
+ end
22
+ end
23
+
24
+ class << self
25
+ # Instantiates a new top level config object if one hasn't already been created
26
+ # Yields that config object to any given block
27
+ # Returns the resulting config object
28
+ def config
29
+ @config ||= Config.new
30
+ yield(@config) if block_given?
31
+ @config
32
+ end
33
+
34
+ # Alias the config method to configure for a slightly clearer access syntax
35
+ alias_method :configure, :config
36
+ end
37
+
38
+ attr_accessor :username, :password, :url, :auth, :client, :headers
39
+
40
+ # Initialize a new jira client using the given inputs
41
+ def initialize(username: self.class.config.username, password: self.class.config.password, url: self.class.config.url)
42
+ @username = username
43
+ @password = password
44
+ @auth = Base64.strict_encode64("#{@username}:#{@password}")
45
+ @url = url
46
+ uri = URI.parse(@url)
47
+ @client = Net::HTTP.new(uri.host, uri.port)
48
+ @client.use_ssl = true
49
+ @client.verify_mode = OpenSSL::SSL::VERIFY_PEER
50
+ @client.set_debug_output(LOG) if self.class.config.http_debug
51
+ @headers = {
52
+ 'authorization' => "Basic #{auth}",
53
+ 'content-type' => 'application/json',
54
+ 'accept' => 'application/json'
55
+ }
56
+ end
57
+
58
+ def user_stories(query, &)
59
+ [].tap do |ary|
60
+ get(UserStory::PATH, query) do |result|
61
+ ary << UserStory.new(result)
62
+ end
63
+ ary.each(&)
64
+ end
65
+ end
66
+
67
+ def get(path, query, &)
68
+ query_string = query.generate
69
+ url = "/api/v1/#{path}"
70
+ url << "?#{URI.encode_www_form(query_string)}" unless query_string.empty?
71
+
72
+ response = client.request_get(url, headers)
73
+ raise "Error querying #{url} [#{query_string}]: #{response.inspect}" unless response.response.is_a?(Net::HTTPSuccess)
74
+
75
+ parsed_response = JSON.parse(response.body)
76
+ return parsed_response unless parsed_response.key?('Items')
77
+
78
+ parsed_response['Items'].each(&)
79
+
80
+ while parsed_response['Next']
81
+ response = client.request_get(parsed_response['Next'], headers)
82
+ raise "Error querying #{parsed_response['Next']} [#{query_string}]: #{response.inspect}" unless response.response.is_a?(Net::HTTPSuccess)
83
+
84
+ parsed_response = JSON.parse(response.body)
85
+ return parsed_response unless parsed_response.key?('Items')
86
+
87
+ parsed_response['Items'].each(&)
88
+ end
89
+
90
+ nil
91
+ end
92
+
93
+ def self.parse_dot_net_time(string)
94
+ Time.at(string.slice(6, 10).to_i)
95
+ end
96
+
97
+ def self.parse_dot_net_date(string)
98
+ parse_dot_net_time(string).to_date
99
+ end
100
+ end
101
+ end
@@ -6,6 +6,6 @@ module Dev
6
6
  # Use 'v.v.v.pre.alpha.v' for pre-release vesions
7
7
  # Use 'v.v.v.beta.v for beta versions
8
8
  # Use semantic versioning for any releases (https://semver.org/)
9
- VERSION = '2.1.7'.freeze
9
+ VERSION = '2.1.10.pre.alpha.1'.freeze
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firespring_dev_commands
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.7
4
+ version: 2.1.10.pre.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Firespring
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-07 00:00:00.000000000 Z
11
+ date: 2023-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.6
19
+ version: 7.1.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.6
26
+ version: 7.1.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: aws-sdk-cloudformation
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -305,6 +305,13 @@ files:
305
305
  - lib/firespring_dev_commands/tar.rb
306
306
  - lib/firespring_dev_commands/tar/pax_header.rb
307
307
  - lib/firespring_dev_commands/tar/type_flag.rb
308
+ - lib/firespring_dev_commands/target_process.rb
309
+ - lib/firespring_dev_commands/target_process/project.rb
310
+ - lib/firespring_dev_commands/target_process/query.rb
311
+ - lib/firespring_dev_commands/target_process/release.rb
312
+ - lib/firespring_dev_commands/target_process/team.rb
313
+ - lib/firespring_dev_commands/target_process/user.rb
314
+ - lib/firespring_dev_commands/target_process/user_story.rb
308
315
  - lib/firespring_dev_commands/templates/aws.rb
309
316
  - lib/firespring_dev_commands/templates/base_interface.rb
310
317
  - lib/firespring_dev_commands/templates/ci.rb
@@ -333,9 +340,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
333
340
  version: '3.1'
334
341
  required_rubygems_version: !ruby/object:Gem::Requirement
335
342
  requirements:
336
- - - ">="
343
+ - - ">"
337
344
  - !ruby/object:Gem::Version
338
- version: '0'
345
+ version: 1.3.1
339
346
  requirements: []
340
347
  rubygems_version: 3.4.10
341
348
  signing_key: