tracker-cli 0.1.0 → 0.1.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
  SHA1:
3
- metadata.gz: 9f189c896ac1d5dcf3de93c29dfa2d959dec382d
4
- data.tar.gz: bf3bbbd61e66e09de3e0beee5bdfc34aa49e067f
3
+ metadata.gz: ae82abc323e36605f6bcdc4659dee82c84b0b159
4
+ data.tar.gz: acc9e362f05030d417e8897cbb6884478e31a96d
5
5
  SHA512:
6
- metadata.gz: 610917a9319d41d41eb073ddc6dc7f9ba1ffdd3741f839fdcf604802c1bee3c34627fe07a2eedd6f235b0e41ac0848527788292965ec48b1153f18511a94e44b
7
- data.tar.gz: 857d4a4844321313a9729237f6ded4fe82e6062237549873342096262ad2ec7b5596598feb94ebcfb392044e9cd83c0fd95b298d0817250177fba51cf8937313
6
+ metadata.gz: 537c535ae3d2196a5a2f0cb1508519c3b04a0ba4f75cf7844e3c08a0700149a8f89c5d9ca11a4a45fce973a6af45820c4e3982c4fabe2c8a7d9e5049f091bd04
7
+ data.tar.gz: 8bfe7bb70e2fbca9cac8d2117f168c356a8217b80eb36c03f6494266e0fef7ddd6f07aceeab51d70af6743db4767c9cf90ecc175db4f143ae19a11d15a0c6685
@@ -1,6 +1,7 @@
1
1
  module Tracker
2
2
  class Cli
3
3
  autoload :Command, 'tracker/cli/command'
4
+ autoload :View, 'tracker/cli/view'
4
5
 
5
6
  def initialize(argv)
6
7
  validate_configuration!
@@ -11,6 +12,13 @@ module Tracker
11
12
  case arguments[:method]
12
13
  when :list then Command::List.new(**arguments)
13
14
  when :fetch then Command::Fetch.new(**arguments)
15
+ when :create then Command::Create.new(**arguments)
16
+ when :destroy then Command::Destroy.new(**arguments)
17
+ when :request
18
+ case arguments[:request_method]
19
+ when :get
20
+ print connection.get(arguments[:url]).body.to_json
21
+ end
14
22
  end
15
23
  end
16
24
 
@@ -3,6 +3,8 @@ module Tracker
3
3
  module Command
4
4
  autoload :Fetch, 'tracker/cli/command/fetch'
5
5
  autoload :List, 'tracker/cli/command/list'
6
+ autoload :Create, 'tracker/cli/command/create'
7
+ autoload :Destroy, 'tracker/cli/command/destroy'
6
8
  end
7
9
  end
8
10
  end
@@ -0,0 +1,40 @@
1
+ module Tracker
2
+ class Cli
3
+ module Command
4
+ class Create
5
+ attr_reader :cli, :arguments
6
+
7
+ def initialize(cli: , object_type: , query_params: {}, **arguments)
8
+ @cli = cli
9
+ @arguments = arguments
10
+ @params = query_params.dup
11
+
12
+ setup_create(object_type, **arguments)
13
+ print cli.connection.post(@path, URI.encode_www_form(@params)).body.to_json
14
+ end
15
+
16
+ def setup_create(object_type, interactive: false, **arguments)
17
+ case object_type
18
+ when 'project'
19
+ @params.merge!(
20
+ name: View::Input.new('Name').value,
21
+ no_owner: View::Input.new('No owner', type: :boolean).value
22
+ ) if interactive
23
+
24
+ @path = 'projects'
25
+
26
+ when 'story'
27
+ @params.merge!({
28
+ name: View::Input.new('Name').value,
29
+ story_type: View::Select.new('What type of story is this?', [ :feature, :bug, :chore, :release ]).selection
30
+ }) if interactive
31
+
32
+ @path = "projects/#{Tracker.project}/stories"
33
+
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ module Tracker
2
+ class Cli
3
+ module Command
4
+ class Destroy
5
+ attr_reader :cli, :arguments
6
+
7
+ def initialize(cli: , object_type: , **arguments)
8
+ @cli = cli
9
+ @arguments = arguments
10
+
11
+ case object_type
12
+ when 'project' then destroy_project(**arguments)
13
+ end
14
+ end
15
+
16
+ def destroy_project(object_id: , **arguments)
17
+ res = cli.connection.get("projects/#{object_id}")
18
+
19
+ if res.status != 200
20
+ $stderr.print "#{res.body['error']}\n"
21
+ $stderr.print "#{res.body['general_problem']}\n"
22
+ $stderr.print "#{res.body['possible_fix']}\n"
23
+ return
24
+ end
25
+
26
+ project = res.body
27
+ $stderr.print "Warning: Destructive Action!\n\n"
28
+ confirm = View::Confirm.new(project['name'])
29
+
30
+ if confirm.confirmed?
31
+ print cli.connection.delete("projects/#{object_id}").body
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -10,12 +10,14 @@ module Tracker
10
10
 
11
11
  case object_type
12
12
  when 'story' then fetch_story(**arguments)
13
+ when 'account'
14
+ print cli.connection.fetch(accounts: object_id)
13
15
  end
14
16
  end
15
17
 
16
18
  def fetch_story(object_id: nil, interactive: false, commit: false, **arguments)
17
19
  if object_id
18
- story = cli.connection.fetch_story(object_id)
20
+ story = cli.connection.fetch(stories: object_id)
19
21
  elsif interactive
20
22
  story = select_story
21
23
  end
@@ -23,28 +25,26 @@ module Tracker
23
25
  if commit
24
26
  create_commit(story)
25
27
  else
26
- print "#{story['id']}\t#{story['name'].to_json}\n"
28
+ print "#{story['name']} (#{story['story_type']} ##{story['id']})\n\n"
29
+ print "#{story['labels'].join(', ')}\n\n" if story['labels'] && story['labels'].any?
30
+ print "#{story['description'] || '(no description)'}\n\n"
31
+ print "#{story['url']}\n"
27
32
  end
28
33
  end
29
34
 
30
35
  def select_story
31
36
  query_params = arguments.fetch(:query_params, {})
32
- stories = cli.connection.fetch_stories(project: Tracker.project, query: query_params)
33
- stories.each_with_index do |story, index|
34
- print "(#{index + 1}) #{story['id']} #{story['name'].to_json}\n"
35
- end
36
-
37
- print "\nWhich Story? "
38
- index = $stdin.gets.chomp.to_i - 1
39
- print "\n"
40
- stories[index]
37
+ stories = cli.connection.fetch(:stories, projects: Tracker.project, query: query_params)
38
+
39
+ select = View::Select.new('Which Story?', stories) { |story| "#{story['id']} #{story['name'].to_json}" }
40
+ select.selection
41
41
  end
42
42
 
43
43
  def create_commit(story)
44
- commit_message = "\"[##{story['id']}] #{story['name'].to_json[1..-2]}\""
44
+ commit_message = "[##{story['id']}] #{story['name'].to_json[1..-2]}"
45
45
  command = [ 'git', 'commit', '-m', commit_message ]
46
46
  _, stdout = Open3.popen2(*command)
47
- print stdout.read
47
+ $stderr.print stdout.read
48
48
  end
49
49
  end
50
50
  end
@@ -11,6 +11,9 @@ module Tracker
11
11
  case object_type
12
12
  when 'stories' then list_stories
13
13
  when 'projects' then list_projects
14
+ when 'memberships' then list_memberships
15
+ when 'accounts'
16
+ @objects = cli.connection.fetch(:accounts)
14
17
  end
15
18
 
16
19
  case arguments[:format_name]
@@ -23,22 +26,29 @@ module Tracker
23
26
 
24
27
  def list_stories
25
28
  query_params = arguments.fetch(:query_params, {})
26
- @objects = cli.connection.fetch_stories(project: Tracker.project, query: query_params)
27
- @columns = [ 'id', 'name', 'current_state', 'story_type' ]
29
+ @objects = cli.connection.fetch(:stories, projects: Tracker.project, query: query_params)
30
+ @columns = -> (row) {
31
+ [ row['id'], row['name'].to_json, row['current_state'], row['story_type'] ]
32
+ }
28
33
  end
29
34
 
30
35
  def list_projects
31
- @objects = cli.connection.get('projects').body
32
- @columns = [ 'id', 'name' ]
36
+ @objects = cli.connection.fetch(:projects)
37
+ @columns = -> (row) {
38
+ [ row['id'], row['name'].to_json ]
39
+ }
40
+ end
41
+
42
+ def list_memberships
43
+ @objects = cli.connection.fetch(:memberships, projects: Tracker.project)
44
+ @columns = -> (row) {
45
+ [ row['id'], row['person']['initials'], row['person']['name'].to_json ]
46
+ }
33
47
  end
34
48
 
35
49
  def print_objects
36
50
  objects.each do |object|
37
- row = object.map do |(k, v)|
38
- if columns.include?(k)
39
- k == 'name' ? v.to_json : v
40
- end
41
- end.compact
51
+ row = @columns.call(object)
42
52
 
43
53
  print row.join("\t")
44
54
  print "\n"
@@ -1,5 +1,5 @@
1
1
  module Tracker
2
2
  class Cli
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
@@ -0,0 +1,9 @@
1
+ module Tracker
2
+ class Cli
3
+ module View
4
+ autoload :Confirm, 'tracker/cli/view/confirm'
5
+ autoload :Select, 'tracker/cli/view/select'
6
+ autoload :Input, 'tracker/cli/view/input'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module Tracker
2
+ class Cli
3
+ module View
4
+ class Confirm
5
+ def initialize(confirm_string)
6
+ @confirm_string = confirm_string
7
+ $stderr.print "Type \"#{confirm_string}\" to confirm: "
8
+ @response_string = $stdin.gets.chomp
9
+ $stderr.print "\n\n"
10
+ end
11
+
12
+ def confirmed?
13
+ @confirm_string == @response_string
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ module Tracker
2
+ class Cli
3
+ module View
4
+ class Input
5
+ attr_reader :value
6
+
7
+ def initialize(attribute_name, type: nil)
8
+ type ||= :string
9
+
10
+ loop do
11
+ $stderr.print "#{attribute_name}#{' (y/n)' if type == :boolean}? "
12
+ value = $stdin.gets.chomp
13
+ $stderr.print "\n"
14
+
15
+ if type == :string
16
+ if value == ''
17
+ $stderr.print "Cannot be blank.\n"
18
+ else
19
+ @value = value
20
+ end
21
+
22
+ elsif type == :boolean
23
+ if value == 'y' || value == 'n'
24
+ @value = value == 'y'
25
+ else
26
+ $stderr.print "Please provide either \"y\" or \"n\"\n"
27
+ end
28
+ end
29
+
30
+ break unless @value.nil?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ module Tracker
2
+ class Cli
3
+ module View
4
+ class Select
5
+ attr_reader :selection
6
+
7
+ def initialize(prompt, options)
8
+ options.each_with_index do |option, index|
9
+ $stderr.print "(#{index + 1}) #{block_given? ? yield(option) : option}\n"
10
+ end
11
+
12
+ loop do
13
+ $stderr.print "\n#{prompt} "
14
+ user_input = $stdin.gets.chomp
15
+ index = user_input.to_i
16
+ selection = options[index - 1]
17
+
18
+ if index.to_s != user_input
19
+ $stderr.print "Please make a selection.\n"
20
+ elsif selection.nil?
21
+ $stderr.print "Please select one of the options above.\n"
22
+ else
23
+ @selection = selection
24
+ break
25
+ end
26
+ end
27
+
28
+ $stderr.print "\n"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -9,12 +9,10 @@ module Tracker
9
9
  end
10
10
  end
11
11
 
12
- def fetch_stories(project: , query: )
13
- get("projects/#{project}/stories", query).body
14
- end
15
-
16
- def fetch_story(story_id)
17
- get("stories/#{story_id}").body
12
+ def fetch(object_type = nil, query: nil, **url_parameters)
13
+ query ||= {}
14
+ url = url_parameters.to_a.flatten.concat([object_type]).compact.join('/')
15
+ get(url, query).body
18
16
  end
19
17
  end
20
18
  end
@@ -6,12 +6,17 @@ module Tracker
6
6
  ::OptionParser.new do |options|
7
7
  options.banner = <<-BANNER
8
8
 
9
- tracker --list OBJECT_TYPE (--format FORMAT_NAME)
10
- tracker --fetch OBJECT_TYPE (--id OBJECT_ID)(-i)
9
+ tracker --list OBJECT_TYPE (--format FORMAT_NAME) (--parameter key,value)
10
+ tracker --fetch OBJECT_TYPE --id OBJECT_ID (--commit)
11
+ -i (--parameter key,value) (--commit)
12
+ tracker --create OBJECT_TYPE (-i) (--parameter key,value ...)
13
+ tracker --destroy OBJECT_TYPE --id OBJECT_ID
14
+ tracker --get URL
11
15
 
12
16
  BANNER
13
17
 
14
- options.on '--list OBJECT_TYPE', 'one of: stories, projects' do |object_type|
18
+ options.separator "\n\e[37mLIST\e[0m"
19
+ options.on '--list OBJECT_TYPE', 'one of: accounts, memberships, projects, stories' do |object_type|
15
20
  arguments[:method] = :list
16
21
  arguments[:object_type] = object_type
17
22
  end
@@ -27,6 +32,8 @@ BANNER
27
32
  arguments[:format_name] = format_name
28
33
  end
29
34
 
35
+ options.separator "\n\e[37mFETCH\e[0m"
36
+
30
37
  options.on '--fetch OBJECT_TYPE', 'story' do |object_type|
31
38
  arguments[:method] = :fetch
32
39
  arguments[:object_type] = object_type
@@ -36,13 +43,35 @@ BANNER
36
43
  arguments[:object_id] = object_id
37
44
  end
38
45
 
39
- options.on '-i', 'interactive --fetch' do
46
+ options.on '-i', 'interactive --fetch or --create' do
40
47
  arguments[:interactive] = true
41
48
  end
42
49
 
43
- options.on '--commit', 'make a commit' do
50
+ options.on '--commit', 'make a commit (must be used with --fetch story)' do
44
51
  arguments[:commit] = true
45
52
  end
53
+
54
+ options.separator "\n\e[37mCREATE\e[0m"
55
+
56
+ options.on '--create OBJECT_TYPE', 'create a project or story' do |object_type|
57
+ arguments[:method] = :create
58
+ arguments[:object_type] = object_type
59
+ end
60
+
61
+ options.separator "\n\e[37mDESTROY\e[0m"
62
+
63
+ options.on '--destroy OBJECT_TYPE', 'destroy a project' do |object_type|
64
+ arguments[:method] = :destroy
65
+ arguments[:object_type] = object_type
66
+ end
67
+
68
+ options.separator "\n\e[37mGET\e[0m"
69
+
70
+ options.on '--get URL', 'get a url endpoint' do |url|
71
+ arguments[:method] = :request
72
+ arguments[:request_method] = :get
73
+ arguments[:url] = url
74
+ end
46
75
 
47
76
  options.parse!(argv)
48
77
  end
@@ -51,3 +80,4 @@ BANNER
51
80
  end
52
81
  end
53
82
  end
83
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracker-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Bergstein
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-03 00:00:00.000000000 Z
11
+ date: 2016-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,9 +114,15 @@ files:
114
114
  - lib/tracker.rb
115
115
  - lib/tracker/cli.rb
116
116
  - lib/tracker/cli/command.rb
117
+ - lib/tracker/cli/command/create.rb
118
+ - lib/tracker/cli/command/destroy.rb
117
119
  - lib/tracker/cli/command/fetch.rb
118
120
  - lib/tracker/cli/command/list.rb
119
121
  - lib/tracker/cli/version.rb
122
+ - lib/tracker/cli/view.rb
123
+ - lib/tracker/cli/view/confirm.rb
124
+ - lib/tracker/cli/view/input.rb
125
+ - lib/tracker/cli/view/select.rb
120
126
  - lib/tracker/client.rb
121
127
  - lib/tracker/option_parser.rb
122
128
  - tracker-cli.gemspec