cardigan 0.0.9 → 0.1.0
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.
- data/.gemtest +0 -0
- data/Rakefile +6 -0
- data/bin/cardigan +2 -0
- data/lib/cardigan/cli.rb +18 -20
- data/lib/cardigan/command/add_transitions.rb +27 -0
- data/lib/cardigan/command/batch_update_cards.rb +15 -14
- data/lib/cardigan/command/change_status.rb +18 -11
- data/lib/cardigan/command/change_value.rb +11 -10
- data/lib/cardigan/command/claim_cards.rb +15 -13
- data/lib/cardigan/command/commit_changes.rb +15 -0
- data/lib/cardigan/command/count_cards.rb +6 -2
- data/lib/cardigan/command/create_card.rb +14 -11
- data/lib/cardigan/command/destroy_cards.rb +15 -13
- data/lib/cardigan/command/edit_value.rb +12 -11
- data/lib/cardigan/command/export_cards.rb +9 -4
- data/lib/cardigan/command/filter_cards.rb +6 -0
- data/lib/cardigan/command/import_cards.rb +18 -4
- data/lib/cardigan/command/list_cards.rb +5 -0
- data/lib/cardigan/command/open_card.rb +20 -12
- data/lib/cardigan/command/open_workflow.rb +14 -12
- data/lib/cardigan/command/remove_transitions.rb +25 -0
- data/lib/cardigan/command/show_entry.rb +12 -10
- data/lib/cardigan/command/specify_display_columns.rb +6 -0
- data/lib/cardigan/command/specify_sort_columns.rb +6 -0
- data/lib/cardigan/command/total_cards.rb +6 -2
- data/lib/cardigan/command/unclaim_cards.rb +13 -13
- data/lib/cardigan/command/unfilter_cards.rb +6 -0
- data/lib/cardigan/commands.rb +10 -0
- data/lib/cardigan/entry_context.rb +7 -12
- data/lib/cardigan/filtered_repository.rb +9 -5
- data/lib/cardigan/io.rb +1 -1
- data/lib/cardigan/root_context.rb +21 -23
- data/lib/cardigan/workflow_context.rb +12 -29
- data/lib/cardigan/workflow_repository.rb +18 -10
- data/spec/command/add_transitions_spec.rb +35 -0
- data/spec/command/batch_update_cards_spec.rb +9 -0
- data/spec/command/change_status_spec.rb +9 -0
- data/spec/command/change_value_spec.rb +9 -0
- data/spec/command/claim_cards_spec.rb +9 -0
- data/spec/command/commit_changes_spec.rb +9 -0
- data/spec/command/count_cards_spec.rb +68 -0
- data/spec/command/create_card_spec.rb +9 -0
- data/spec/command/destroy_cards_spec.rb +9 -0
- data/spec/command/edit_value_spec.rb +9 -0
- data/spec/command/export_cards_spec.rb +9 -0
- data/spec/command/filter_cards_spec.rb +9 -0
- data/spec/command/import_cards_spec.rb +9 -0
- data/spec/command/list_cards_spec.rb +9 -0
- data/spec/command/open_card_spec.rb +9 -0
- data/spec/command/open_workflow_spec.rb +9 -0
- data/spec/command/remove_transitions_spec.rb +25 -0
- data/spec/command/show_entry_spec.rb +9 -0
- data/spec/command/specify_display_columns_spec.rb +9 -0
- data/spec/command/specify_sort_columns_spec.rb +9 -0
- data/spec/command/total_cards_spec.rb +82 -0
- data/spec/command/unfilter_cards_spec.rb +9 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/text_report_formatter_spec.rb +47 -0
- metadata +100 -35
- data/lib/cardigan/command/select_columns.rb +0 -20
- data/lib/cardigan/context.rb +0 -60
- data/lib/cardigan/directory.rb +0 -34
- data/lib/cardigan/repository.rb +0 -54
- data/lib/cardigan/symbol_extensions.rb +0 -3
data/.gemtest
ADDED
File without changes
|
data/Rakefile
ADDED
data/bin/cardigan
CHANGED
data/lib/cardigan/cli.rb
CHANGED
@@ -1,28 +1,26 @@
|
|
1
1
|
require 'cardigan/io'
|
2
2
|
require 'cardigan/root_context'
|
3
|
-
require '
|
3
|
+
require 'flat_hash/directory'
|
4
|
+
require 'flat_hash/serialiser'
|
5
|
+
require 'flat_hash/repository'
|
4
6
|
require 'cardigan/workflow_repository'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
CONFIG_FILE = '.cardigan'
|
8
|
+
class Cardigan::Cli
|
9
|
+
CONFIG_FILE = '.cardigan'
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def initialize io=Cardigan::Io.new
|
12
|
+
@io = io
|
13
|
+
@home = FlatHash::Directory.new(FlatHash::Serialiser.new,File.expand_path('~'))
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
name = "\"#{config[:name]}\" <#{config[:email]}>"
|
25
|
-
RootContext.new(@io, Repository.new('.cards'), name, WorkflowRepository.new('.')).push
|
26
|
-
end
|
16
|
+
def execute *args
|
17
|
+
config = @home.exist?(CONFIG_FILE) ? @home[CONFIG_FILE] : {}
|
18
|
+
config['name'] = @io.ask('Enter your full name') unless config['name']
|
19
|
+
config['email'] = @io.ask('Enter your email address') unless config['email']
|
20
|
+
@home[CONFIG_FILE] = config
|
21
|
+
repository = FlatHash::Repository.new(FlatHash::Serialiser.new,'.cards')
|
22
|
+
name = "\"#{config['name']}\" <#{config['email']}>"
|
23
|
+
workflow_repository = Cardigan::WorkflowRepository.new('.')
|
24
|
+
Cardigan::RootContext.new(@io, repository, name, workflow_repository).push
|
27
25
|
end
|
28
26
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'cardigan/commands'
|
2
|
+
|
3
|
+
class Cardigan::Command::AddTransitions
|
4
|
+
attr_reader :usage, :help
|
5
|
+
|
6
|
+
def initialize entry, io
|
7
|
+
@entry, @io = entry, io
|
8
|
+
@usage = '<start status> [<subsequent status>]+'
|
9
|
+
@help = 'Creates transitions from a starting status to a number of subsequent statuses'
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute text=nil
|
13
|
+
unless text and !text.empty?
|
14
|
+
@io.say 'missing required start status'
|
15
|
+
return
|
16
|
+
end
|
17
|
+
name, *states = text.scan(/\w+/)
|
18
|
+
if states.empty?
|
19
|
+
@io.say 'missing required subsequent status'
|
20
|
+
return
|
21
|
+
end
|
22
|
+
@entry[name] ||= []
|
23
|
+
states = states.uniq
|
24
|
+
@entry[name] += states
|
25
|
+
states.each {|state| @entry[state] ||= [] }
|
26
|
+
end
|
27
|
+
end
|
@@ -1,20 +1,21 @@
|
|
1
|
+
require 'cardigan/commands'
|
1
2
|
require 'cardigan/card_editor'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
class BatchUpdateCards
|
6
|
-
def initialize repository, io
|
7
|
-
@repository, @io = repository, io
|
8
|
-
end
|
4
|
+
class Cardigan::Command::BatchUpdateCards
|
5
|
+
attr_reader :usage, :help
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
def initialize repository, io
|
8
|
+
@repository, @io = repository, io
|
9
|
+
@usage = '<field> <number>*'
|
10
|
+
@help = 'Sets the specified field to a new value for the specified cards (by index in the list)'
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute text
|
14
|
+
key, *rest = text.scan(/\w+/)
|
15
|
+
value = @io.ask("Enter the new value for #{key}")
|
16
|
+
@repository.each_card_from_indices(rest.join(' ')) do |card|
|
17
|
+
Cardigan::CardEditor.new(card, @io).set key, value
|
18
|
+
@repository[card.id] = card
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -1,13 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
require 'cardigan/commands'
|
2
|
+
|
3
|
+
class Cardigan::Command::ChangeStatus
|
4
|
+
attr_reader :usage, :help
|
5
|
+
|
6
|
+
def initialize entry, workflow_repository
|
7
|
+
@entry, @workflow_repository = entry, workflow_repository
|
8
|
+
@usage = '<new status>'
|
9
|
+
@help = 'Changes the status of the current entry'
|
10
|
+
end
|
11
|
+
|
12
|
+
def completion text
|
13
|
+
status = @entry['status'] || 'none'
|
14
|
+
@workflow_repository.load[status].grep(/^#{text}/).sort || []
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute status
|
18
|
+
@entry['status'] = status
|
12
19
|
end
|
13
20
|
end
|
@@ -1,15 +1,16 @@
|
|
1
|
+
require 'cardigan/commands'
|
1
2
|
require 'cardigan/card_editor'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
class ChangeValue
|
6
|
-
def initialize entry, io
|
7
|
-
@entry, @io = entry, io
|
8
|
-
end
|
4
|
+
class Cardigan::Command::ChangeValue
|
5
|
+
attr_reader :usage, :help
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
def initialize entry, io
|
8
|
+
@entry, @io = entry, io
|
9
|
+
@usage = '<key>'
|
10
|
+
@help = 'Prompt for a new value to associate with the specified key'
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute key
|
14
|
+
Cardigan::CardEditor.new(@entry, @io).set key, @io.ask("Enter the new value for #{key}")
|
14
15
|
end
|
15
16
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
-
|
2
|
-
module Command
|
3
|
-
class ClaimCards
|
4
|
-
def initialize repository, io, name
|
5
|
-
@repository, @io, @name = repository, io, name
|
6
|
-
end
|
1
|
+
require 'cardigan/commands'
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
class Cardigan::Command::ClaimCards
|
4
|
+
attr_reader :usage, :help
|
5
|
+
|
6
|
+
def initialize repository, io, name
|
7
|
+
@repository, @io, @name = repository, io, name
|
8
|
+
@usage = '<number>*'
|
9
|
+
@help = 'Sets you as the owner of the specified cards (by index in the list)'
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute numbers
|
13
|
+
@repository.each_card_from_indices(numbers || '') do |card|
|
14
|
+
@io.say "claiming \"#{card['name']}\""
|
15
|
+
card['owner'] = @name
|
16
|
+
@repository[card.id] = card
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'cardigan/commands'
|
2
|
+
|
3
|
+
class Cardigan::Command::CommitChanges
|
4
|
+
attr_reader :usage, :help
|
5
|
+
|
6
|
+
def initialize repository, io
|
7
|
+
@io, @repository = io, repository
|
8
|
+
@usage = "<commit message>"
|
9
|
+
@help = "Commits _all_ changes (adds, removes and modifications) to the source control system\nWarning: Use with caution. This will not only commit changes to cards - all modifications will be committed."
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute text=nil
|
13
|
+
@repository.addremovecommit text
|
14
|
+
end
|
15
|
+
end
|
@@ -1,9 +1,13 @@
|
|
1
|
-
require 'cardigan/
|
1
|
+
require 'cardigan/commands'
|
2
2
|
require 'cardigan/text_report_formatter'
|
3
3
|
|
4
4
|
class Cardigan::Command::CountCards
|
5
|
+
attr_reader :usage, :help
|
6
|
+
|
5
7
|
def initialize repository, io
|
6
8
|
@repository, @io = repository, io
|
9
|
+
@usage = "<grouping field>*"
|
10
|
+
@help = "Counts cards aggregated across the specified grouping fields"
|
7
11
|
end
|
8
12
|
|
9
13
|
def execute text=nil
|
@@ -12,7 +16,7 @@ class Cardigan::Command::CountCards
|
|
12
16
|
lengths = Array.new(grouping_fields.size, 0)
|
13
17
|
counts = {}
|
14
18
|
total = 0
|
15
|
-
@repository.each do |card|
|
19
|
+
@repository.cards.each do |card|
|
16
20
|
grouping_fields.each_with_index do |grouping_field,index|
|
17
21
|
lengths[index] = card[grouping_field].size if card[grouping_field] and card[grouping_field].size > lengths[index]
|
18
22
|
end
|
@@ -1,13 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class CreateCard
|
4
|
-
def initialize repository
|
5
|
-
@repository = repository
|
6
|
-
end
|
1
|
+
require 'cardigan/commands'
|
2
|
+
require 'uuidtools'
|
7
3
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
class Cardigan::Command::CreateCard
|
5
|
+
attr_reader :usage, :help
|
6
|
+
|
7
|
+
def initialize repository
|
8
|
+
@repository = repository
|
9
|
+
@usage = '<name>'
|
10
|
+
@help = 'Creates a new card with the specified name (without opening it for editing)'
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute name
|
14
|
+
@repository[UUIDTools::UUID.random_create.to_s] = {'name' => name }
|
12
15
|
end
|
13
|
-
end
|
16
|
+
end
|
@@ -1,16 +1,18 @@
|
|
1
|
-
|
2
|
-
module Command
|
3
|
-
class DestroyCards
|
4
|
-
def initialize repository, io
|
5
|
-
@repository, @io = repository, io
|
6
|
-
end
|
1
|
+
require 'cardigan/commands'
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
3
|
+
class Cardigan::Command::DestroyCards
|
4
|
+
attr_reader :usage, :help
|
5
|
+
|
6
|
+
def initialize repository, io
|
7
|
+
@repository, @io = repository, io
|
8
|
+
@usage = '<number>*'
|
9
|
+
@help = 'Destroys the specified cards (by index in the list)'
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute numbers
|
13
|
+
@repository.each_card_from_indices(numbers) do |card|
|
14
|
+
@io.say "destroying \"#{card['name']}\""
|
15
|
+
@repository.destroy card.id
|
14
16
|
end
|
15
17
|
end
|
16
|
-
end
|
18
|
+
end
|
@@ -1,17 +1,18 @@
|
|
1
|
+
require 'cardigan/commands'
|
1
2
|
require 'splat'
|
2
3
|
require 'cardigan/card_editor'
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
class EditValue
|
7
|
-
def initialize entry, io
|
8
|
-
@entry, @io = entry, io
|
9
|
-
end
|
5
|
+
class Cardigan::Command::EditValue
|
6
|
+
attr_reader :usage, :help
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
def initialize entry, io
|
9
|
+
@entry, @io = entry, io
|
10
|
+
@usage = '<key>'
|
11
|
+
@help = 'Launch default editor to specify a new value to associate with the specified key'
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute key
|
15
|
+
value = @entry[key] ? @entry[key] : ''
|
16
|
+
Cardigan::CardEditor.new(@entry, @io).set key, value.to_editor
|
16
17
|
end
|
17
18
|
end
|
@@ -1,17 +1,22 @@
|
|
1
|
+
require 'cardigan/commands'
|
1
2
|
require 'csv'
|
2
3
|
|
3
4
|
class Cardigan::Command::ExportCards
|
5
|
+
attr_reader :usage, :help
|
6
|
+
|
4
7
|
def initialize repository
|
5
8
|
@repository = repository
|
9
|
+
@usage = '<filename>'
|
10
|
+
@help = 'Exports all cards according to the current filter'
|
6
11
|
end
|
7
12
|
|
8
13
|
def execute filename
|
9
14
|
filename += ".csv"
|
10
|
-
columns = @repository.columns
|
15
|
+
columns = @repository.columns - ['id']
|
11
16
|
CSV.open(filename, 'w') do |writer|
|
12
|
-
writer << columns
|
13
|
-
@repository.each do |card|
|
14
|
-
writer << columns.map {|column| card[column] ? card[column] : ''}
|
17
|
+
writer << (['id'] + columns)
|
18
|
+
@repository.cards.each do |card|
|
19
|
+
writer << ([card.id] + columns.map {|column| card[column] ? card[column] : ''})
|
15
20
|
end
|
16
21
|
end
|
17
22
|
end
|
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'cardigan/command/list_cards'
|
2
2
|
|
3
3
|
class Cardigan::Command::FilterCards < Cardigan::Command::ListCards
|
4
|
+
def initialize repository, io
|
5
|
+
super
|
6
|
+
@usage = '<ruby expression>'
|
7
|
+
@help = "Sets the filter on cards to be displayed\nThis filter is a ruby expression that must return a boolean.\nBound variables are card (a hash) and me (a string)"
|
8
|
+
end
|
9
|
+
|
4
10
|
def execute filter
|
5
11
|
@repository.filter = filter
|
6
12
|
begin
|
@@ -1,8 +1,14 @@
|
|
1
|
+
require 'cardigan/commands'
|
1
2
|
require 'csv'
|
3
|
+
require 'uuidtools'
|
2
4
|
|
3
5
|
class Cardigan::Command::ImportCards
|
6
|
+
attr_reader :usage, :help
|
7
|
+
|
4
8
|
def initialize repository, io
|
5
9
|
@repository, @io = repository, io
|
10
|
+
@usage = '<filename>'
|
11
|
+
@help = "Imports cards from the specific csv file.\nNote that if the file does not contain an id column, all new cards will be created.\nOtherwise, existing cards with a matching id will be updated."
|
6
12
|
end
|
7
13
|
|
8
14
|
def execute filename
|
@@ -14,14 +20,22 @@ class Cardigan::Command::ImportCards
|
|
14
20
|
header, id_index = nil, nil
|
15
21
|
CSV.open(filename, 'r') do |row|
|
16
22
|
if header
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
if id_index and row[id_index]
|
24
|
+
id = row[id_index]
|
25
|
+
card = @repository[id] if @repository.exist?(id)
|
26
|
+
end
|
27
|
+
if card
|
28
|
+
puts "updating #{id}"
|
29
|
+
else
|
30
|
+
id = UUIDTools::UUID.random_create.to_s
|
31
|
+
card = {}
|
32
|
+
puts "creating card #{id}"
|
33
|
+
end
|
20
34
|
editor = Cardigan::CardEditor.new(card, @io)
|
21
35
|
header.each_with_index do |field, index|
|
22
36
|
editor.set field, row[index]
|
23
37
|
end
|
24
|
-
@repository
|
38
|
+
@repository[id] = card
|
25
39
|
else
|
26
40
|
header = row
|
27
41
|
id_index = header.find_index('id')
|
@@ -1,8 +1,13 @@
|
|
1
|
+
require 'cardigan/commands'
|
1
2
|
require 'cardigan/text_report_formatter'
|
2
3
|
|
3
4
|
class Cardigan::Command::ListCards
|
5
|
+
attr_reader :usage, :help
|
6
|
+
|
4
7
|
def initialize repository, io
|
5
8
|
@repository, @io = repository, io
|
9
|
+
@usage = ''
|
10
|
+
@help = 'Lists all cards that match the current filter'
|
6
11
|
end
|
7
12
|
|
8
13
|
def execute text
|
@@ -1,17 +1,25 @@
|
|
1
1
|
require 'cardigan/entry_context'
|
2
|
+
require 'uuidtools'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
class OpenCard
|
6
|
-
def initialize repository, workflow_repository, io
|
7
|
-
@repository, @workflow_repository, @io = repository, workflow_repository, io
|
8
|
-
end
|
4
|
+
class Cardigan::Command::OpenCard
|
5
|
+
attr_reader :usage, :help
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
def initialize repository, workflow_repository, io
|
8
|
+
@repository, @workflow_repository, @io = repository, workflow_repository, io
|
9
|
+
@usage = '<card name>'
|
10
|
+
@help = 'Opens the specified card for editing'
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute name
|
14
|
+
entry = @repository.cards.find { |entry| entry['name'] == name }
|
15
|
+
id = entry ? entry.id : UUIDTools::UUID.random_create.to_s
|
16
|
+
entry ||= {'name' => name}
|
17
|
+
original = entry.dup
|
18
|
+
Cardigan::EntryContext.new(@io, @workflow_repository, entry).push
|
19
|
+
@repository[id] = entry unless original == entry
|
20
|
+
end
|
21
|
+
|
22
|
+
def completion text
|
23
|
+
@repository.cards.map {|card| card['name'] }.grep(/^#{Regexp.escape(text)}/).sort
|
16
24
|
end
|
17
25
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
+
require 'cardigan/commands'
|
1
2
|
require 'cardigan/workflow_context'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
class OpenWorkflow
|
6
|
-
def initialize workflow_repository, io
|
7
|
-
@workflow_repository, @io = workflow_repository, io
|
8
|
-
end
|
4
|
+
class Cardigan::Command::OpenWorkflow
|
5
|
+
attr_reader :usage, :help
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
def initialize workflow_repository, io
|
8
|
+
@workflow_repository, @io = workflow_repository, io
|
9
|
+
@usage = ''
|
10
|
+
@help = 'Opens the current workflow for editing'
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute name
|
14
|
+
workflow = @workflow_repository.load
|
15
|
+
original = workflow.dup
|
16
|
+
Cardigan::WorkflowContext.new(@io, workflow).push
|
17
|
+
@workflow_repository.save workflow unless workflow == original
|
16
18
|
end
|
17
19
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cardigan/commands'
|
2
|
+
|
3
|
+
class Cardigan::Command::RemoveTransitions
|
4
|
+
attr_reader :usage, :help
|
5
|
+
|
6
|
+
def initialize entry, io
|
7
|
+
@entry, @io = entry, io
|
8
|
+
@usage = '<start status> [<subsequent status>]+'
|
9
|
+
@help = 'Removes transitions from a starting status to a number of subsequent statuses'
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute text=nil
|
13
|
+
unless text and !text.empty?
|
14
|
+
@io.say 'missing required start status'
|
15
|
+
return
|
16
|
+
end
|
17
|
+
name, *states = text.scan(/\w+/)
|
18
|
+
if states.empty?
|
19
|
+
@io.say 'missing required subsequent status'
|
20
|
+
return
|
21
|
+
end
|
22
|
+
name, *states = text.scan(/\w+/)
|
23
|
+
@entry[name] -= states
|
24
|
+
end
|
25
|
+
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
module Command
|
3
|
-
class ShowEntry
|
4
|
-
def initialize entry, io
|
5
|
-
@entry, @io = entry, io
|
6
|
-
end
|
1
|
+
require 'cardigan/commands'
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
class Cardigan::Command::ShowEntry
|
4
|
+
attr_reader :usage, :help
|
5
|
+
|
6
|
+
def initialize entry, io
|
7
|
+
@entry, @io = entry, io
|
8
|
+
@usage = ''
|
9
|
+
@help = 'Shows the entire content of the entry'
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute ignored=nil
|
13
|
+
@entry.keys.sort.each { |key| @io.say "#{key}: #{@entry[key].inspect}" }
|
12
14
|
end
|
13
15
|
end
|
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'cardigan/command/list_cards'
|
2
2
|
|
3
3
|
class Cardigan::Command::SpecifyDisplayColumns < Cardigan::Command::ListCards
|
4
|
+
def initialize repository, io
|
5
|
+
super
|
6
|
+
@usage = '<column>*'
|
7
|
+
@help = 'Specify the list of columns to display'
|
8
|
+
end
|
9
|
+
|
4
10
|
def execute text
|
5
11
|
if text
|
6
12
|
@repository.display_columns = text.scan(/\w+/)
|
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'cardigan/command/list_cards'
|
2
2
|
|
3
3
|
class Cardigan::Command::SpecifySortColumns < Cardigan::Command::ListCards
|
4
|
+
def initialize repository, io
|
5
|
+
super
|
6
|
+
@usage = '<column>*'
|
7
|
+
@help = 'Specify the list of columns to sort by'
|
8
|
+
end
|
9
|
+
|
4
10
|
def execute text
|
5
11
|
if text
|
6
12
|
@repository.sort_columns = text.scan(/\w+/)
|
@@ -1,9 +1,13 @@
|
|
1
|
-
require 'cardigan/
|
1
|
+
require 'cardigan/commands'
|
2
2
|
require 'cardigan/text_report_formatter'
|
3
3
|
|
4
4
|
class Cardigan::Command::TotalCards
|
5
|
+
attr_reader :usage, :help
|
6
|
+
|
5
7
|
def initialize repository, io
|
6
8
|
@repository, @io = repository, io
|
9
|
+
@usage = '<numeric field> <grouping field>*'
|
10
|
+
@help = 'Calculates totals for the specified numeric field aggregated across the specified grouping fields'
|
7
11
|
end
|
8
12
|
|
9
13
|
def execute text=nil
|
@@ -13,7 +17,7 @@ class Cardigan::Command::TotalCards
|
|
13
17
|
return
|
14
18
|
end
|
15
19
|
counts = {}
|
16
|
-
@repository.each do |card|
|
20
|
+
@repository.cards.each do |card|
|
17
21
|
key = grouping_fields.map {|grouping_field| card[grouping_field] ? card[grouping_field] : ''}
|
18
22
|
value = card[count_field].to_i
|
19
23
|
counts[key] = counts[key] ? counts[key] + value : value
|