sfctl 1.0.0 → 1.0.4

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: 987345c89cefd795ef0e0caf100079fdae0d21928e5dd797216132aed206834b
4
- data.tar.gz: b6935e7ebbaa5af76c6d16ce666da547b32262c3dbe688a7e51dc5201788e4bd
3
+ metadata.gz: 50b06c3748555b51931554ecc9278f97340fc1b3f27289e147a481a598bc01db
4
+ data.tar.gz: 7d449dee4713db1d04681069a88224a7e52385e18cf1903eb4fe32b1193f1217
5
5
  SHA512:
6
- metadata.gz: ac9d36c7c89667c8cd92be1e1ef61009674ef889ba971a40108ca6ca9342e244033d239349ff66ead8fa994a827c5f3f21252bc440ffe3345298f03d47a3ef74
7
- data.tar.gz: 6e29f52a803757984dede41303d62109734a09090492d414972f908369f70596dbadaabd35fe37557b73fa1286407d17b9fdeec6faeaf8ed2d39608a9bf467a9
6
+ metadata.gz: c62e5d25d1fd9247a4b919fbf496bd7a449a41689fd4d745197390f6a44fed0de074acdb73ca0bdae6675bb9b865498fff2c78c4001ee22e871bb75e286dc135
7
+ data.tar.gz: f72dd63951c7c9522e312251f10fa3a859c26cab4a1832f22a3fcd39e6584537b59e88b0e233c6d7950986c401b3ca7db69615e8638a1f94838513278421dfbd
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  .DS_Store
13
13
  sfctl-*.gem
14
14
  /.sflink
15
+ .byebug_history
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sfctl (0.1.0)
4
+ sfctl (1.0.4)
5
5
  faraday (~> 1.0)
6
6
  pastel (~> 0.7)
7
7
  rake (~> 12.0)
@@ -23,7 +23,7 @@ PATH
23
23
  tty-progressbar (~> 0.17.0)
24
24
  tty-prompt (~> 0.21.0)
25
25
  tty-reader (~> 0.7.0)
26
- tty-screen (~> 0.7.1)
26
+ tty-screen (~> 0.8.1)
27
27
  tty-spinner (~> 0.9.3)
28
28
  tty-table (~> 0.11.0)
29
29
  tty-tree (~> 0.4.0)
@@ -34,12 +34,12 @@ GEM
34
34
  specs:
35
35
  addressable (2.7.0)
36
36
  public_suffix (>= 2.0.2, < 5.0)
37
- ast (2.4.0)
38
- byebug (11.1.1)
39
- coderay (1.1.2)
37
+ ast (2.4.1)
38
+ byebug (11.1.3)
39
+ coderay (1.1.3)
40
40
  crack (0.4.3)
41
41
  safe_yaml (~> 1.0.0)
42
- diff-lcs (1.3)
42
+ diff-lcs (1.4.4)
43
43
  docile (1.3.2)
44
44
  equatable (0.6.1)
45
45
  faraday (1.0.1)
@@ -48,15 +48,14 @@ GEM
48
48
  rspec-core (~> 3.0)
49
49
  ruby-progressbar (~> 1.4)
50
50
  hashdiff (1.0.1)
51
- jaro_winkler (1.5.4)
52
51
  kramdown (1.16.2)
53
52
  method_source (1.0.0)
54
53
  multipart-post (2.1.1)
55
54
  necromancer (0.5.1)
56
- parallel (1.19.1)
57
- parser (2.7.1.1)
58
- ast (~> 2.4.0)
59
- pastel (0.7.3)
55
+ parallel (1.19.2)
56
+ parser (2.7.1.4)
57
+ ast (~> 2.4.1)
58
+ pastel (0.7.4)
60
59
  equatable (~> 0.6)
61
60
  tty-color (~> 0.5)
62
61
  pry (0.13.1)
@@ -65,32 +64,36 @@ GEM
65
64
  pry-byebug (3.9.0)
66
65
  byebug (~> 11.0)
67
66
  pry (~> 0.13.0)
68
- public_suffix (4.0.4)
67
+ public_suffix (4.0.5)
69
68
  rainbow (3.0.0)
70
69
  rake (12.3.3)
70
+ regexp_parser (1.7.1)
71
71
  rexml (3.2.4)
72
- rouge (3.18.0)
72
+ rouge (3.21.0)
73
73
  rspec (3.9.0)
74
74
  rspec-core (~> 3.9.0)
75
75
  rspec-expectations (~> 3.9.0)
76
76
  rspec-mocks (~> 3.9.0)
77
- rspec-core (3.9.1)
78
- rspec-support (~> 3.9.1)
79
- rspec-expectations (3.9.1)
77
+ rspec-core (3.9.2)
78
+ rspec-support (~> 3.9.3)
79
+ rspec-expectations (3.9.2)
80
80
  diff-lcs (>= 1.2.0, < 2.0)
81
81
  rspec-support (~> 3.9.0)
82
82
  rspec-mocks (3.9.1)
83
83
  diff-lcs (>= 1.2.0, < 2.0)
84
84
  rspec-support (~> 3.9.0)
85
- rspec-support (3.9.2)
86
- rubocop (0.81.0)
87
- jaro_winkler (~> 1.5.1)
85
+ rspec-support (3.9.3)
86
+ rubocop (0.88.0)
88
87
  parallel (~> 1.10)
89
- parser (>= 2.7.0.1)
88
+ parser (>= 2.7.1.1)
90
89
  rainbow (>= 2.2.2, < 4.0)
90
+ regexp_parser (>= 1.7)
91
91
  rexml
92
+ rubocop-ast (>= 0.1.0, < 1.0)
92
93
  ruby-progressbar (~> 1.7)
93
94
  unicode-display_width (>= 1.4.0, < 2.0)
95
+ rubocop-ast (0.1.0)
96
+ parser (>= 2.7.0.1)
94
97
  ruby-progressbar (1.10.1)
95
98
  safe_yaml (1.0.5)
96
99
  simplecov (0.18.5)
@@ -151,7 +154,7 @@ GEM
151
154
  tty-cursor (~> 0.7)
152
155
  tty-screen (~> 0.7)
153
156
  wisper (~> 2.0.0)
154
- tty-screen (0.7.1)
157
+ tty-screen (0.8.1)
155
158
  tty-spinner (0.9.3)
156
159
  tty-cursor (~> 0.7)
157
160
  tty-table (0.11.0)
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # sfctl [![Build status](https://badge.buildkite.com/22ecc67f358163f4714383ff0fde8e847d1e3ae488fc10312f.svg)](https://buildkite.com/starfish/sf-control)
2
+ [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Falphatier-works%2Fsfctl.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Falphatier-works%2Fsfctl?ref=badge_shield)
2
3
 
3
4
  ```
4
5
  sfctl is a command line interface for the Starfish API.
@@ -270,3 +271,7 @@ Uploading to starfish.team: [IN PROGRESS|DONE]
270
271
 
271
272
  [NEXT CONNECTION]
272
273
  ```
274
+
275
+
276
+ ## License
277
+ [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Falphatier-works%2Fsfctl.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Falphatier-works%2Fsfctl?ref=badge_large)
@@ -90,7 +90,7 @@ module Sfctl
90
90
  @prompt.select('Rounding?', %w[on off])
91
91
  end
92
92
 
93
- def setup_toggl_connection!(output, assignment_obj) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
93
+ def setup_toggl_connection!(output, assignment_obj) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
94
94
  spinner = ::TTY::Spinner.new('[:spinner] Loading ...')
95
95
 
96
96
  assignment_id = assignment_obj['id']
@@ -162,7 +162,7 @@ module Sfctl
162
162
  clear_conf_and_print_success!(output)
163
163
  end
164
164
 
165
- def setup_harvest_connection!(output, assignment_obj) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
165
+ def setup_harvest_connection!(output, assignment_obj) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
166
166
  spinner = ::TTY::Spinner.new('[:spinner] Loading ...')
167
167
 
168
168
  assignment_id = assignment_obj['id']
@@ -21,7 +21,7 @@ module Sfctl
21
21
  def execute(output: $stdout)
22
22
  return if !config_present?(output) || !link_config_present?(output)
23
23
 
24
- if read_link_config['connections'].length.zero?
24
+ if connections.length.zero?
25
25
  output.puts @pastel.red('Please add a connection before continue.')
26
26
  return
27
27
  end
@@ -34,8 +34,12 @@ module Sfctl
34
34
 
35
35
  private
36
36
 
37
+ def connections
38
+ @connections ||= read_link_config.fetch('connections', [])
39
+ end
40
+
37
41
  def assignments_from_connections
38
- read_link_config['connections'].map do |con|
42
+ connections.map do |con|
39
43
  id = con[0]
40
44
  asmnt = con[1]
41
45
  {
@@ -70,12 +74,12 @@ module Sfctl
70
74
  def sync_assignments(output, list)
71
75
  list.each do |assignment|
72
76
  assignment_id = assignment['id'].to_s
73
- connection = read_link_config['connections'].select { |c| c == assignment_id }
77
+ connection = connections.select { |c| c == assignment_id }
74
78
  sync(output, assignment, connection[assignment_id])
75
79
  end
76
80
  end
77
81
 
78
- def sync(output, assignment, connection) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
82
+ def sync(output, assignment, connection) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
79
83
  output.puts "Synchronizing: #{@pastel.cyan("[#{assignment['name']} / #{assignment['service']}]")}"
80
84
 
81
85
  success, next_report = Starfish::Client.next_report(@options['starfish-host'], access_token, assignment['id'])
@@ -88,7 +92,7 @@ module Sfctl
88
92
 
89
93
  print_report_contains_data(output, next_report) && return if touchy?(next_report)
90
94
 
91
- uploading_to_starfish(output, assignment, time_entries, connection)
95
+ uploading_to_starfish(output, assignment, time_entries, connection) if time_entries.any?
92
96
  end
93
97
 
94
98
  def report_interval(record)
@@ -68,10 +68,13 @@ module Sfctl
68
68
  def self.assignment_items(time_entries, connection)
69
69
  hours_field = hours_field(connection['rounding'])
70
70
  time_entries.map do |te|
71
+ hours = te[hours_field]
72
+ time_seconds = hours * 60 * 60
71
73
  {
72
- time: te[hours_field],
74
+ time_seconds: time_seconds.round,
73
75
  date: te['spent_date'].to_s,
74
- comment: te['notes']
76
+ comment: te['notes'],
77
+ external_id: te['id'].to_s
75
78
  }
76
79
  end
77
80
  end
@@ -13,7 +13,7 @@ module Sfctl
13
13
  api_path = api == 'reports' ? REPORTS_API_PATH : DEFAULT_API_PATH
14
14
 
15
15
  headers = { 'Content-Type' => 'application/json' }
16
- Faraday.new(url: "https://#{token}:api_token@www.toggl.com/#{api_path}", headers: headers) do |builder|
16
+ Faraday.new(url: "https://#{token}:api_token@api.track.toggl.com/#{api_path}", headers: headers) do |builder|
17
17
  builder.request :retry
18
18
  builder.adapter :net_http
19
19
  end
@@ -10,9 +10,14 @@ module Sfctl
10
10
  spinner = TTY::Spinner.new("Loaded data from #{Sfctl::Command::TOGGL_PROVIDER}: [:spinner]", format: :dots)
11
11
  spinner.auto_spin
12
12
 
13
- time_entries = get_time_entries(connection, toggl_config, report_interval)
13
+ time_entries, error = get_time_entries(connection, toggl_config, report_interval)
14
14
 
15
- spinner.success(pastel.green('Done'))
15
+ if error
16
+ spinner.error
17
+ output.puts pastel.red(error)
18
+ else
19
+ spinner.success(pastel.green('Done'))
20
+ end
16
21
 
17
22
  table = TTY::Table.new %w[Date Comment Time], time_entries_table_rows(time_entries)
18
23
  output.puts
@@ -20,31 +25,51 @@ module Sfctl
20
25
  output.puts
21
26
  output.puts
22
27
 
23
- time_entries['data']
28
+ time_entries
24
29
  end
25
30
 
26
31
  def self.time_entries_table_rows(time_entries)
27
- rows = time_entries['data'].sort_by { |te| te['start'] }.map do |te|
32
+ rows = time_entries.sort_by { |te| te['start'] }.map do |te|
28
33
  [
29
34
  Date.parse(te['start']).to_s,
30
35
  te['description'],
31
36
  "#{humanize_duration(te['dur'])}h"
32
37
  ]
33
38
  end
34
- rows.push(['Total:', '', "#{humanize_duration(time_entries['total_grand'])}h"])
39
+ total_grand = time_entries.sum { |te| te['dur'] }
40
+ rows.push(['Total:', '', "#{humanize_duration(total_grand)}h"])
35
41
  rows
36
42
  end
37
43
 
38
44
  def self.get_time_entries(connection, toggl_config, report_interval)
39
- _success, data = Toggl::Client.time_entries(
40
- toggl_config['access_token'],
41
- time_entries_params(connection, report_interval)
42
- )
45
+ entries_list = []
46
+ error = nil
47
+
48
+ page = 1
49
+ loop do
50
+ success, body = Toggl::Client.time_entries(
51
+ toggl_config['access_token'],
52
+ time_entries_params(connection, report_interval, page)
53
+ )
54
+
55
+ unless success
56
+ error = body.fetch('message', body)
57
+ break
58
+ end
59
+
60
+ entries_list << body['data']
61
+ entries_list.flatten!
62
+ entries_list.compact!
63
+
64
+ break if entries_list.length >= body['total_count']
65
+
66
+ page += 1
67
+ end
43
68
 
44
- data
69
+ [entries_list, error]
45
70
  end
46
71
 
47
- def self.time_entries_params(connection, report_interval)
72
+ def self.time_entries_params(connection, report_interval, page = 1)
48
73
  start_date, end_date = report_interval
49
74
  params = {
50
75
  workspace_id: connection['workspace_id'],
@@ -52,7 +77,8 @@ module Sfctl
52
77
  billable: connection['billable'],
53
78
  rounding: connection['rounding'],
54
79
  since: start_date.to_s,
55
- until: end_date.to_s
80
+ until: end_date.to_s,
81
+ page: page
56
82
  }
57
83
  params[:task_ids] = connection['task_ids'] if connection['task_ids'].length.positive?
58
84
  params
@@ -78,10 +104,12 @@ module Sfctl
78
104
 
79
105
  def self.assignment_items(time_entries)
80
106
  time_entries.map do |te|
107
+ milliseconds = te['dur'] || 0
81
108
  {
82
- time: humanize_duration(te['dur']).to_f,
109
+ time_seconds: milliseconds.div(1000),
83
110
  date: Date.parse(te['start']).to_s,
84
- comment: te['description']
111
+ comment: te['description'],
112
+ external_id: te['id'].to_s
85
113
  }
86
114
  end
87
115
  end
data/lib/sfctl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sfctl
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.0.4'.freeze
3
3
  end
data/sfctl.gemspec CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |spec|
5
5
  spec.license = 'MIT'
6
6
  spec.version = Sfctl::VERSION
7
7
  spec.authors = ['Serhii Rudik', 'Markus Kuhnt']
8
- spec.email = ['serhii@starfish.team']
8
+ spec.email = ['hello@starfish.codes']
9
9
  spec.homepage = 'https://github.com/alphatier-works/sfctl'
10
10
  spec.summary = 'sfctl is a command line interface for the Starfish API.'
11
11
  # spec.homepage = ''
@@ -38,7 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.add_runtime_dependency 'tty-progressbar', '~> 0.17.0'
39
39
  spec.add_runtime_dependency 'tty-prompt', '~> 0.21.0'
40
40
  spec.add_runtime_dependency 'tty-reader', '~> 0.7.0'
41
- spec.add_runtime_dependency 'tty-screen', '~> 0.7.1'
41
+ spec.add_runtime_dependency 'tty-screen', '~> 0.8.1'
42
42
  spec.add_runtime_dependency 'tty-spinner', '~> 0.9.3'
43
43
  spec.add_runtime_dependency 'tty-table', '~> 0.11.0'
44
44
  spec.add_runtime_dependency 'tty-tree', '~> 0.4.0'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfctl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serhii Rudik
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-06-12 00:00:00.000000000 Z
12
+ date: 2021-09-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -311,14 +311,14 @@ dependencies:
311
311
  requirements:
312
312
  - - "~>"
313
313
  - !ruby/object:Gem::Version
314
- version: 0.7.1
314
+ version: 0.8.1
315
315
  type: :runtime
316
316
  prerelease: false
317
317
  version_requirements: !ruby/object:Gem::Requirement
318
318
  requirements:
319
319
  - - "~>"
320
320
  - !ruby/object:Gem::Version
321
- version: 0.7.1
321
+ version: 0.8.1
322
322
  - !ruby/object:Gem::Dependency
323
323
  name: tty-spinner
324
324
  requirement: !ruby/object:Gem::Requirement
@@ -377,7 +377,7 @@ dependencies:
377
377
  version: 0.4.2
378
378
  description:
379
379
  email:
380
- - serhii@starfish.team
380
+ - hello@starfish.codes
381
381
  executables:
382
382
  - sfctl
383
383
  extensions: []