tracker-cli 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9f189c896ac1d5dcf3de93c29dfa2d959dec382d
4
+ data.tar.gz: bf3bbbd61e66e09de3e0beee5bdfc34aa49e067f
5
+ SHA512:
6
+ metadata.gz: 610917a9319d41d41eb073ddc6dc7f9ba1ffdd3741f839fdcf604802c1bee3c34627fe07a2eedd6f235b0e41ac0848527788292965ec48b1153f18511a94e44b
7
+ data.tar.gz: 857d4a4844321313a9729237f6ded4fe82e6062237549873342096262ad2ec7b5596598feb94ebcfb392044e9cd83c0fd95b298d0817250177fba51cf8937313
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .idea
2
+ .rspec
3
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,52 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tracker-cli (0.1.0)
5
+ faraday
6
+ faraday_middleware
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.4.0)
12
+ crack (0.4.3)
13
+ safe_yaml (~> 1.0.0)
14
+ diff-lcs (1.2.5)
15
+ faraday (0.9.2)
16
+ multipart-post (>= 1.2, < 3)
17
+ faraday_middleware (0.10.0)
18
+ faraday (>= 0.7.4, < 0.10)
19
+ hashdiff (0.3.0)
20
+ multipart-post (2.0.0)
21
+ rake (10.4.2)
22
+ rspec (3.5.0)
23
+ rspec-core (~> 3.5.0)
24
+ rspec-expectations (~> 3.5.0)
25
+ rspec-mocks (~> 3.5.0)
26
+ rspec-core (3.5.3)
27
+ rspec-support (~> 3.5.0)
28
+ rspec-expectations (3.5.0)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.5.0)
31
+ rspec-mocks (3.5.0)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.5.0)
34
+ rspec-support (3.5.0)
35
+ safe_yaml (1.0.4)
36
+ webmock (2.1.0)
37
+ addressable (>= 2.3.6)
38
+ crack (>= 0.3.2)
39
+ hashdiff
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ bundler (~> 1.13)
46
+ rake (~> 10.0)
47
+ rspec
48
+ tracker-cli!
49
+ webmock
50
+
51
+ BUNDLED WITH
52
+ 1.13.1
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2016 Benjamin Joffe Bergstein <bennyjbergstein@gmail.com>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # Tracker CLI
2
+
3
+ A mostly-for-fun Command Line Interface (CLI) for Pivotal Tracker
4
+
5
+ # Installation
6
+
7
+ ## Configure
8
+
9
+ An API Token and Project ID are required in the configuration file.
10
+
11
+ ### 1) Find your API Token
12
+
13
+ Your API Token is located at https://www.pivotaltracker.com/profile.
14
+
15
+ ### 2) Find your Project ID
16
+
17
+ Your Project ID is located in the project's url. If your project url is https://www.pivotaltracker.com/n/projects/999999, this project's id is 999999.
18
+
19
+ ### 3) Create a config file
20
+
21
+ Open ~/.tracker.config in your favorite text editor and enter the following yaml:
22
+
23
+ ```
24
+ api_token: {{API_TOKEN}}
25
+ project: {{PROJECT_ID}}
26
+ ```
27
+
28
+ ## Add to your Gemfile
29
+
30
+ ```
31
+ gem 'tracker-cli', github: 'benastan/tracker-cli'
32
+ ```
33
+
34
+ ## Take it for a test drive
35
+
36
+ ```
37
+ tracker --list stories
38
+ => 00001 "My First Story"
39
+ ```
40
+
41
+ # Usage
42
+
43
+ ## List
44
+
45
+ ```
46
+ tracker --list stories
47
+
48
+ 00001 "Story 1"
49
+ 00002 "Story 2"
50
+
51
+ tracker --list stories --format json # JSON format
52
+ tracker --list projects
53
+ tracker --list projects --format json # JSON format
54
+ ```
55
+
56
+ ## Fetch
57
+
58
+ ```
59
+ tracker --fetch [OBJECT_TYPE]
60
+ ```
61
+
62
+ `OBJECT_TYPE` can be story.
63
+
64
+ ### Story
65
+
66
+ A story can be fetched interactively:
67
+
68
+ ```
69
+ tracker --fetch story -i
70
+
71
+ (1) 00001 "Story #1"
72
+ (2) 00002 "Story #2"
73
+ (3) 00002 "Story #3"
74
+
75
+ Which Story? 1
76
+ ```
77
+
78
+ Or with an id:
79
+
80
+ ```
81
+ tracker --fetch story --id 00001
82
+ ```
83
+
84
+ Make a commit for a started story of your choice.
85
+
86
+ ```
87
+ tracker --fetch story -i --parameter with_state,started --commit
88
+ (1) 133544285 "Test Story"
89
+
90
+ Which Story? 1
91
+
92
+ [master 2886e30] [#133544285] Test Story
93
+ 7 files changed, 94 insertions(+), 23 deletions(-)
94
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler'
4
+ Bundler.require
5
+ $LOAD_PATH.push(File.expand_path('./lib'))
6
+ require 'tracker'
7
+ require 'irb'
8
+
9
+ @client = Tracker::Client.new(Tracker.api_token)
10
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
data/bin/tracker ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ $LOAD_PATH.push(File.expand_path('./lib'))
6
+ require 'tracker'
7
+ require 'tracker/cli'
8
+
9
+ Tracker::Cli.new(ARGV)
@@ -0,0 +1,52 @@
1
+ module Tracker
2
+ class Cli
3
+ module Command
4
+ class Fetch
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 'story' then fetch_story(**arguments)
13
+ end
14
+ end
15
+
16
+ def fetch_story(object_id: nil, interactive: false, commit: false, **arguments)
17
+ if object_id
18
+ story = cli.connection.fetch_story(object_id)
19
+ elsif interactive
20
+ story = select_story
21
+ end
22
+
23
+ if commit
24
+ create_commit(story)
25
+ else
26
+ print "#{story['id']}\t#{story['name'].to_json}\n"
27
+ end
28
+ end
29
+
30
+ def select_story
31
+ 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]
41
+ end
42
+
43
+ def create_commit(story)
44
+ commit_message = "\"[##{story['id']}] #{story['name'].to_json[1..-2]}\""
45
+ command = [ 'git', 'commit', '-m', commit_message ]
46
+ _, stdout = Open3.popen2(*command)
47
+ print stdout.read
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,50 @@
1
+ module Tracker
2
+ class Cli
3
+ module Command
4
+ class List
5
+ attr_reader :cli, :arguments, :objects, :columns
6
+
7
+ def initialize(cli: , object_type: , **arguments)
8
+ @cli = cli
9
+ @arguments = arguments
10
+
11
+ case object_type
12
+ when 'stories' then list_stories
13
+ when 'projects' then list_projects
14
+ end
15
+
16
+ case arguments[:format_name]
17
+ when 'json'
18
+ print JSON.dump(objects)
19
+ else
20
+ print_objects
21
+ end
22
+ end
23
+
24
+ def list_stories
25
+ 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' ]
28
+ end
29
+
30
+ def list_projects
31
+ @objects = cli.connection.get('projects').body
32
+ @columns = [ 'id', 'name' ]
33
+ end
34
+
35
+ def print_objects
36
+ 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
42
+
43
+ print row.join("\t")
44
+ print "\n"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,8 @@
1
+ module Tracker
2
+ class Cli
3
+ module Command
4
+ autoload :Fetch, 'tracker/cli/command/fetch'
5
+ autoload :List, 'tracker/cli/command/list'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Tracker
2
+ class Cli
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ module Tracker
2
+ class Cli
3
+ autoload :Command, 'tracker/cli/command'
4
+
5
+ def initialize(argv)
6
+ validate_configuration!
7
+
8
+ arguments = OptionParser.parse!(argv)
9
+ arguments[:cli] = self
10
+
11
+ case arguments[:method]
12
+ when :list then Command::List.new(**arguments)
13
+ when :fetch then Command::Fetch.new(**arguments)
14
+ end
15
+ end
16
+
17
+ def connection
18
+ @connection ||= Client.new(Tracker.api_token)
19
+ end
20
+
21
+ def validate_configuration!
22
+ if Tracker.api_token.nil?
23
+ error = "API Token missing. Find yours at https://www.pivotaltracker.com/profile and add: \n\napi_token: {{YOUR_TOKEN}}\n\n to ~/.tracker.config"
24
+ end
25
+
26
+ if Tracker.project.nil?
27
+ error = "Project id is missing. Find the id in the url for the project and add: \n\nproject: {{YOUR_PROJECT_ID}}\n\n to ~/.tracker.config"
28
+ end
29
+
30
+ if error
31
+ raise ArgumentError, error
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ module Tracker
2
+ class Client < Faraday::Connection
3
+ def initialize(api_token)
4
+ super('https://www.pivotaltracker.com/services/v5') do | builder |
5
+ builder.headers['X-Tracker-Token'] = api_token
6
+ builder.headers['X-TrackerToken'] = api_token
7
+ builder.response :json
8
+ builder.adapter Faraday.default_adapter
9
+ end
10
+ end
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
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,53 @@
1
+ module Tracker
2
+ module OptionParser
3
+ def self.parse!(argv)
4
+ arguments = {}
5
+
6
+ ::OptionParser.new do |options|
7
+ options.banner = <<-BANNER
8
+
9
+ tracker --list OBJECT_TYPE (--format FORMAT_NAME)
10
+ tracker --fetch OBJECT_TYPE (--id OBJECT_ID)(-i)
11
+
12
+ BANNER
13
+
14
+ options.on '--list OBJECT_TYPE', 'one of: stories, projects' do |object_type|
15
+ arguments[:method] = :list
16
+ arguments[:object_type] = object_type
17
+ end
18
+
19
+ options.on '--parameter QUERY_PARAM', 'set a query param for get requests in the form of key,value. Can be used multiple times. See https://www.pivotaltracker.com/help/api/rest/v5 for possible keys', Array do |query_param|
20
+ arguments[:query_params] ||= {}
21
+ key, value, *_ = query_param
22
+ arguments[:query_params][key] = value
23
+
24
+ end
25
+
26
+ options.on '--format FORMAT_NAME', 'none (default), json' do |format_name|
27
+ arguments[:format_name] = format_name
28
+ end
29
+
30
+ options.on '--fetch OBJECT_TYPE', 'story' do |object_type|
31
+ arguments[:method] = :fetch
32
+ arguments[:object_type] = object_type
33
+ end
34
+
35
+ options.on '--id OBJECT_ID', 'OBJECT_ID for --fetch' do |object_id|
36
+ arguments[:object_id] = object_id
37
+ end
38
+
39
+ options.on '-i', 'interactive --fetch' do
40
+ arguments[:interactive] = true
41
+ end
42
+
43
+ options.on '--commit', 'make a commit' do
44
+ arguments[:commit] = true
45
+ end
46
+
47
+ options.parse!(argv)
48
+ end
49
+
50
+ arguments
51
+ end
52
+ end
53
+ end
data/lib/tracker.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'psych'
2
+ require 'optparse'
3
+ require 'pathname'
4
+ require 'faraday'
5
+ require 'faraday_middleware'
6
+ require 'open3'
7
+
8
+ module Tracker
9
+ autoload :Cli, 'tracker/cli'
10
+ autoload :Client, 'tracker/client'
11
+ autoload :OptionParser, 'tracker/option_parser'
12
+
13
+ def self.api_token
14
+ config['api_token']
15
+ end
16
+
17
+ def self.project
18
+ config['project']
19
+ end
20
+
21
+ def self.config
22
+ if File.exist?(configuration_file_location)
23
+ content = File.read(configuration_file_location)
24
+ Psych.load(content)
25
+ else
26
+ {}
27
+ end
28
+ end
29
+
30
+ def self.configuration_file_location
31
+ @configuration_file_location ||= Pathname(ENV['HOME']).join('.tracker.config').to_s
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tracker/cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tracker-cli"
8
+ spec.version = Tracker::Cli::VERSION
9
+ spec.authors = ["Benjamin Bergstein"]
10
+ spec.email = ["bennyjbergstein@gmail.com"]
11
+
12
+ spec.summary = "A mostly for-fun Command Line Interface (CLI) for Pivotal Tracker"
13
+ spec.description = "Supports listing/fetching stories and projects"
14
+ spec.homepage = "https://github.com/benastan/tracker-cli"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against " \
22
+ "public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+
29
+ spec.bindir = "bin"
30
+ spec.executables << 'tracker'
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.13"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency 'rspec'
36
+ spec.add_development_dependency 'webmock'
37
+
38
+ spec.add_dependency 'faraday'
39
+ spec.add_dependency 'faraday_middleware'
40
+
41
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tracker-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Benjamin Bergstein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: faraday_middleware
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Supports listing/fetching stories and projects
98
+ email:
99
+ - bennyjbergstein@gmail.com
100
+ executables:
101
+ - tracker
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - Gemfile
107
+ - Gemfile.lock
108
+ - LICENSE
109
+ - README.md
110
+ - Rakefile
111
+ - bin/console
112
+ - bin/setup
113
+ - bin/tracker
114
+ - lib/tracker.rb
115
+ - lib/tracker/cli.rb
116
+ - lib/tracker/cli/command.rb
117
+ - lib/tracker/cli/command/fetch.rb
118
+ - lib/tracker/cli/command/list.rb
119
+ - lib/tracker/cli/version.rb
120
+ - lib/tracker/client.rb
121
+ - lib/tracker/option_parser.rb
122
+ - tracker-cli.gemspec
123
+ homepage: https://github.com/benastan/tracker-cli
124
+ licenses: []
125
+ metadata:
126
+ allowed_push_host: https://rubygems.org
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.5.1
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: A mostly for-fun Command Line Interface (CLI) for Pivotal Tracker
147
+ test_files: []