tempest_time 0.6.0 → 0.6.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/tempest_time/api/authorization.rb +1 -1
- data/lib/tempest_time/api/jira_api/authorization.rb +4 -4
- data/lib/tempest_time/api/tempo_api/authorization.rb +3 -3
- data/lib/tempest_time/api/tempo_api/requests/create_worklog.rb +3 -3
- data/lib/tempest_time/cli.rb +13 -19
- data/lib/tempest_time/command.rb +2 -0
- data/lib/tempest_time/commands/config.rb +2 -8
- data/lib/tempest_time/commands/config/edit.rb +4 -4
- data/lib/tempest_time/commands/config/setup.rb +6 -6
- data/lib/tempest_time/commands/issue.rb +12 -13
- data/lib/tempest_time/commands/issue/list.rb +56 -0
- data/lib/tempest_time/commands/issue/open.rb +28 -0
- data/lib/tempest_time/commands/report.rb +5 -5
- data/lib/tempest_time/commands/teams/add.rb +2 -2
- data/lib/tempest_time/commands/teams/delete.rb +4 -4
- data/lib/tempest_time/commands/teams/edit.rb +9 -11
- data/lib/tempest_time/commands/track.rb +13 -21
- data/lib/tempest_time/helpers/git_helper.rb +13 -0
- data/lib/tempest_time/setting.rb +45 -42
- data/lib/tempest_time/settings/app.rb +12 -0
- data/lib/tempest_time/settings/authorization.rb +3 -10
- data/lib/tempest_time/settings/teams.rb +7 -8
- data/lib/tempest_time/version.rb +2 -2
- metadata +6 -3
- data/lib/tempest_time/commands/issues.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecfd390e581133802a83716b8c068cdc40e5c6890638833a253b3bfb5295726e
|
4
|
+
data.tar.gz: 464e98b2dba3d40deb03f8d66b2dd3796db5b9006cdcee46a6e98ee8a42b296f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 567a89a440c7a644945289d8c47feb749f74b10b6a3d36333ed40c7f3cf6f7498c648fac4256497f6e27544a1fc92ce70589063aedee57cd95cfa29ce63c6a38
|
7
|
+
data.tar.gz: 6762dd7c7175db615f5e783f622d9a676044e10ace1b91cbc7a56ce6fb74ddefa22fca008e2f982cf26515e4fda1b65e221ad48748013d7ce055eaebae80dc4f
|
data/Gemfile.lock
CHANGED
@@ -9,19 +9,19 @@ module JiraAPI
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def subdomain
|
12
|
-
settings.
|
12
|
+
settings.fetch('subdomain')
|
13
13
|
end
|
14
14
|
|
15
15
|
def user
|
16
|
-
settings.
|
16
|
+
settings.fetch('username')
|
17
17
|
end
|
18
18
|
|
19
19
|
def email
|
20
|
-
settings.
|
20
|
+
settings.fetch('email')
|
21
21
|
end
|
22
22
|
|
23
23
|
def token
|
24
|
-
settings.
|
24
|
+
settings.fetch('jira_token')
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -9,15 +9,15 @@ module TempoAPI
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def user
|
12
|
-
settings.
|
12
|
+
settings.fetch('username')
|
13
13
|
end
|
14
14
|
|
15
15
|
def email
|
16
|
-
settings.
|
16
|
+
settings.fetch('email')
|
17
17
|
end
|
18
18
|
|
19
19
|
def token
|
20
|
-
settings.
|
20
|
+
settings.fetch('tempo_token')
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -8,7 +8,7 @@ module TempoAPI
|
|
8
8
|
super
|
9
9
|
@seconds = seconds
|
10
10
|
@remaining = options['remaining']
|
11
|
-
@
|
11
|
+
@issue = options['issue']
|
12
12
|
@message = options['message']
|
13
13
|
@date = options['date'] ? Date.parse(options['date']) : Date.today
|
14
14
|
@billable = options['billable']
|
@@ -16,7 +16,7 @@ module TempoAPI
|
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
attr_reader :
|
19
|
+
attr_reader :issue, :remaining, :seconds, :message, :date, :billable
|
20
20
|
|
21
21
|
def request_method
|
22
22
|
'post'
|
@@ -32,7 +32,7 @@ module TempoAPI
|
|
32
32
|
|
33
33
|
def request_body
|
34
34
|
{
|
35
|
-
"issueKey":
|
35
|
+
"issueKey": issue,
|
36
36
|
"timeSpentSeconds": seconds,
|
37
37
|
"billableSeconds": billable_time,
|
38
38
|
"remainingEstimateSeconds": remaining,
|
data/lib/tempest_time/cli.rb
CHANGED
@@ -23,6 +23,11 @@ module TempestTime
|
|
23
23
|
'teams', 'teams [SUBCOMMAND]',
|
24
24
|
'Add or modify teams.'
|
25
25
|
|
26
|
+
require_relative 'commands/issue'
|
27
|
+
register TempestTime::Commands::Issue,
|
28
|
+
'issue', 'issue [SUBCOMMAND]',
|
29
|
+
'View and modify Jira issues.'
|
30
|
+
|
26
31
|
desc 'list', 'List worklogs for a specific date.'
|
27
32
|
option :user, aliases: '-u', type: :string
|
28
33
|
def list
|
@@ -30,7 +35,6 @@ module TempestTime
|
|
30
35
|
TempestTime::Commands::List.new(options).execute
|
31
36
|
end
|
32
37
|
|
33
|
-
|
34
38
|
desc 'submit', 'Submit your timesheet to a supervisor.'
|
35
39
|
def submit(*)
|
36
40
|
require_relative 'commands/submit'
|
@@ -57,23 +61,11 @@ module TempestTime
|
|
57
61
|
TempestTime::Commands::Delete.new(worklogs, options).execute
|
58
62
|
end
|
59
63
|
|
60
|
-
desc
|
61
|
-
def issue(issue)
|
62
|
-
require_relative 'commands/issue'
|
63
|
-
TempestTime::Commands::Issue.new(issue).execute
|
64
|
-
end
|
65
|
-
|
66
|
-
desc 'issues', "View a list of a user's assigned tickets. (Defaults to you.)"
|
67
|
-
def issues(user = nil)
|
68
|
-
require_relative 'commands/issues'
|
69
|
-
TempestTime::Commands::Issues.new(user, options).execute
|
70
|
-
end
|
71
|
-
|
72
|
-
desc "track [TIME] [TICKET(S)]", 'Track time to Tempo.'
|
64
|
+
desc "track [TIME] [ISSUE(S)]", 'Track time to Tempo.'
|
73
65
|
long_desc <<-LONGDESC
|
74
|
-
`tempest track` or `tempest log` will track the specified number of hours or minutes to the
|
75
|
-
If not specified, it will check the name of the current git branch and automatically track the logged time to that
|
76
|
-
You can also split a bank of time evenly across multiple
|
66
|
+
`tempest track` or `tempest log` will track the specified number of hours or minutes to the issue(s) specified.\n
|
67
|
+
If not specified, it will check the name of the current git branch and automatically track the logged time to that issue, if found.\n
|
68
|
+
You can also split a bank of time evenly across multiple issues with the --split flag.\n
|
77
69
|
e.g. tempest track 1.5h BCIT-1 --message='Tracking 1.5 hours.'\n
|
78
70
|
e.g. tempest log 90m BCIT-1 BCIT-2 --message='Tracking 90 minutes.'\n
|
79
71
|
e.g. tempest track 3h BCIT-1 BCIT-2 BCIT-3 --message='Tracking 1 hour.'\n
|
@@ -84,9 +76,11 @@ module TempestTime
|
|
84
76
|
option :billable, aliases: '-b', type: :boolean, default: true
|
85
77
|
option :split, aliases: '-s', type: :boolean, default: false
|
86
78
|
option :autoconfirm, type: :boolean, default: false
|
87
|
-
def track(time, *
|
79
|
+
def track(time, *issues)
|
88
80
|
require_relative 'commands/track'
|
89
|
-
TempestTime::Commands::Track.new(time,
|
81
|
+
TempestTime::Commands::Track.new(time, issues, options).execute
|
90
82
|
end
|
83
|
+
|
84
|
+
map log: :track
|
91
85
|
end
|
92
86
|
end
|
data/lib/tempest_time/command.rb
CHANGED
@@ -3,12 +3,14 @@
|
|
3
3
|
require 'forwardable'
|
4
4
|
require_relative 'helpers/time_helper'
|
5
5
|
require_relative 'helpers/formatting_helper'
|
6
|
+
require_relative 'helpers/git_helper'
|
6
7
|
|
7
8
|
module TempestTime
|
8
9
|
class Command
|
9
10
|
extend Forwardable
|
10
11
|
include TempestTime::Helpers::TimeHelper
|
11
12
|
include TempestTime::Helpers::FormattingHelper
|
13
|
+
include TempestTime::Helpers::GitHelper
|
12
14
|
|
13
15
|
def_delegators :command, :run
|
14
16
|
|
@@ -15,15 +15,9 @@ module TempestTime
|
|
15
15
|
end
|
16
16
|
|
17
17
|
desc 'edit', 'Modify your user credentials.'
|
18
|
-
method_option :help, aliases: '-h', type: :boolean,
|
19
|
-
desc: 'Display usage information'
|
20
18
|
def edit(*)
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
require_relative 'config/edit'
|
25
|
-
TempestTime::Commands::Config::Edit.new(options).execute
|
26
|
-
end
|
19
|
+
require_relative 'config/edit'
|
20
|
+
TempestTime::Commands::Config::Edit.new(options).execute
|
27
21
|
end
|
28
22
|
end
|
29
23
|
end
|
@@ -12,7 +12,7 @@ module TempestTime
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute(input: $stdin, output: $stdout)
|
15
|
-
settings = TempestTime::Settings::Authorization
|
15
|
+
settings = TempestTime::Settings::Authorization.new
|
16
16
|
setting = prompt.select(
|
17
17
|
"Which #{pastel.green('setting')} would you like to edit?",
|
18
18
|
settings.keys
|
@@ -20,11 +20,11 @@ module TempestTime
|
|
20
20
|
|
21
21
|
new_value = prompt.ask(
|
22
22
|
"Enter the #{pastel.green('new value')}.",
|
23
|
-
default: settings.
|
23
|
+
default: settings.fetch(setting)
|
24
24
|
)
|
25
25
|
|
26
|
-
if new_value != settings.
|
27
|
-
settings.
|
26
|
+
if new_value != settings.fetch(setting)
|
27
|
+
settings.set(setting, new_value)
|
28
28
|
prompt.say(pastel.green('Setting updated!'))
|
29
29
|
else
|
30
30
|
prompt.say('Nothing changed.')
|
@@ -39,13 +39,13 @@ module TempestTime
|
|
39
39
|
)
|
40
40
|
end
|
41
41
|
|
42
|
-
authorization = TempestTime::Settings::Authorization
|
42
|
+
authorization = TempestTime::Settings::Authorization.new
|
43
43
|
|
44
|
-
authorization.
|
45
|
-
authorization.
|
46
|
-
authorization.
|
47
|
-
authorization.
|
48
|
-
authorization.
|
44
|
+
authorization.set('email', email)
|
45
|
+
authorization.set('username', username)
|
46
|
+
authorization.set('subdomain', subdomain)
|
47
|
+
authorization.set('jira_token', jira_token)
|
48
|
+
authorization.set('tempo_token', tempo_token)
|
49
49
|
|
50
50
|
puts pastel.green('Setup complete!')
|
51
51
|
end
|
@@ -1,24 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative '../settings/authorization'
|
3
|
+
require 'thor'
|
5
4
|
|
6
5
|
module TempestTime
|
7
6
|
module Commands
|
8
|
-
class Issue <
|
9
|
-
def initialize(issue)
|
10
|
-
@issue = issue.upcase
|
11
|
-
end
|
7
|
+
class Issue < Thor
|
12
8
|
|
13
|
-
|
14
|
-
command.run("open #{url(@issue)}")
|
15
|
-
end
|
9
|
+
namespace :issue
|
16
10
|
|
17
|
-
|
11
|
+
desc 'list', 'Set up Tempest with your credentials.'
|
12
|
+
def list(*)
|
13
|
+
require_relative 'issue/list'
|
14
|
+
TempestTime::Commands::Issue::List.new(options).execute
|
15
|
+
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
desc 'open', 'Open an issue in your browser. (Default: current branch)'
|
18
|
+
def open(issue = '')
|
19
|
+
require_relative 'issue/open'
|
20
|
+
TempestTime::Commands::Issue::Open.new(issue).execute
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command'
|
4
|
+
require_relative '../../api/jira_api/requests/get_user_issues'
|
5
|
+
|
6
|
+
module TempestTime
|
7
|
+
module Commands
|
8
|
+
class Issue
|
9
|
+
class List < TempestTime::Command
|
10
|
+
def initialize(options)
|
11
|
+
@user = options[:user] || current_user
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute(input: $stdin, output: $stdout)
|
16
|
+
request = JiraAPI::Requests::GetUserIssues.new(@user)
|
17
|
+
message = "Getting issues for #{request.requested_user}"
|
18
|
+
response = with_spinner(message) do |spinner|
|
19
|
+
request.send_request.tap { spinner.stop }
|
20
|
+
end
|
21
|
+
puts format_output(response.issues)
|
22
|
+
browser_prompt(response.issues)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def browser_prompt(issues)
|
28
|
+
abort if prompt.no?('Open an issue in your browser?')
|
29
|
+
issue = prompt.select(
|
30
|
+
'Select an issue to open in browser, or press ^C to quit.',
|
31
|
+
issues.map(&:key),
|
32
|
+
per_page: 5
|
33
|
+
)
|
34
|
+
require_relative 'open'
|
35
|
+
Open.new(issue).execute
|
36
|
+
end
|
37
|
+
|
38
|
+
def format_output(issues)
|
39
|
+
table.new(
|
40
|
+
%w[Status Issue Summary],
|
41
|
+
issues.map { |issue| row(issue) }
|
42
|
+
).render(:ascii, padding: [0, 1], column_widths: [15, 10, 30])
|
43
|
+
end
|
44
|
+
|
45
|
+
def row(issue)
|
46
|
+
[issue.status, issue.key, issue.summary]
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_user
|
50
|
+
require_relative '../../settings/authorization'
|
51
|
+
TempestTime::Settings::Authorization.new.fetch('username')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command'
|
4
|
+
require_relative '../../settings/authorization'
|
5
|
+
|
6
|
+
module TempestTime
|
7
|
+
module Commands
|
8
|
+
class Issue
|
9
|
+
class Open < TempestTime::Command
|
10
|
+
def initialize(issue)
|
11
|
+
@issue = issue.upcase
|
12
|
+
@issue = automatic_issue if issue.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute(input: $stdin, output: $stdout)
|
16
|
+
command.run("open #{url(@issue)}")
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def url(issue)
|
22
|
+
domain = TempestTime::Settings::Authorization.new.fetch('subdomain')
|
23
|
+
"https://#{domain}.atlassian.net/browse/#{issue}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -14,11 +14,12 @@ module TempestTime
|
|
14
14
|
def initialize(users, options)
|
15
15
|
@users = users || []
|
16
16
|
@team = options[:team]
|
17
|
+
@teams = TempestTime::Settings::Teams.new
|
17
18
|
end
|
18
19
|
|
19
20
|
def execute(input: $stdin, output: $stdout)
|
20
21
|
@users = user_prompt if @users.empty? && @team.nil?
|
21
|
-
@users.push(
|
22
|
+
@users.push(teams.members(@team)) if @team
|
22
23
|
abort('No users specified.') unless @users.any?
|
23
24
|
|
24
25
|
@week = week_prompt('Please select the week to report.')
|
@@ -49,16 +50,15 @@ module TempestTime
|
|
49
50
|
]
|
50
51
|
end
|
51
52
|
|
52
|
-
teams
|
53
|
-
if teams.keys.empty?
|
53
|
+
if @teams.names.empty?
|
54
54
|
abort('You have no teams yet! Go make one! (tempest teams add)')
|
55
55
|
end
|
56
56
|
|
57
57
|
team = prompt.select(
|
58
58
|
"Please select a #{pastel.green('team')}.",
|
59
|
-
teams.
|
59
|
+
@teams.names
|
60
60
|
)
|
61
|
-
teams.members(team)
|
61
|
+
@teams.members(team)
|
62
62
|
end
|
63
63
|
|
64
64
|
def start_date
|
@@ -12,7 +12,7 @@ module TempestTime
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute(input: $stdin, output: $stdout)
|
15
|
-
teams = TempestTime::Settings::Teams
|
15
|
+
teams = TempestTime::Settings::Teams.new
|
16
16
|
message =
|
17
17
|
'Please enter ' + pastel.green('the members') + " of this team. "\
|
18
18
|
'(Comma-separated, e.g. jkirk, jpicard, bsisko, kjaneway) '
|
@@ -20,7 +20,7 @@ module TempestTime
|
|
20
20
|
q.convert ->(input) { input.split(/,\s*/) }
|
21
21
|
end
|
22
22
|
name = prompt.ask('Please enter ' + pastel.green('the name') + ' of your new team.')
|
23
|
-
teams.
|
23
|
+
teams.set(name, members)
|
24
24
|
prompt.say(pastel.green('Success!'))
|
25
25
|
end
|
26
26
|
end
|
@@ -8,18 +8,18 @@ module TempestTime
|
|
8
8
|
class Teams
|
9
9
|
class Delete < TempestTime::Command
|
10
10
|
def initialize(options)
|
11
|
+
@teams = TempestTime::Settings::Teams.new
|
11
12
|
@options = options
|
12
13
|
end
|
13
14
|
|
14
15
|
def execute(input: $stdin, output: $stdout)
|
15
|
-
teams
|
16
|
-
abort("There are no teams to delete!") unless teams.keys.any?
|
16
|
+
abort("There are no teams to delete!") unless @teams.keys.any?
|
17
17
|
team = prompt.select(
|
18
18
|
"Which #{pastel.green('team')} would you like to delete?",
|
19
|
-
teams.
|
19
|
+
@teams.names
|
20
20
|
)
|
21
21
|
if prompt.yes?(pastel.red("Are you sure you want to delete #{team}?"))
|
22
|
-
teams.delete(team)
|
22
|
+
@teams.delete(team)
|
23
23
|
prompt.say("Successfully #{pastel.red("deleted #{team}!")}")
|
24
24
|
else
|
25
25
|
abort('Nothing was deleted.')
|
@@ -12,11 +12,11 @@ module TempestTime
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute(input: $stdin, output: $stdout)
|
15
|
-
teams = TempestTime::Settings::Teams
|
16
|
-
abort("There are no teams to edit!") unless teams.
|
15
|
+
teams = TempestTime::Settings::Teams.new
|
16
|
+
abort("There are no teams to edit!") unless teams.names.any?
|
17
17
|
team = prompt.select(
|
18
18
|
"Which #{pastel.green('team')} would you like to edit?",
|
19
|
-
teams.
|
19
|
+
teams.names
|
20
20
|
)
|
21
21
|
|
22
22
|
members = teams.members(team)
|
@@ -25,23 +25,21 @@ module TempestTime
|
|
25
25
|
members + ['Add New Member']
|
26
26
|
)
|
27
27
|
|
28
|
-
|
28
|
+
replacement = prompt.ask(
|
29
29
|
"Enter the #{pastel.green('new name')}. "\
|
30
30
|
"Leave blank to #{pastel.red('delete')}."
|
31
31
|
)
|
32
32
|
|
33
|
-
|
33
|
+
teams.remove(team, member)
|
34
34
|
|
35
|
-
if
|
36
|
-
teams.update(team, members)
|
35
|
+
if replacement.nil?
|
37
36
|
prompt.say("Deleted #{pastel.red(member)}!")
|
38
37
|
else
|
39
|
-
|
40
|
-
|
41
|
-
prompt.say("Added #{pastel.green(replace)}")
|
38
|
+
teams.append(team, replacement)
|
39
|
+
prompt.say("Added #{pastel.green(replacement)}")
|
42
40
|
end
|
43
41
|
|
44
|
-
execute
|
42
|
+
execute unless prompt.no?('Keep editing?')
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -9,37 +9,35 @@ require_relative '../api/jira_api/requests/get_issue'
|
|
9
9
|
module TempestTime
|
10
10
|
module Commands
|
11
11
|
class Track < TempestTime::Command
|
12
|
-
|
13
|
-
|
14
|
-
def initialize(time, tickets, options)
|
12
|
+
def initialize(time, issues, options)
|
15
13
|
@time = time
|
16
|
-
@
|
14
|
+
@issues = issues
|
17
15
|
@options = options
|
18
16
|
end
|
19
17
|
|
20
18
|
def execute(input: $stdin, output: $stdout)
|
21
|
-
time = @options[:split] ? parsed_time(@time) / @
|
22
|
-
|
19
|
+
time = @options[:split] ? parsed_time(@time) / @issues.count : parsed_time(@time)
|
20
|
+
issues = @issues.any? ? @issues.map(&:upcase) : [automatic_issue]
|
23
21
|
|
24
22
|
unless @options[:autoconfirm]
|
25
23
|
prompt_message = "Track #{formatted_time(time)}, "\
|
26
24
|
"#{billability(@options)}, "\
|
27
|
-
"to #{
|
25
|
+
"to #{issues.join(', ')}?"
|
28
26
|
abort unless prompt.yes?(prompt_message, convert: :bool)
|
29
27
|
end
|
30
28
|
|
31
|
-
|
32
|
-
track_time(time, @options.merge(
|
29
|
+
issues.each do |issue|
|
30
|
+
track_time(time, @options.merge(issue: issue))
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
36
34
|
private
|
37
35
|
|
38
36
|
def track_time(time, options)
|
39
|
-
message = "Tracking #{formatted_time(time)} to #{options['
|
37
|
+
message = "Tracking #{formatted_time(time)} to #{options['issue']}..."
|
40
38
|
with_success_fail_spinner(message) do
|
41
39
|
options['remaining'] = if options['remaining'].nil?
|
42
|
-
remaining_estimate(options['
|
40
|
+
remaining_estimate(options['issue'], time)
|
43
41
|
else
|
44
42
|
parsed_time(options['remaining'])
|
45
43
|
end
|
@@ -47,23 +45,17 @@ module TempestTime
|
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
50
|
-
def remaining_estimate(
|
51
|
-
request = JiraAPI::Requests::GetIssue.new(
|
48
|
+
def remaining_estimate(issue, time)
|
49
|
+
request = JiraAPI::Requests::GetIssue.new(issue)
|
52
50
|
request.send_request
|
53
51
|
if request.response.failure?
|
54
|
-
abort("There was an issue getting this Jira
|
55
|
-
'Please check the
|
52
|
+
abort("There was an issue getting this Jira issue.\n"\
|
53
|
+
'Please check the issue number and your credentials.')
|
56
54
|
end
|
57
55
|
remaining = request.response.issue.remaining_estimate || 0
|
58
56
|
remaining > time ? remaining - time : 0
|
59
57
|
end
|
60
58
|
|
61
|
-
def automatic_ticket
|
62
|
-
ticket = /[A-Z]+-\d+/.match(Git.open(Dir.pwd).current_branch)
|
63
|
-
abort('Ticket not found for this branch. Please specify.') unless ticket
|
64
|
-
ticket.to_s
|
65
|
-
end
|
66
|
-
|
67
59
|
def billability(options)
|
68
60
|
options['billable'] ? 'billed' : 'non-billed'
|
69
61
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'git'
|
2
|
+
|
3
|
+
module TempestTime
|
4
|
+
module Helpers
|
5
|
+
module GitHelper
|
6
|
+
def automatic_issue
|
7
|
+
issue = /[A-Z]+-\d+/.match(Git.open(Dir.pwd).current_branch)
|
8
|
+
abort('Issue not found for this branch. Please specify.') unless issue
|
9
|
+
issue.to_s.upcase
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/tempest_time/setting.rb
CHANGED
@@ -1,47 +1,50 @@
|
|
1
|
-
require '
|
1
|
+
require 'tty-config'
|
2
2
|
|
3
3
|
module TempestTime
|
4
4
|
class Setting
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@config = TTY::Config.new
|
9
|
+
config.extname = '.yml'
|
10
|
+
config.append_path(Dir.home + '/.tempest')
|
11
|
+
end
|
12
|
+
|
13
|
+
def keys
|
14
|
+
read_config { config.to_h.keys }
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(key)
|
18
|
+
read_config { config.fetch(key) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(key)
|
22
|
+
write_config { config.delete(key) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def set(key, value)
|
26
|
+
write_config { config.set(key, value: value) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove(key, value)
|
30
|
+
write_config { config.remove(value, from: key) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def append(key, value)
|
34
|
+
write_config { config.append(value, to: key) }
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def read_config
|
40
|
+
config.read
|
41
|
+
yield
|
42
|
+
end
|
43
|
+
|
44
|
+
def write_config
|
45
|
+
config.read
|
46
|
+
yield
|
47
|
+
config.write(force: true)
|
45
48
|
end
|
46
49
|
end
|
47
|
-
end
|
50
|
+
end
|
@@ -3,16 +3,9 @@ require_relative '../setting'
|
|
3
3
|
module TempestTime
|
4
4
|
module Settings
|
5
5
|
class Authorization < TempestTime::Setting
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def file_name
|
10
|
-
'auth.yml'
|
11
|
-
end
|
12
|
-
|
13
|
-
def file_path
|
14
|
-
[directory_path, file_name].join('/')
|
15
|
-
end
|
6
|
+
def initialize
|
7
|
+
super
|
8
|
+
config.filename = 'auth'
|
16
9
|
end
|
17
10
|
end
|
18
11
|
end
|
@@ -3,16 +3,15 @@ require_relative '../setting'
|
|
3
3
|
module TempestTime
|
4
4
|
module Settings
|
5
5
|
class Teams < TempestTime::Setting
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
def initialize
|
7
|
+
super
|
8
|
+
config.filename = 'teams'
|
9
|
+
end
|
10
10
|
|
11
|
-
|
11
|
+
alias names keys
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
13
|
+
def members(team)
|
14
|
+
config.fetch(team)&.sort
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
data/lib/tempest_time/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module TempestTime
|
2
|
-
VERSION = '0.6.
|
3
|
-
end
|
2
|
+
VERSION = '0.6.1'.freeze
|
3
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tempest_time
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Devan Hurst
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-02-
|
11
|
+
date: 2019-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -455,7 +455,8 @@ files:
|
|
455
455
|
- lib/tempest_time/commands/config/setup.rb
|
456
456
|
- lib/tempest_time/commands/delete.rb
|
457
457
|
- lib/tempest_time/commands/issue.rb
|
458
|
-
- lib/tempest_time/commands/
|
458
|
+
- lib/tempest_time/commands/issue/list.rb
|
459
|
+
- lib/tempest_time/commands/issue/open.rb
|
459
460
|
- lib/tempest_time/commands/list.rb
|
460
461
|
- lib/tempest_time/commands/report.rb
|
461
462
|
- lib/tempest_time/commands/submit.rb
|
@@ -465,9 +466,11 @@ files:
|
|
465
466
|
- lib/tempest_time/commands/teams/edit.rb
|
466
467
|
- lib/tempest_time/commands/track.rb
|
467
468
|
- lib/tempest_time/helpers/formatting_helper.rb
|
469
|
+
- lib/tempest_time/helpers/git_helper.rb
|
468
470
|
- lib/tempest_time/helpers/time_helper.rb
|
469
471
|
- lib/tempest_time/models/report.rb
|
470
472
|
- lib/tempest_time/setting.rb
|
473
|
+
- lib/tempest_time/settings/app.rb
|
471
474
|
- lib/tempest_time/settings/authorization.rb
|
472
475
|
- lib/tempest_time/settings/teams.rb
|
473
476
|
- lib/tempest_time/templates/config/.gitkeep
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../command'
|
4
|
-
require_relative '../api/jira_api/requests/get_user_issues'
|
5
|
-
require_relative './issue'
|
6
|
-
|
7
|
-
module TempestTime
|
8
|
-
module Commands
|
9
|
-
class Issues < TempestTime::Command
|
10
|
-
def initialize(user, options)
|
11
|
-
@user = user
|
12
|
-
@options = options
|
13
|
-
end
|
14
|
-
|
15
|
-
def execute(input: $stdin, output: $stdout)
|
16
|
-
request = JiraAPI::Requests::GetUserIssues.new(@user)
|
17
|
-
message = "Getting issues for #{request.requested_user}"
|
18
|
-
response = with_spinner(message) do |spinner|
|
19
|
-
request.send_request.tap { spinner.stop }
|
20
|
-
end
|
21
|
-
puts format_output(response.issues)
|
22
|
-
browser_prompt(response.issues)
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def browser_prompt(issues)
|
28
|
-
abort if prompt.no?('Open an issue in your browser?')
|
29
|
-
issue = prompt.select(
|
30
|
-
'Select an issue to open in browser, or press ^C to quit.',
|
31
|
-
issues.map(&:key),
|
32
|
-
per_page: 5
|
33
|
-
)
|
34
|
-
Issue.new(issue).execute
|
35
|
-
end
|
36
|
-
|
37
|
-
def format_output(issues)
|
38
|
-
table.new(
|
39
|
-
%w[Status Issue Summary],
|
40
|
-
issues.map { |issue| row(issue) }
|
41
|
-
).render(:ascii, padding: [0, 1], column_widths: [15, 10, 30])
|
42
|
-
end
|
43
|
-
|
44
|
-
def row(issue)
|
45
|
-
[issue.status, issue.key, issue.summary]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|