gitloggl 0.1.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -1
- data/bin/console +6 -0
- data/gitloggl.gemspec +1 -0
- data/lib/gitloggl.rb +5 -3
- data/lib/gitloggl/command.rb +6 -2
- data/lib/gitloggl/commands/main.rb +3 -2
- data/lib/gitloggl/commands/manage_integration.rb +76 -0
- data/lib/gitloggl/commands/sync.rb +51 -30
- data/lib/gitloggl/commands/update.rb +49 -0
- data/lib/gitloggl/const.rb +10 -4
- data/lib/gitloggl/gitlab/cli.rb +1 -10
- data/lib/gitloggl/gitlab/issue.rb +2 -2
- data/lib/gitloggl/toggle/cli.rb +17 -24
- data/lib/gitloggl/version.rb +3 -1
- metadata +18 -5
- data/lib/gitloggl/commands/gitlab_cfg.rb +0 -50
- data/lib/gitloggl/commands/toggl_cfg.rb +0 -53
- data/lib/gitloggl/gitlab/stack/group_agg.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80535fcd6dd3199ecf83bce88b0583076823114532ca19671bf65c405eb83856
|
4
|
+
data.tar.gz: 22628ad4f9a099d2fb138eff26d31ce7104e3125a0cc1f18e5029bca5b43ca44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35d4115c1a5b2bd5e6ac1c1d62f1b8c8debc1d5be6304af027e2597c26c5edf434d7787483a5f78c75cb941de3d68cbd31b481b7f2cd5de7180f314cdc66f091
|
7
|
+
data.tar.gz: 8676f3ab7f73bb51dc318b5e51995b2777735313b17ede0ff724a9994350bdc2360099aea6c4e3f9136c0769f34834625d9d7657abd8774fe647081da267ff17
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
gitloggl (0.
|
4
|
+
gitloggl (0.2)
|
5
5
|
activesupport
|
6
6
|
chronic_duration
|
7
7
|
faraday
|
@@ -15,6 +15,7 @@ PATH
|
|
15
15
|
tty-config
|
16
16
|
tty-progressbar
|
17
17
|
tty-prompt
|
18
|
+
tty-spinner
|
18
19
|
tty-table
|
19
20
|
typhoeus
|
20
21
|
|
@@ -98,6 +99,8 @@ GEM
|
|
98
99
|
tty-screen (~> 0.6.4)
|
99
100
|
wisper (~> 2.0.0)
|
100
101
|
tty-screen (0.6.5)
|
102
|
+
tty-spinner (0.9.0)
|
103
|
+
tty-cursor (~> 0.6.0)
|
101
104
|
tty-table (0.10.0)
|
102
105
|
equatable (~> 0.5.0)
|
103
106
|
necromancer (~> 0.4.0)
|
data/bin/console
CHANGED
data/gitloggl.gemspec
CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_dependency 'tty-progressbar'
|
30
30
|
spec.add_dependency 'tty-prompt'
|
31
31
|
spec.add_dependency 'tty-table'
|
32
|
+
spec.add_dependency 'tty-spinner'
|
32
33
|
spec.add_dependency 'pastel'
|
33
34
|
spec.add_dependency 'thor'
|
34
35
|
spec.add_dependency 'activesupport'
|
data/lib/gitloggl.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'tty-table'
|
2
2
|
require 'tty-progressbar'
|
3
|
+
require 'tty-spinner'
|
4
|
+
require 'tty-command'
|
3
5
|
require 'ostruct'
|
4
6
|
require 'faraday'
|
5
7
|
require 'faraday_middleware'
|
@@ -15,6 +17,7 @@ require 'active_support/core_ext/module/delegation'
|
|
15
17
|
require 'active_support/duration'
|
16
18
|
require 'active_support/core_ext/date'
|
17
19
|
require 'active_support/core_ext/numeric/time'
|
20
|
+
require 'active_support/core_ext/array/grouping'
|
18
21
|
require 'gitloggl/const'
|
19
22
|
require 'gitloggl/version'
|
20
23
|
require 'gitloggl/cli'
|
@@ -27,9 +30,9 @@ module Gitloggl
|
|
27
30
|
extend ActiveSupport::Autoload
|
28
31
|
|
29
32
|
autoload :Main
|
30
|
-
autoload :
|
31
|
-
autoload :GitlabCfg
|
33
|
+
autoload :ManageIntegration
|
32
34
|
autoload :Sync
|
35
|
+
autoload :Update
|
33
36
|
end
|
34
37
|
|
35
38
|
module Toggle
|
@@ -49,7 +52,6 @@ module Gitloggl
|
|
49
52
|
|
50
53
|
autoload :Abstract
|
51
54
|
autoload :Filter
|
52
|
-
autoload :GroupAgg
|
53
55
|
autoload :DetectProject
|
54
56
|
autoload :LoadNotes
|
55
57
|
autoload :UpdateSpent
|
data/lib/gitloggl/command.rb
CHANGED
@@ -24,10 +24,10 @@ module Gitloggl
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def capture_back
|
27
|
-
-> { self.class.new.execute }
|
27
|
+
-> { self.class.new(options).execute }
|
28
28
|
end
|
29
29
|
|
30
|
-
def menu_back(menu)
|
30
|
+
def menu_back(menu, back: back)
|
31
31
|
return unless back?
|
32
32
|
|
33
33
|
menu.choice 'Back', back
|
@@ -148,6 +148,10 @@ module Gitloggl
|
|
148
148
|
TTY::Which.exist?(*args)
|
149
149
|
end
|
150
150
|
|
151
|
+
def render_table(table)
|
152
|
+
table.render :unicode, padding: 1
|
153
|
+
end
|
154
|
+
|
151
155
|
def pastel(opts = {})
|
152
156
|
Pastel.new(opts)
|
153
157
|
end
|
@@ -5,9 +5,10 @@ module Gitloggl
|
|
5
5
|
class Main < Gitloggl::Command
|
6
6
|
def execute(*)
|
7
7
|
action = prompt.select('') do |menu|
|
8
|
+
menu.enum ')'
|
8
9
|
menu.choice 'SYNC', Sync
|
9
|
-
menu.choice '
|
10
|
-
menu.choice '
|
10
|
+
menu.choice 'Manage Integrations', ManageIntegration
|
11
|
+
menu.choice 'Check For Updates', Update
|
11
12
|
end
|
12
13
|
|
13
14
|
action.new(options) do |a|
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitloggl
|
4
|
+
module Commands
|
5
|
+
class ManageIntegration < Gitloggl::Command
|
6
|
+
def execute
|
7
|
+
puts render_table(table)
|
8
|
+
|
9
|
+
prompt.select('Manage toggle -> gitlab integrations') do |menu|
|
10
|
+
menu.enum ')'
|
11
|
+
menu_back(menu)
|
12
|
+
menu.choice 'Add', -> { add }
|
13
|
+
menu.choice 'Remove', -> { remove }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def remove
|
20
|
+
index = prompt.select('Select integration to remove') do |menu|
|
21
|
+
menu.enum ')'
|
22
|
+
|
23
|
+
integrations.each_with_index do |row, index|
|
24
|
+
menu.choice row[Const::NAME], index
|
25
|
+
end
|
26
|
+
|
27
|
+
menu_back(menu, back: -1)
|
28
|
+
end
|
29
|
+
|
30
|
+
return execute if index.negative?
|
31
|
+
|
32
|
+
integrations.delete_at(index)
|
33
|
+
config.set(Const::INTEGRATIONS, value: integrations)
|
34
|
+
config.write(force: true)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add
|
38
|
+
result = prompt.collect do
|
39
|
+
key(Const::NAME).ask('Name?', default: 'Default')
|
40
|
+
key(Const::GITLAB_URL).ask('Gitlab URL?', default: 'https://gitlab.com')
|
41
|
+
key(Const::GITLAB_TOKEN).ask('Gitlab Token?', required: true)
|
42
|
+
key(Const::TOGGL_WORKSPACE_ID).ask('Toggl WorkspaceID?', required: true)
|
43
|
+
key(Const::TOGGL_PROJECT_ID).ask('Toggl ProjectID? (not required)')
|
44
|
+
key(Const::TOGGL_TOKEN).ask('Toggl Token?', requred: true)
|
45
|
+
end
|
46
|
+
|
47
|
+
config.append(result, to: Const::INTEGRATIONS)
|
48
|
+
config.write(force: true)
|
49
|
+
end
|
50
|
+
|
51
|
+
def table
|
52
|
+
table = TTY::Table.new header: ['№', 'Name', 'Gitlab URL', 'Gitlab Token', 'Toggl WorkspaceID', 'Toggle ProjectID', 'Toggl Token']
|
53
|
+
|
54
|
+
integrations(default: [{}]).each_with_index do |row, index|
|
55
|
+
table << [
|
56
|
+
index.next,
|
57
|
+
*row.values_at(
|
58
|
+
Const::NAME,
|
59
|
+
Const::GITLAB_URL,
|
60
|
+
Const::GITLAB_TOKEN,
|
61
|
+
Const::TOGGL_WORKSPACE_ID,
|
62
|
+
Const::TOGGL_PROJECT_ID,
|
63
|
+
Const::TOGGL_TOKEN
|
64
|
+
)
|
65
|
+
]
|
66
|
+
end
|
67
|
+
|
68
|
+
table
|
69
|
+
end
|
70
|
+
|
71
|
+
def integrations(default: [])
|
72
|
+
config.fetch(Const::INTEGRATIONS, default: default)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -3,10 +3,16 @@
|
|
3
3
|
module Gitloggl
|
4
4
|
module Commands
|
5
5
|
class Sync < Gitloggl::Command
|
6
|
-
attr_accessor :date_from, :date_to
|
6
|
+
attr_accessor :integration, :date_from, :date_to
|
7
7
|
attr_accessor :toggl_bar, :gitlab_bar
|
8
8
|
|
9
9
|
def execute
|
10
|
+
if integrations.empty?
|
11
|
+
puts pastel.yellow('Please add integration first')
|
12
|
+
return back.call
|
13
|
+
end
|
14
|
+
|
15
|
+
self.integration = select_integration
|
10
16
|
self.date_from, self.date_to = select_dates
|
11
17
|
|
12
18
|
setup_toggl_hooks
|
@@ -22,34 +28,33 @@ module Gitloggl
|
|
22
28
|
def print_tables
|
23
29
|
if updated.any?
|
24
30
|
puts pastel.green('Updated tracks')
|
25
|
-
puts(updated_table)
|
31
|
+
puts render_table(updated_table)
|
26
32
|
end
|
27
33
|
|
28
34
|
if rejected.any?
|
29
35
|
puts pastel.yellow('Rejected tracks')
|
30
|
-
puts(rejected_table)
|
36
|
+
puts render_table(rejected_table)
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
34
40
|
def setup_toggl_hooks
|
35
|
-
toggl.
|
36
|
-
self.toggl_bar = bars.register("toggl [:bar] :percent", total:
|
37
|
-
self.gitlab_bar = bars.register("gitlab [:bar] :percent", total:
|
41
|
+
toggl.on_done do |data|
|
42
|
+
self.toggl_bar = bars.register("toggl [:bar] :percent", total: data.length)
|
43
|
+
self.gitlab_bar = bars.register("gitlab [:bar] :percent", total: data.length)
|
44
|
+
toggl_bar.advance(data.length)
|
38
45
|
end
|
39
46
|
|
40
|
-
toggl.
|
41
|
-
|
42
|
-
|
47
|
+
toggl.on_done do |data|
|
48
|
+
data.in_groups_of(10, false) do |group|
|
49
|
+
group.map! do |result|
|
50
|
+
Gitlab::Issue.new(
|
51
|
+
spent_ms: Integer(result.spent_ms),
|
52
|
+
title: result.title
|
53
|
+
)
|
54
|
+
end
|
43
55
|
|
44
|
-
|
45
|
-
issues = response.body.fetch('data').map do |row|
|
46
|
-
Gitlab::Issue.new(
|
47
|
-
spent_ms: Integer(row.fetch('dur')),
|
48
|
-
description: row.fetch('description')
|
49
|
-
)
|
56
|
+
gitlab.batch(group)
|
50
57
|
end
|
51
|
-
|
52
|
-
gitlab.batch(issues)
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
@@ -58,10 +63,6 @@ module Gitloggl
|
|
58
63
|
gitlab_bar.advance
|
59
64
|
end
|
60
65
|
|
61
|
-
gitlab.on_skipped do
|
62
|
-
gitlab_bar.advance
|
63
|
-
end
|
64
|
-
|
65
66
|
gitlab.on_rejected do |issue, reason|
|
66
67
|
rejected.push([issue, reason])
|
67
68
|
end
|
@@ -82,21 +83,25 @@ module Gitloggl
|
|
82
83
|
def rejected_table
|
83
84
|
table = TTY::Table.new header: %w[Track Reason]
|
84
85
|
|
85
|
-
rejected.uniq { |(i)| i.
|
86
|
-
table << [issue.
|
86
|
+
rejected.uniq { |(i, _)| i.title }.each do |(issue, reason)|
|
87
|
+
table << [issue.title, reason]
|
87
88
|
end
|
88
89
|
|
89
|
-
table
|
90
|
+
table
|
90
91
|
end
|
91
92
|
|
92
93
|
def updated_table
|
93
94
|
table = TTY::Table.new header: %w[Track Diff]
|
94
95
|
|
96
|
+
updated.sort_by! do |(_, diff)|
|
97
|
+
-diff
|
98
|
+
end
|
99
|
+
|
95
100
|
updated.each do |(issue, diff)|
|
96
|
-
table << [issue.
|
101
|
+
table << [issue.title, %{added +#{ChronicDuration.output(diff, keep_zero: true)}}]
|
97
102
|
end
|
98
103
|
|
99
|
-
table
|
104
|
+
table
|
100
105
|
end
|
101
106
|
|
102
107
|
def bars
|
@@ -106,8 +111,9 @@ module Gitloggl
|
|
106
111
|
def toggl
|
107
112
|
@toggl ||= Toggle::Cli.new do |c|
|
108
113
|
c.verbose = verbose?
|
109
|
-
c.
|
110
|
-
c.
|
114
|
+
c.project_id = integration.fetch(Const::TOGGL_PROJECT_ID)
|
115
|
+
c.workspace_id = integration.fetch(Const::TOGGL_WORKSPACE_ID)
|
116
|
+
c.token = integration.fetch(Const::TOGGL_TOKEN)
|
111
117
|
c.date_from = date_from
|
112
118
|
c.date_to = date_to
|
113
119
|
end
|
@@ -116,18 +122,33 @@ module Gitloggl
|
|
116
122
|
def gitlab
|
117
123
|
@gitlab ||= Gitlab::Cli.new do |c|
|
118
124
|
c.verbose = verbose?
|
119
|
-
c.url =
|
120
|
-
c.token =
|
125
|
+
c.url = integration.fetch(Const::GITLAB_URL)
|
126
|
+
c.token = integration.fetch(Const::GITLAB_TOKEN)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def select_integration
|
131
|
+
prompt.select('Select integration') do |menu|
|
132
|
+
menu.enum ')'
|
133
|
+
|
134
|
+
integrations.each do |row|
|
135
|
+
menu.choice row[Const::NAME], row
|
136
|
+
end
|
121
137
|
end
|
122
138
|
end
|
123
139
|
|
124
140
|
def select_dates
|
125
141
|
prompt.select('Select period for sync. Tracks will be added to gitlab if diff will be detected') do |menu|
|
142
|
+
menu.enum ')'
|
126
143
|
menu.choice 'Past 3 weeks', [3.weeks.ago.to_date, Date.current]
|
127
144
|
menu.choice 'Past 2 weeks', [2.weeks.ago.to_date, Date.current]
|
128
145
|
menu.choice 'Past 7 days', [7.days.ago.to_date, Date.current]
|
129
146
|
end
|
130
147
|
end
|
148
|
+
|
149
|
+
def integrations
|
150
|
+
config.fetch(Const::INTEGRATIONS, default: [])
|
151
|
+
end
|
131
152
|
end
|
132
153
|
end
|
133
154
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitloggl
|
4
|
+
module Commands
|
5
|
+
class Update < Gitloggl::Command
|
6
|
+
RUBYGEMS_URL = 'https://rubygems.org/api/v1/gems/gitloggl.json'
|
7
|
+
|
8
|
+
def execute
|
9
|
+
spinner = TTY::Spinner.new("[:spinner] Loading ...", format: :pulse_2)
|
10
|
+
outdated = outdated?(parse_version(VERSION), parse_version(remote_version))
|
11
|
+
spinner.stop
|
12
|
+
|
13
|
+
unless outdated
|
14
|
+
puts pastel.yellow('No Updates Available')
|
15
|
+
return back.call
|
16
|
+
end
|
17
|
+
|
18
|
+
select_update
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def select_update
|
24
|
+
yes = prompt.yes?("#{remote_version} version available, update?")
|
25
|
+
|
26
|
+
return back.call unless yes
|
27
|
+
|
28
|
+
cmd = TTY::Command.new
|
29
|
+
cmd.run('gem update gitloggl')
|
30
|
+
end
|
31
|
+
|
32
|
+
def outdated?(current, remote)
|
33
|
+
remote.each_with_index do |num, ix|
|
34
|
+
return true if num > current[ix].to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def remote_version
|
41
|
+
@remote_version ||= Connection.new(RUBYGEMS_URL).get.body.fetch('version')
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_version(string)
|
45
|
+
string.split('.').map(&:to_i)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/gitloggl/const.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Gitloggl
|
2
4
|
module Const
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
INTEGRATIONS = :integrations
|
6
|
+
|
7
|
+
NAME = 'name'
|
8
|
+
GITLAB_URL = 'gitlab_url'
|
9
|
+
GITLAB_TOKEN = 'gitlab_token'
|
10
|
+
TOGGL_WORKSPACE_ID = 'toggl_workspace_id'
|
11
|
+
TOGGL_PROJECT_ID = 'toggl_project_id'
|
12
|
+
TOGGL_TOKEN = 'toggl_token'
|
7
13
|
end
|
8
14
|
end
|
data/lib/gitloggl/gitlab/cli.rb
CHANGED
@@ -7,7 +7,6 @@ module Gitloggl
|
|
7
7
|
define_hook :on_rejected, scope: ->(*) { nil }
|
8
8
|
define_hook :on_updated, scope: ->(*) { nil }
|
9
9
|
define_hook :on_completed, scope: ->(*) { nil }
|
10
|
-
define_hook :on_skipped, scope: ->(*) { nil }
|
11
10
|
|
12
11
|
attr_accessor :token, :url, :verbose
|
13
12
|
|
@@ -26,10 +25,6 @@ module Gitloggl
|
|
26
25
|
false
|
27
26
|
end
|
28
27
|
|
29
|
-
b.use Stack::GroupAgg, callback: ->(issues) do
|
30
|
-
issues.each { skipped }
|
31
|
-
end
|
32
|
-
|
33
28
|
b.use Stack::DetectProject
|
34
29
|
|
35
30
|
b.use Stack::Filter, where: -> (issue) do
|
@@ -43,7 +38,7 @@ module Gitloggl
|
|
43
38
|
b.use Stack::LoadNotes
|
44
39
|
|
45
40
|
b.use Stack::UpdateSpent, callback: ->(issue, diff_sec) do
|
46
|
-
updated(issue,
|
41
|
+
updated(issue, diff_sec)
|
47
42
|
end
|
48
43
|
end
|
49
44
|
|
@@ -62,10 +57,6 @@ module Gitloggl
|
|
62
57
|
run_hook(:on_updated, issue, diff)
|
63
58
|
end
|
64
59
|
|
65
|
-
def skipped
|
66
|
-
run_hook(:on_skipped)
|
67
|
-
end
|
68
|
-
|
69
60
|
def connection
|
70
61
|
@connection ||= Connection.new(url, headers: { 'PRIVATE-TOKEN' => token }, verbose: verbose).tap do |c|
|
71
62
|
c.transport.basic_auth(token, 'api_token')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Gitloggl
|
2
2
|
module Gitlab
|
3
|
-
class Issue < Struct.new(:
|
3
|
+
class Issue < Struct.new(:title, :project_id, :spent_ms, keyword_init: true)
|
4
4
|
ISSUE_PATH_RE = /([[[:alnum:]]_-]*)#(\d+)/ # "poslogic-partner#471"
|
5
5
|
|
6
6
|
attr_accessor :notes
|
@@ -10,7 +10,7 @@ module Gitloggl
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def path
|
13
|
-
return nil unless
|
13
|
+
return nil unless title =~ ISSUE_PATH_RE
|
14
14
|
return nil unless $1.present? && $2.present?
|
15
15
|
|
16
16
|
@path ||= OpenStruct.new(project_path: $1, issue_id: $2)
|
data/lib/gitloggl/toggle/cli.rb
CHANGED
@@ -4,54 +4,47 @@ module Gitloggl
|
|
4
4
|
include Hooks
|
5
5
|
include Hooks::InstanceHooks
|
6
6
|
|
7
|
-
define_hook :
|
8
|
-
define_hook :on_each_page, scope: ->(*) { nil }
|
7
|
+
define_hook :on_done, scope: ->(*) { nil }
|
9
8
|
|
10
|
-
attr_accessor :token, :workspace_id, :date_from, :date_to, :verbose
|
9
|
+
attr_accessor :token, :workspace_id, :project_id, :date_from, :date_to, :verbose
|
11
10
|
|
12
11
|
def initialize(params = {})
|
13
12
|
params.each { |k, v| public_send("#{k}=", v) }
|
14
13
|
yield(self) if block_given?
|
15
14
|
end
|
16
15
|
|
17
|
-
def run
|
18
|
-
|
16
|
+
def run
|
17
|
+
data = request.fetch('data').flat_map { |row| row.fetch('items') }
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
per_page: per_page,
|
27
|
-
total_pages: total_pages,
|
28
|
-
page: page,
|
29
|
-
body: body
|
30
|
-
)
|
31
|
-
|
32
|
-
run_hook(:on_first_page, result) if page == 1
|
33
|
-
run_hook(:on_each_page, result)
|
19
|
+
data.map! do |row|
|
20
|
+
OpenStruct.new(
|
21
|
+
title: row.fetch('title').fetch('time_entry'),
|
22
|
+
spent_ms: row.fetch('time')
|
23
|
+
)
|
24
|
+
end
|
34
25
|
|
35
|
-
|
26
|
+
run_hook(:on_done, data)
|
36
27
|
end
|
37
28
|
|
38
29
|
private
|
39
30
|
|
40
31
|
# @return [JSON]
|
41
|
-
def request
|
42
|
-
response = connection.get('/reports/api/v2/
|
32
|
+
def request
|
33
|
+
response = connection.get('/reports/api/v2/summary', {
|
43
34
|
workspace_id: workspace_id,
|
35
|
+
project_ids: project_id,
|
44
36
|
since: date_from,
|
45
37
|
until: date_to,
|
38
|
+
grouping: 'projects',
|
39
|
+
subgrouping: 'time_entries',
|
46
40
|
user_agent: Connection::USER_AGENT,
|
47
|
-
page: page
|
48
41
|
})
|
49
42
|
|
50
43
|
response.body
|
51
44
|
end
|
52
45
|
|
53
46
|
def connection
|
54
|
-
@connection ||= Connection.new('https://toggl.com
|
47
|
+
@connection ||= Connection.new('https://toggl.com', verbose: verbose).tap do |c|
|
55
48
|
c.transport.basic_auth(token, 'api_token')
|
56
49
|
end
|
57
50
|
end
|
data/lib/gitloggl/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitloggl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shylau Aloaksandr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-02-
|
11
|
+
date: 2019-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-color
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: tty-spinner
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: pastel
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -298,10 +312,10 @@ files:
|
|
298
312
|
- lib/gitloggl.rb
|
299
313
|
- lib/gitloggl/cli.rb
|
300
314
|
- lib/gitloggl/command.rb
|
301
|
-
- lib/gitloggl/commands/gitlab_cfg.rb
|
302
315
|
- lib/gitloggl/commands/main.rb
|
316
|
+
- lib/gitloggl/commands/manage_integration.rb
|
303
317
|
- lib/gitloggl/commands/sync.rb
|
304
|
-
- lib/gitloggl/commands/
|
318
|
+
- lib/gitloggl/commands/update.rb
|
305
319
|
- lib/gitloggl/connection.rb
|
306
320
|
- lib/gitloggl/const.rb
|
307
321
|
- lib/gitloggl/gitlab/cli.rb
|
@@ -309,7 +323,6 @@ files:
|
|
309
323
|
- lib/gitloggl/gitlab/stack/abstract.rb
|
310
324
|
- lib/gitloggl/gitlab/stack/detect_project.rb
|
311
325
|
- lib/gitloggl/gitlab/stack/filter.rb
|
312
|
-
- lib/gitloggl/gitlab/stack/group_agg.rb
|
313
326
|
- lib/gitloggl/gitlab/stack/load_notes.rb
|
314
327
|
- lib/gitloggl/gitlab/stack/update_spent.rb
|
315
328
|
- lib/gitloggl/templates/.gitkeep
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitloggl
|
4
|
-
module Commands
|
5
|
-
class GitlabCfg < Gitloggl::Command
|
6
|
-
def execute(*)
|
7
|
-
render_config_table
|
8
|
-
|
9
|
-
prompt.select('') do |menu|
|
10
|
-
menu.choice 'Back', back if back?
|
11
|
-
menu.choice 'Add site', -> { add_site }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def add_site
|
18
|
-
domain = ask_domain
|
19
|
-
token = ask_token
|
20
|
-
|
21
|
-
return unless prompt.yes?("Change settings? Domain: #{pastel.green(domain)}, token: #{pastel.green(token)}")
|
22
|
-
|
23
|
-
config.set(Const::GITLAB_URL, value: domain)
|
24
|
-
config.set(Const::GITLAB_TOKEN, value: token)
|
25
|
-
|
26
|
-
config.write(force: true)
|
27
|
-
end
|
28
|
-
|
29
|
-
def ask_domain
|
30
|
-
prompt.ask('Enter gitlab domain:', default: 'https://gitlab.com') do |q|
|
31
|
-
q.required true
|
32
|
-
q.validate /\A.+\Z/
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def ask_token
|
37
|
-
prompt.ask('Enter access token') do |q|
|
38
|
-
q.required true
|
39
|
-
q.validate /\A.+\Z/
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def render_config_table
|
44
|
-
table = TTY::Table.new header: %w[Domain Token]
|
45
|
-
table << [config.fetch(Const::GITLAB_URL), config.fetch(Const::GITLAB_TOKEN)]
|
46
|
-
puts table.render :unicode, padding: 1
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitloggl
|
4
|
-
module Commands
|
5
|
-
class TogglCfg < Gitloggl::Command
|
6
|
-
def execute(*)
|
7
|
-
render_config_config
|
8
|
-
|
9
|
-
prompt.select('') do |menu|
|
10
|
-
menu.enum ')'
|
11
|
-
menu_back(menu)
|
12
|
-
menu.choice 'Change', -> { change }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def change
|
19
|
-
workspace_id = ask_workspace_id
|
20
|
-
token = ask_token
|
21
|
-
|
22
|
-
return unless prompt.yes? <<~ECHO
|
23
|
-
Change settings? WorkspaceID: #{pastel.green(workspace_id)}, token: #{pastel.green(token)}
|
24
|
-
ECHO
|
25
|
-
|
26
|
-
config.set(Const::TOGGL_WORKSPACE_ID, value: workspace_id)
|
27
|
-
config.set(Const::TOGGL_TOKEN, value: token)
|
28
|
-
|
29
|
-
config.write(force: true)
|
30
|
-
end
|
31
|
-
|
32
|
-
def ask_workspace_id
|
33
|
-
prompt.ask('Enter workspaceID:') do |q|
|
34
|
-
q.required true
|
35
|
-
q.validate /\A.+\Z/
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def ask_token
|
40
|
-
prompt.ask('Enter token:') do |q|
|
41
|
-
q.required true
|
42
|
-
q.validate /\A.+\Z/
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def render_config_config
|
47
|
-
table = TTY::Table.new header: %w[WorkspaceID Token]
|
48
|
-
table << [config.fetch(Const::TOGGL_WORKSPACE_ID), config.fetch(Const::TOGGL_TOKEN)]
|
49
|
-
puts table.render :unicode, padding: 1
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitloggl
|
4
|
-
module Gitlab
|
5
|
-
module Stack
|
6
|
-
class GroupAgg < Abstract
|
7
|
-
opt :callback
|
8
|
-
|
9
|
-
def before_call
|
10
|
-
env.issues = env.issues.group_by(&:path).each_with_object([]) do |(_, group), object|
|
11
|
-
object.push(group.inject { |a, b| a + b })
|
12
|
-
|
13
|
-
next unless group.many?
|
14
|
-
|
15
|
-
callback!.call(group[1..-1])
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|