afterlife 1.7.3 → 1.7.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04142460aa12c27177dd71d0450a10930e27370ab91b753f107ace751735ebbd
4
- data.tar.gz: a9f0f37abc39566e8c7a5660b5a86108a7e1dcc88f87936e882f0364f00687c7
3
+ metadata.gz: 5b3027a754b5aeaaa15a7dbbba4b5aa895ce11fb48402dd9a4348f30b3dc8aa7
4
+ data.tar.gz: 2253a73fd40b0e247cafb3b35b0bd0d75fb9b78d722b7887a7800b30d0f8faa9
5
5
  SHA512:
6
- metadata.gz: c503b855bd1257b9266c010ca4364fc894d26aefaccb65f2debaba46859bf7af51e661265f148bb0119ea1432e3edc7fd21d5f89ba546e8be719c7f26e1c960c
7
- data.tar.gz: 9e046b5c9bb75f1ffd71edf220935260423c5d4d7d5fffabaedffc82a849944e0850458ac1e90885ccb96ad5072d802cac06bfa1851139f27295287386b42f1f
6
+ metadata.gz: 01a9c292bef075d314f0ce97ff3deda29705247f9e6e0227c82645292fe0ffe262a4d18d62b8abd896b6376325bcb5071a61d90f992ee47e42dba0a0828bba64
7
+ data.tar.gz: 2f7763617dbd485d863afb4ea226caac63fa3493b14ab3a0c35c186d11ff22f01a8b2e895ba0b7d12ca5cc30db45e140a4be0814e557840cdffd3ff085016b99
data/README.md CHANGED
@@ -40,12 +40,29 @@ To not do this blindly, you can run just `afterlife clickup get-commits <revisio
40
40
  clickup extract-ids` to review if the tasks being moved are correct. But the `update-status` in the
41
41
  full command will print the list of moved or ignored tasks anyway.
42
42
 
43
+ Also, to easily run these commands, is recommended to setup an alias:
44
+
45
+ For bash or zsh:
46
+ ```bash
47
+ alias ci="afterlife clickup"
48
+ ```
49
+
50
+ For fish:
51
+ ```fish
52
+ alias ci 'afterlife clickup'
53
+ ```
54
+
43
55
  ## Development
44
56
 
45
57
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
46
58
 
47
59
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
60
 
61
+ ## Publishing
62
+ This gem is published on rubygems. To publish there, just:
63
+ 1. Do a version bump in `lib/afterlife/version.rb`.
64
+ 2. Execute `bundle exec rake release`. This will ask you for rubygems credentials. You'll access, ask Genaro for it.
65
+
49
66
  ## Contributing
50
67
 
51
68
  Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/afterlife.
@@ -12,16 +12,20 @@ module Afterlife
12
12
  end
13
13
 
14
14
  desc 'extract-ids [TEXT]', 'Extract ClickUp task IDs from text or stdin'
15
+ option :link, type: :boolean, default: false, aliases: '-l',
16
+ desc: 'Convert task IDs to links'
15
17
  def extract_ids(text = nil)
16
18
  text ||= $stdin.read
17
- ids = GetIdsFromText.call(text)
19
+ ids = GetIdsFromText.call(text, options[:link])
18
20
  ids.each { |id| puts id }
19
21
  end
20
22
 
21
23
  desc 'get-commits FROM_REVISION [TO_REVISION]',
22
24
  'Get commits between revisions. The revision can be a short or long version of the commit sha.'
25
+ option :short, type: :boolean, default: false, aliases: '-s',
26
+ desc: 'Only prints a short version of the commit, do not use it on CI.'
23
27
  def get_commits(from_revision, to_revision = 'HEAD')
24
- messages = GetRangeCommits.call(from_revision, to_revision)
28
+ messages = GetRangeCommits.call(from_revision, to_revision, short: options[:short])
25
29
  puts messages
26
30
  rescue StandardError => e
27
31
  fatal!(e.message)
@@ -29,10 +33,14 @@ module Afterlife
29
33
 
30
34
  desc 'update-status TARGET_STATUS TASK_ID [TASK_ID...]',
31
35
  "Update status of ClickUp tasks. Possible values for TARGET_STATUS: #{CLICKUP_STATUS_OPTIONS}"
36
+ option :force, type: :boolean, default: false, aliases: '-f',
37
+ desc: 'Force update status of tasks even if they would not be updated due to status precedence'
38
+ option :dry_run, type: :boolean, default: false, aliases: '-d',
39
+ desc: 'Do not actually update the status of the tasks, just print what would be done'
32
40
  def update_status(target_status, *task_ids)
33
41
  task_ids = $stdin.read.strip.split("\n") if task_ids.empty?
34
42
 
35
- UpdateTaskStatus.call(task_ids, target_status)
43
+ UpdateTaskStatus.call(task_ids, target_status, force: options[:force], dry_run: options[:dry_run])
36
44
  rescue StandardError => e
37
45
  fatal!(e.message)
38
46
  end
@@ -10,7 +10,7 @@ module Afterlife
10
10
  /CU-([a-z0-9]+)/i,
11
11
  ].freeze
12
12
 
13
- def self.call(text)
13
+ def self.call(text, convert_to_link = false) # rubocop:disable Metrics/MethodLength
14
14
  ids = Set.new
15
15
 
16
16
  ID_PATTERNS.each do |pattern|
@@ -19,7 +19,11 @@ module Afterlife
19
19
  end
20
20
  end
21
21
 
22
- ids.to_a
22
+ if convert_to_link
23
+ ids.map { |id| "https://app.clickup.com/t/#{id}" }
24
+ else
25
+ ids.to_a
26
+ end
23
27
  end
24
28
  end
25
29
  end
@@ -5,9 +5,13 @@ require 'English'
5
5
  module Afterlife
6
6
  module Clickup
7
7
  class GetRangeCommits
8
- def self.call(from_revision, to_revision = 'HEAD')
8
+ SHORT_PARAMS = "--graph --decorate --pretty=format:'%C(yellow)%h %C(cyan)%ad %C(cyan)%d %Creset%s %Cgreen[%an]' --date=relative" # rubocop:disable Layout/LineLength
9
+ DEFAULT_PARAMS = "--pretty=format:'%s%n%b'"
10
+
11
+ def self.call(from_revision, to_revision = 'HEAD', short: nil)
9
12
  range = "#{from_revision}..#{to_revision}"
10
- commit_messages = `git log --pretty=format:"%s%n%b" #{range}`.strip
13
+ params = short ? SHORT_PARAMS : DEFAULT_PARAMS
14
+ commit_messages = `git log #{params} #{range}`.strip
11
15
  fail "Error getting commits for range #{range}" unless $CHILD_STATUS.success?
12
16
 
13
17
  commit_messages
@@ -3,27 +3,34 @@
3
3
  module Afterlife
4
4
  module Clickup
5
5
  class UpdateTaskStatus
6
- attr_reader :target_status, :precedence_checker, :api
6
+ attr_reader :target_status, :precedence_checker, :api, :force, :dry_run
7
7
 
8
- def self.call(task_ids, target_status)
9
- new.call(task_ids, target_status)
8
+ def self.call(task_ids, target_status, force: false, dry_run: false)
9
+ new(force: force, dry_run: dry_run).call(task_ids, target_status)
10
10
  end
11
11
 
12
- def initialize
12
+ def initialize(force: false, dry_run: false)
13
+ @force = force
14
+ @dry_run = dry_run
13
15
  token = ENV['CLICKUP_TOKEN'] || fail('CLICKUP_TOKEN required, put `export CLICKUP_TOKEN=...` or the equivalent in your shell') # rubocop:disable Layout/LineLength
14
16
  @api = Api.new(token: token)
15
17
  @precedence_checker = StatusPrecedenceChecker.new
16
18
  end
17
19
 
18
- def call(task_ids, target_status)
20
+ def call(task_ids, target_status) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
19
21
  if task_ids.empty?
20
22
  puts 'No tasks to update'
21
23
  return []
22
24
  end
23
25
 
26
+ puts 'WARNING: Forcing status updates...' if force
27
+ puts 'WARNING: Dry run, no tasks will be updated' if dry_run
24
28
  puts "Updating #{task_ids.length} tasks to '#{target_status}'"
25
29
  moved_task_ids = task_ids.map { |task_id| move_task(task_id, target_status) }.compact
26
- puts "Moved #{moved_task_ids.length} tasks, with ids: #{moved_task_ids.join(', ')}"
30
+ puts "#{dry_run ? 'Would have moved' : 'Moved'} #{moved_task_ids.length} tasks:"
31
+ moved_task_ids.each do |task|
32
+ puts "- #{task[:link]} (from '#{task[:previous_status]}' to '#{task[:new_status]}')"
33
+ end
27
34
  moved_task_ids
28
35
  end
29
36
 
@@ -34,11 +41,12 @@ module Afterlife
34
41
 
35
42
  return puts "WARNING: Task #{task_id} not found" if current_status.nil?
36
43
 
37
- should_skip_update = precedence_checker.should_skip_update?(current_status, target_status)
38
- return puts "Skipping task #{task_id} because it's already at '#{current_status}'" if should_skip_update
44
+ should_skip_update = !force && precedence_checker.should_skip_update?(current_status, target_status)
45
+ task_link = "https://app.clickup.com/t/#{task_id}"
46
+ return puts "Skipping task #{task_link} because it's already at '#{current_status}'" if should_skip_update
39
47
 
40
- api.update_task(task_id, { status: target_status })
41
- task_id
48
+ api.update_task(task_id, { status: target_status }) unless dry_run
49
+ { id: task_id, link: task_link, previous_status: current_status, new_status: target_status }
42
50
  end
43
51
  end
44
52
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Afterlife
4
- VERSION = '1.7.3'
4
+ VERSION = '1.7.4'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: afterlife
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.3
4
+ version: 1.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genaro Madrid
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-07-29 00:00:00.000000000 Z
11
+ date: 2025-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday