firespring_dev_commands 2.1.7 → 2.1.10.pre.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
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: