renuo-cli 4.7.1 → 4.8.0

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: dfd554a0dc6c1e7a71d712c41a9e01f7d8a22f23e756fabf620b02b3fef3d912
4
- data.tar.gz: 788aab9b1d5eae0fd0cdbc8cec536e69761128749d553d426488218946a16d25
3
+ metadata.gz: 90d3b8e87a9471eda0e8c3562f8f9d0be7163f94bcf4e90eb3f05fe4618b0d87
4
+ data.tar.gz: a512b8151eb5a140cb35c15f7ec85744c9e3f8f3bc01ba81e0bc75afa3a98a48
5
5
  SHA512:
6
- metadata.gz: 7dc15ca3ddc34b94b1e7a0d2b8b628d94a7f01a04089f60a25d025e87dd148bb48801065e1f07d60754b1cb3e9e85b929d2726b9f9edb3a937cfd976f9175666
7
- data.tar.gz: eedd47ddb8f4c8e607fe6d94adfd51de86d12decc94cb97ba24287f2cf838317aaa37ba234f7ebad7d6a454e9d420c0062cc93df4b502d30cddd7a427b5d5181
6
+ metadata.gz: cab9dc3ae7914973a79137af6372e4ca94e5a725f57329da4cdd06babbd437e0024ff263b586c0dbe2394fa191d92ccdb6093c9d9ccca86cc5fc3af339f7ce65
7
+ data.tar.gz: e6dc36d8a6dbae546175f29a372c27ad85d30bccc23350c387f5c57dd487a548323dab6cc8be04748ed3ade3ffe37e93eccb01e9c07054345a3a22a50c3636a3
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.3.5
1
+ 3.4.1
data/bin/setup CHANGED
@@ -4,4 +4,3 @@ IFS=$'\n\t'
4
4
 
5
5
  gem install bundler --conservative
6
6
  bundle install
7
- ln -s ../../bin/check .git/hooks/pre-commit
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "renuo/cli/app/services/cloudfront_config_service"
4
4
 
5
+ # :nocov:
5
6
  class CreateAwsProject
6
7
  def initialize
7
8
  ensure_aws_setup?
@@ -115,3 +116,4 @@ class CreateAwsProject
115
116
  CLOUDFRONT_COMMANDS
116
117
  end
117
118
  end
119
+ # :nocov:
@@ -6,7 +6,7 @@ class GithubReplace
6
6
  validate_options opts
7
7
 
8
8
  opts.projects.split(",").each do |repo|
9
- base = clone_and_checkout repo
9
+ base = clone_and_checkout opts, repo
10
10
  find_and_replace args, repo, opts.files.split(",")
11
11
  create_pr opts, repo, base
12
12
  end
@@ -26,9 +26,9 @@ class GithubReplace
26
26
  abort ">> specify comma-separated files to check" unless opts.files
27
27
  end
28
28
 
29
- def clone_and_checkout(repo)
29
+ def clone_and_checkout(opts, repo)
30
30
  puts `cd #{repo} || git clone --depth=1 git@github.com:renuo/#{repo}.git`
31
- puts `cd #{repo} && echo git checkout -b "#{opts.branch}"`
31
+ puts `cd #{repo} && git checkout -b "#{opts.branch}"`
32
32
  `cd #{repo} && git branch -rl origin/main origin/master`.strip
33
33
  end
34
34
 
@@ -43,9 +43,9 @@ class GithubReplace
43
43
 
44
44
  def create_pr(opts, repo, base)
45
45
  puts `cd "#{repo}" \
46
- && echo git add . \
47
- && echo git commit -S -m "#{opts.title}" \
48
- && echo git push --set-upstream origin "#{opts.branch}" \
46
+ && git add . \
47
+ && git commit -S -m "#{opts.title}" \
48
+ && git push --set-upstream origin "#{opts.branch}" \
49
49
  && gh pr create -a @me -b "#{opts.body}" -t "#{opts.title}" -B "#{base}" -H "#{opts.branch}"`
50
50
  end
51
51
  end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :nocov:
3
4
  module Renuo
4
5
  module Cli
5
- VERSION = "4.7.1"
6
+ VERSION = "4.8.0"
6
7
  NAME = "renuo-cli"
7
8
  end
8
9
  end
10
+ # :nocov:
data/lib/renuo/cli.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "renuo/cli/version"
4
+ require "active_support"
5
+ require "active_support/core_ext"
4
6
  require "rubygems"
5
7
  require "gems"
6
8
  require "colorize"
@@ -16,14 +18,11 @@ require "renuo/cli/app/create_aws_project"
16
18
  require "renuo/cli/app/create_heroku_app"
17
19
  require "renuo/cli/app/configure_sentry"
18
20
  require "renuo/cli/app/create_new_logins"
19
- require "renuo/cli/app/work"
20
21
  require "renuo/cli/app/release_project"
21
22
  require "renuo/cli/app/fetch_emails"
22
23
  require "renuo/cli/app/heroku_users"
23
24
  require "renuo/cli/app/setup_uptimerobot"
24
- require "renuo/cli/app/release_xing"
25
25
  require "renuo/cli/app/configure_semaphore"
26
- require "renuo/cli/app/toggl_redmine_comparator"
27
26
  require "renuo/cli/app/renuo_version"
28
27
  require "renuo/cli/app/create_slidev_presentation"
29
28
  require "renuo/cli/app/commit_leaderboard_stage"
@@ -142,19 +141,6 @@ module Renuo
142
141
  end
143
142
  end
144
143
 
145
- command "work" do |c|
146
- c.syntax = "renuo work"
147
- c.summary = "A utility command to start working on a ticket."
148
- c.description = "When you start working on a feature, it will jump to the project folder, " \
149
- "start a new feature with the ticket number," \
150
- 'move the ticket in "In progress" state on Redmine and start Toggl with the ' \
151
- "ticket number or add the ticket number to the running one if there was none."
152
- c.example "renuo work start kinova 1234", "start working on ticket 1234 on kinova project"
153
- c.action do |args|
154
- Work.new.run(args)
155
- end
156
- end
157
-
158
144
  command "release" do |c|
159
145
  c.syntax = "renuo release"
160
146
  c.summary = "Release a projects state of develop (on github) to main in one command."
@@ -222,16 +208,6 @@ module Renuo
222
208
  end
223
209
  end
224
210
 
225
- command "release-xing" do |c|
226
- c.syntax = "renuo release-xing"
227
- c.summary = "Release Xing to preview."
228
- c.description = "Xing needs to be released manually. " \
229
- "You need a VPN connection open before runnign this command."
230
- c.action do |_args|
231
- ReleaseXing.new.run
232
- end
233
- end
234
-
235
211
  command "configure-semaphore" do |c|
236
212
  c.syntax = "renuo configure-semaphore"
237
213
  c.summary = "Adds standard semaphore configuration files to a project and creates the notifications"
@@ -242,16 +218,6 @@ module Renuo
242
218
  end
243
219
  end
244
220
 
245
- command "toggl-redmine" do |c|
246
- c.syntax = "renuo toggl-redmine"
247
- c.summary = "Compares your time entries between Toggl and Redmine"
248
- c.description = "This command extracts your time entries in Toggl and in Redmine and checks if they are " \
249
- "consistant. It can help you in your time booking to find if you booked something wrong"
250
- c.action do |_args|
251
- TogglRedmineComparator.call
252
- end
253
- end
254
-
255
221
  command "create-slidev-presentation" do |c|
256
222
  c.syntax = "renuo create-slidev-presentation [presentation-name]"
257
223
  c.summary = "Creates a new Slidev presentation with the Renuo theme"
data/renuo-cli.gemspec CHANGED
@@ -23,9 +23,9 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.required_ruby_version = ">= 3.1.0"
25
25
 
26
- spec.add_dependency "activeresource", "~> 5.1.0"
26
+ spec.add_dependency "activesupport", "~> 8.0.0"
27
27
  spec.add_dependency "colorize", "~> 0"
28
- spec.add_dependency "commander", "~> 4.0"
28
+ spec.add_dependency "commander", "~> 5.0"
29
29
  spec.add_dependency "gems", "~> 1.1"
30
30
  spec.add_dependency "redcarpet", "~> 3.0"
31
31
  spec.add_dependency "terminal-table"
metadata CHANGED
@@ -1,29 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renuo-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.1
4
+ version: 4.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renuo AG
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-05 00:00:00.000000000 Z
10
+ date: 2025-01-15 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: activeresource
13
+ name: activesupport
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: 5.1.0
18
+ version: 8.0.0
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: 5.1.0
25
+ version: 8.0.0
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: colorize
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +43,14 @@ dependencies:
44
43
  requirements:
45
44
  - - "~>"
46
45
  - !ruby/object:Gem::Version
47
- version: '4.0'
46
+ version: '5.0'
48
47
  type: :runtime
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - "~>"
53
52
  - !ruby/object:Gem::Version
54
- version: '4.0'
53
+ version: '5.0'
55
54
  - !ruby/object:Gem::Dependency
56
55
  name: gems
57
56
  requirement: !ruby/object:Gem::Requirement
@@ -340,10 +339,7 @@ files:
340
339
  - lib/renuo/cli/app/local_storage.rb
341
340
  - lib/renuo/cli/app/name_display.rb
342
341
  - lib/renuo/cli/app/package.json
343
- - lib/renuo/cli/app/redmine/csv_base_service.rb
344
- - lib/renuo/cli/app/redmine/issue.rb
345
342
  - lib/renuo/cli/app/release_project.rb
346
- - lib/renuo/cli/app/release_xing.rb
347
343
  - lib/renuo/cli/app/renuo_version.rb
348
344
  - lib/renuo/cli/app/secrets_fetcher.rb
349
345
  - lib/renuo/cli/app/services/cloudfront_config_service.rb
@@ -357,15 +353,9 @@ files:
357
353
  - lib/renuo/cli/app/templates/semaphore/semaphore.yml.erb
358
354
  - lib/renuo/cli/app/templates/slidev/README.md.erb
359
355
  - lib/renuo/cli/app/templates/slidev/package.json.erb
360
- - lib/renuo/cli/app/toggl/detail.rb
361
- - lib/renuo/cli/app/toggl/time_entry.rb
362
- - lib/renuo/cli/app/toggl/user.rb
363
- - lib/renuo/cli/app/toggl/workspace.rb
364
- - lib/renuo/cli/app/toggl_redmine_comparator.rb
365
356
  - lib/renuo/cli/app/upgrade_laptop.rb
366
357
  - lib/renuo/cli/app/upgrade_laptop/upgrade_laptop_execution.rb
367
358
  - lib/renuo/cli/app/upgrade_laptop/upgrade_mac_os.rb
368
- - lib/renuo/cli/app/work.rb
369
359
  - lib/renuo/cli/version.rb
370
360
  - notification.yml
371
361
  - renuo-cli.gemspec
@@ -376,7 +366,6 @@ licenses:
376
366
  - MIT
377
367
  metadata:
378
368
  rubygems_mfa_required: 'true'
379
- post_install_message:
380
369
  rdoc_options: []
381
370
  require_paths:
382
371
  - lib
@@ -391,8 +380,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
391
380
  - !ruby/object:Gem::Version
392
381
  version: '0'
393
382
  requirements: []
394
- rubygems_version: 3.5.18
395
- signing_key:
383
+ rubygems_version: 3.6.2
396
384
  specification_version: 4
397
385
  summary: The Renuo CLI automates some common workflows.
398
386
  test_files: []
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "csv"
4
-
5
- module Redmine
6
- class CsvBaseService
7
- API_LOCATION = "https://redmine.renuo.ch"
8
-
9
- def initialize(token)
10
- @token = token
11
- end
12
-
13
- def get
14
- http_response = http_request(generate_url)
15
- encoded_body = http_response.body.force_encoding("ISO-8859-1").encode("UTF-8")
16
- csv = parse_csv(encoded_body)
17
- parse_results(csv)
18
- end
19
-
20
- private
21
-
22
- def generate_url
23
- URI("#{API_LOCATION}/time_entries/report.csv?#{query}&key=#{@token}")
24
- end
25
-
26
- def http_request(url)
27
- req = Net::HTTP::Get.new(url)
28
- Net::HTTP.start(url.hostname, url.port, use_ssl: true) do |http|
29
- http.request(req)
30
- end
31
- end
32
-
33
- def query
34
- # to be implemented in concrete service
35
- end
36
-
37
- def parse_results(_csv)
38
- # to be implemented in concrete service
39
- end
40
-
41
- def parse_csv(body)
42
- separated_csv_entries = CSV.parse(body, col_sep: ",")
43
- keys = separated_csv_entries.shift[1..-2]
44
- entries = separated_csv_entries.shift[1..-2]
45
- keys.zip(entries).to_h
46
- rescue CSV::MalformedCSVError
47
- raise_bad_data_error
48
- end
49
-
50
- def raise_bad_data_error
51
- error = "Malformed CSV, please use comma delimiters (Redmine language setting?)"
52
- Rails.logger.error error
53
- raise Redmine::BadData, error
54
- end
55
- end
56
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_resource"
4
-
5
- module Redmine
6
- class Issue < ActiveResource::Base
7
- STATUSES = {
8
- to_start: 9,
9
- planned: 15,
10
- in_progress: 2,
11
- qa: 12
12
- }.freeze
13
-
14
- self.site = "https://redmine.renuo.ch"
15
- self.include_root_in_json = true
16
-
17
- def self.headers
18
- { "X-Redmine-API-Key" => RenuoCliConfig.redmine_api_key }
19
- end
20
-
21
- def html_url
22
- "#{self.class.site}issues/#{id}"
23
- end
24
- end
25
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class ReleaseXing
4
- TMP_FOLDER_NAME = "_RENUO_RELEASE_TEMP_#{rand(100_000_000)}".freeze
5
- MOVE_TO_TMP_FOLDER = "mkdir -p #{TMP_FOLDER_NAME} && cd #{TMP_FOLDER_NAME}".freeze
6
-
7
- def run
8
- checkout_project
9
- cmd_in_folder "git remote add -f renuo git@github.com:renuo/xing-campaign.git"
10
- cmd_in_folder "git pull"
11
- cmd_in_folder "git fetch renuo develop"
12
- cmd_in_folder "git subtree pull --prefix public renuo develop --squash"
13
- cmd_in_folder "git push"
14
- ensure
15
- cleanup
16
- end
17
-
18
- private
19
-
20
- def checkout_project
21
- system "#{MOVE_TO_TMP_FOLDER} && git clone git@gitlab.dc.xing.com:renuo-ag/wunsch-arbeitgeber.xing.com.git"
22
- end
23
-
24
- def cmd_in_folder(command)
25
- system "#{move_and_cd} && #{command}"
26
- end
27
-
28
- def move_and_cd
29
- "#{MOVE_TO_TMP_FOLDER} && cd wunsch-arbeitgeber.xing.com"
30
- end
31
-
32
- def cleanup
33
- system("rm -rf #{TMP_FOLDER_NAME}")
34
- end
35
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_resource"
4
-
5
- module Toggl
6
- module CustomJsonFormat
7
- include ActiveResource::Formats::JsonFormat
8
-
9
- # rubocop:disable Style/ModuleFunction
10
- extend self
11
- # rubocop:enable Style/ModuleFunction
12
-
13
- def decode(json)
14
- ActiveSupport::JSON.decode(json)["data"]
15
- end
16
- end
17
-
18
- class Detail < ActiveResource::Base
19
- self.format = CustomJsonFormat
20
- self.site = "https://toggl.com/reports/api/v2"
21
- self.include_root_in_json = true
22
- self.include_format_in_path = false
23
-
24
- def self.user
25
- RenuoCliConfig.toggl_api_token
26
- end
27
-
28
- def self.password
29
- "api_token"
30
- end
31
- end
32
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_resource"
4
-
5
- module Toggl
6
- class TimeEntry < ActiveResource::Base
7
- self.site = "https://www.toggl.com/api/v8/"
8
- self.include_root_in_json = true
9
- self.include_format_in_path = false
10
-
11
- def self.user
12
- RenuoCliConfig.toggl_api_token
13
- end
14
-
15
- def self.password
16
- "api_token"
17
- end
18
-
19
- def self.current
20
- data = get(:current)["data"]
21
- data ? new(data) : nil
22
- end
23
-
24
- def self.start(params)
25
- post(:start, {}, params.to_json)
26
- end
27
-
28
- def stop
29
- put(:stop)
30
- end
31
- end
32
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Toggl
4
- class User < ActiveResource::Base
5
- self.site = "https://www.toggl.com/api/v8/"
6
- self.include_root_in_json = true
7
- self.include_format_in_path = false
8
-
9
- def self.user
10
- RenuoCliConfig.toggl_api_token
11
- end
12
-
13
- def self.password
14
- "api_token"
15
- end
16
-
17
- def self.custom_method_collection_url(method_name, options)
18
- prefix_options, query_options = split_options(options)
19
- "#{prefix(prefix_options)}#{method_name}#{format_extension}#{query_string(query_options)}"
20
- end
21
-
22
- def self.me
23
- new(get(:me)["data"])
24
- end
25
- end
26
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_resource"
4
-
5
- module Toggl
6
- class Workspace < ActiveResource::Base
7
- self.site = "https://www.toggl.com/api/v8/"
8
- self.include_root_in_json = true
9
- self.include_format_in_path = false
10
-
11
- def self.user
12
- RenuoCliConfig.toggl_api_token
13
- end
14
-
15
- def self.password
16
- "api_token"
17
- end
18
- end
19
- end
@@ -1,150 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "commander"
4
- require "csv"
5
- require_relative "environments"
6
- require_relative "fetch_emails"
7
- require "renuo/cli/app/toggl/workspace"
8
- require "renuo/cli/app/toggl/detail"
9
- require "renuo/cli/app/toggl/user"
10
- require "terminal-table"
11
- require "colorize"
12
- require "active_support/core_ext/numeric/time"
13
-
14
- # rubocop:disable Metrics/ClassLength
15
- class TogglRedmineComparator
16
- class << self
17
- def call(days_behind = 7)
18
- report = {}
19
- since_date = days_behind.days.before(Date.yesterday).strftime("%F")
20
- until_date = Date.yesterday.strftime("%F")
21
- extract_redmine(report, since_date, until_date)
22
- extract_toggl(report, since_date, until_date)
23
- report = report.sort.reverse.to_h
24
- print_table(report)
25
- report
26
- end
27
-
28
- private
29
-
30
- def print_table(report)
31
- rows = []
32
- report.each do |date, value|
33
- rows << colorize_table_row(date, value)
34
- rows << :separator
35
- end
36
- rows.pop
37
- table = Terminal::Table.new headings: %w[Day Redmine Toggl].map(&:cyan), rows:,
38
- style: { padding_left: 2, padding_right: 2,
39
- border_x: "-".blue, border_y: "|".blue, border_i: "+".blue }
40
- puts table
41
- end
42
-
43
- def colorize_table_row(date, value)
44
- printed_day = date.strftime("%F %a")
45
- printed_redmine = to_time(value[:redmine])
46
- printed_toggl = to_time(value[:toggl])
47
- colorize_method = colorization_for_value(value)
48
- [printed_day, printed_redmine, printed_toggl].map { |v| v.colorize(colorize_method) }
49
- end
50
-
51
- def colorization_for_value(value)
52
- if more_toggl?(value)
53
- :red
54
- elsif more_redmine?(value)
55
- :default
56
- else
57
- :green
58
- end
59
- end
60
-
61
- def extract_redmine(report, since_date, _until_date)
62
- encoded_body = perform_redmine_call(since_date)
63
- csv = convert_redmine_csv(encoded_body)
64
- csv.each do |date, entry|
65
- report[Date.parse(date)] ||= default_value
66
- report[Date.parse(date)][:redmine] = to_seconds(entry) if entry.present?
67
- end
68
- end
69
-
70
- def convert_redmine_csv(encoded_body)
71
- separated_csv_entries = CSV.parse(encoded_body, col_sep: ",")
72
- keys = separated_csv_entries.shift[1..-2]
73
- entries = separated_csv_entries.shift[1..-2]
74
- keys.zip(entries)
75
- end
76
-
77
- def perform_redmine_call(since_date)
78
- query = generate_redmine_query(since_date)
79
- url = URI("https://redmine.renuo.ch/time_entries/report.csv?#{query}")
80
- req = Net::HTTP::Get.new(url)
81
- req["X-Redmine-API-Key"] = RenuoCliConfig.redmine_api_key
82
- response = Net::HTTP.start(url.hostname, url.port, use_ssl: true) { |http| http.request(req) }
83
- response.body.force_encoding("ISO-8859-1").encode("UTF-8")
84
- end
85
-
86
- def generate_redmine_query(since_date)
87
- URI.encode_www_form(
88
- [["utf8", "✓"], ["criteria[]", "user"],
89
- ["f[]", "spent_on"], ["f[]", "user_id"],
90
- ["op[spent_on]", ">="], ["op[user_id]", "="],
91
- ["v[spent_on][]", since_date], ["v[user_id][]", "me"],
92
- ["f[]", ""],
93
- ["c[]", "project"], ["c[]", "spent_on"], ["c[]", "user"], ["c[]", "activity"], ["c[]", "issue"],
94
- ["c[]", "comments"], ["c[]", "hours"], %w[columns day], ["criteria[]", ""]]
95
- )
96
- end
97
-
98
- def extract_toggl(report, since_date, until_date)
99
- user_id = Toggl::User.me.id
100
- workspace_ids = Toggl::Workspace.all.map(&:id)
101
-
102
- workspace_ids.each do |workspace_id|
103
- time_entries = Toggl::Detail.where(since: since_date, until: until_date,
104
- user_agent: "renuo-cli", workspace_id:, user_ids: user_id)
105
- parse_toggl_entries(report, time_entries)
106
- end
107
- end
108
-
109
- def parse_toggl_entries(report, time_entries)
110
- time_entries
111
- .reject { |te| te.end.nil? }
112
- .group_by { |time_entry| Date.parse(time_entry.end) }
113
- .each do |date, grouped_time_entries|
114
- report[date] ||= default_value
115
- report[date][:toggl] += grouped_time_entries.sum(&:dur)
116
- end
117
- end
118
-
119
- def default_value
120
- { redmine: 0.0, toggl: 0.0 }
121
- end
122
-
123
- def to_time(value)
124
- sec = value / 1000.0
125
- min, _sec = sec.divmod(60.0)
126
- hour, min = min.divmod(60.0)
127
- format("%<hour>02d:%<min>02d", hour:, min:)
128
- end
129
-
130
- def to_seconds(value)
131
- hours, minutes = value.to_d.divmod(1.0)
132
- (hours * 60 * 60 * 1000) + (minutes * 60 * 60 * 1000)
133
- end
134
-
135
- def non_working_day?(value)
136
- [value[:redmine], value[:toggl]].all?(&:zero?)
137
- end
138
-
139
- BUFFER = 20_000
140
-
141
- def more_toggl?(value)
142
- (value[:toggl] - value[:redmine]) > BUFFER
143
- end
144
-
145
- def more_redmine?(value)
146
- (value[:redmine] - value[:toggl]) > BUFFER
147
- end
148
- end
149
- end
150
- # rubocop:enable Metrics/ClassLength
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "fileutils"
4
- require "renuo/cli/app/redmine/issue"
5
- require "renuo/cli/app/toggl/time_entry"
6
-
7
- class Work
8
- ACTIONS = %w[start].freeze
9
-
10
- def run(args)
11
- ActiveResource::Base.logger = Logger.new($stdout)
12
- @action, @project_name, @ticket_number = args
13
- validate_action
14
- validate_project_name
15
- validate_ticket_number
16
- start_feature_branch
17
- update_redmine_ticket
18
- start_toggl
19
- end
20
-
21
- private
22
-
23
- # TODO: I want to implement also the stop action.
24
- def validate_action
25
- abort(">> No action given. It must be start") unless ACTIONS.include? @action
26
- end
27
-
28
- def validate_project_name
29
- abort(">> No project name given.") unless @project_name
30
- end
31
-
32
- def validate_ticket_number
33
- abort(">> No ticket number given.") unless @ticket_number
34
- issue = Redmine::Issue.find(@ticket_number)
35
- open_statuses = Redmine::Issue::STATUSES.values_at(:to_start, :planned, :in_progress, :qa)
36
- return if open_statuses.include?(issue.status.id)
37
-
38
- system("open #{issue.html_url}")
39
- abort(">> Ticket should be in an open status")
40
- end
41
-
42
- def start_feature_branch
43
- project_folder = `autojump #{@project_name}`.strip
44
- system("cd #{project_folder} && git stash && git checkout develop " \
45
- "&& git pull && git flow feature start #{@ticket_number}")
46
- end
47
-
48
- def update_redmine_ticket
49
- issue = Redmine::Issue.find(@ticket_number)
50
- issue.status_id = Redmine::Issue::STATUSES[:in_progress]
51
- issue.save
52
- system("open #{issue.html_url}")
53
- end
54
-
55
- def start_toggl
56
- current_time_entry = Toggl::TimeEntry.current
57
- if current_time_entry.nil?
58
- create_toggl_time_entry
59
- elsif current_time_entry.description.nil?
60
- update_toggl_time_entry(current_time_entry.id)
61
- else
62
- existing_toggl(current_time_entry)
63
- end
64
- end
65
-
66
- def existing_toggl(current_time_entry)
67
- say("A timer '#{current_time_entry.description}' was already running.")
68
- if current_time_entry.description.to_i == @ticket_number.to_i
69
- say("I will keep using it")
70
- else
71
- say("I stopped it and started a new time entry.")
72
- stop_toggl_time_entry(current_time_entry.id)
73
- create_toggl_time_entry
74
- end
75
- end
76
-
77
- def update_toggl_time_entry(time_entry_id)
78
- say("A timer was already running but without a project assigned. I updated the current time entry.")
79
-
80
- time_entry = Toggl::TimeEntry.find(time_entry_id)
81
- time_entry.description = @ticket_number.to_s
82
- time_entry.tags = [@project_name.to_s]
83
- time_entry.created_with = "curl"
84
- time_entry.save
85
- end
86
-
87
- def create_toggl_time_entry
88
- Toggl::TimeEntry.start(time_entry: { description: @ticket_number.to_s,
89
- tags: [@project_name.to_s],
90
- created_with: "curl" })
91
- end
92
-
93
- def stop_toggl_time_entry(time_entry_id)
94
- Toggl::TimeEntry.find(time_entry_id).stop
95
- end
96
- end