cardigan 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -25,15 +25,20 @@ The commands available are (with the awesome power of tab completion):
25
25
  * quit
26
26
  * exit
27
27
  * list - shows all cards
28
- * list <filter> - shows a subset of cards. Filter is some ruby code such as card[:name].start_with?('a')
29
- * edit <name> - creates a card and enters edit mode
28
+ * filter <filter> - sets the filter for cards - this is ruby code such as card[:name].start_with?('a')
29
+ * claim <name> - sets the owner of the card
30
+ * unclaim <name> - removes the card owner
31
+ * create <name> - creates a card with the specified name
32
+ * open <name> - creates or opens the card and enters edit mode
33
+ * columns - changes the list of columns to be displayed
34
+ * destroy <numbers> - deletes the specified cards (by index number from the list view)
30
35
 
31
36
  == Editing mode
32
37
 
33
38
  * quit
34
39
  * exit
35
40
  * set <key> - creates a new key and prompts for the new value
36
-
41
+
37
42
  == Future plans
38
43
 
39
44
  Refer to the .cards for detailed story breakdown but mostly importing, exporting and generating pretty html reports/charts.
data/lib/cardigan/cli.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'cardigan/io'
2
2
  require 'cardigan/root_context'
3
- require 'cardigan/directory'
3
+ require 'cardigan/repository'
4
4
 
5
5
  module Cardigan
6
6
  class Cli
@@ -20,7 +20,8 @@ module Cardigan
20
20
  }
21
21
  @home.store CONFIG_FILE, config
22
22
  end
23
- RootContext.new(@io, Directory.new('.cards')).push
23
+ name = "\"#{config[:name]}\" <#{config[:email]}>"
24
+ RootContext.new(@io, Repository.new('.cards'), name).push
24
25
  end
25
26
  end
26
27
  end
@@ -19,6 +19,10 @@ module Cardigan
19
19
  File.open(File.join(@path, file), 'w') {|f| f.print hash.to_yaml}
20
20
  end
21
21
 
22
+ def delete file
23
+ FileUtils.rm File.join(@path, file)
24
+ end
25
+
22
26
  def create
23
27
  FileUtils.mkdir_p @path
24
28
  end
@@ -6,12 +6,12 @@ module Cardigan
6
6
 
7
7
  def initialize io, entry
8
8
  @io, @entry = io, entry
9
- @prompt_text = "c/#{entry[:name]} > "
9
+ @prompt_text = "#{File.expand_path('.').split('/').last.slice(0..1)}/#{entry['name']} > "
10
10
  @commands = ['set']
11
11
  end
12
-
12
+
13
13
  def set_command key
14
- @entry[:text] = @io.ask("Enter the new value for #{key}")
14
+ @entry[key] = @io.ask("Enter the new value for #{key}")
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,35 @@
1
+ require 'cardigan/directory'
2
+
3
+ module Cardigan
4
+ class Repository
5
+ attr_reader :cards
6
+
7
+ def initialize path
8
+ @directory = Directory.new(path)
9
+ @directory.create
10
+ end
11
+
12
+ def refresh
13
+ @cards = @directory.find('*.card')
14
+ end
15
+
16
+ def find_card name
17
+ @cards.find {|card| card['name'] == name}
18
+ end
19
+
20
+ def save card
21
+ @directory.store "#{card['id']}.card", card
22
+ end
23
+
24
+ def destroy card
25
+ @directory.delete "#{card['id']}.card"
26
+ end
27
+
28
+ def find_or_create name
29
+ card = find_card(name)
30
+ card or { 'id' => UUIDTools::UUID.random_create.to_s,
31
+ 'name' => name
32
+ }
33
+ end
34
+ end
35
+ end
@@ -2,38 +2,105 @@ require 'rubygems'
2
2
  require 'uuidtools'
3
3
  require 'cardigan/context'
4
4
  require 'cardigan/entry_context'
5
+ require 'cardigan/text_report_formatter'
5
6
 
6
7
  module Cardigan
7
8
  class RootContext
8
9
  include Context
9
10
 
10
- def initialize io, directory
11
- @io, @directory = io, directory
12
- @directory.create
13
- @prompt_text = 'cardigan > '
11
+ def initialize io, repository, name
12
+ @io, @repository, @name = io, repository, name
13
+ @prompt_text = "#{File.expand_path('.').split('/').last} > "
14
+ @columns = ['name']
14
15
  end
15
-
16
+
16
17
  def refresh_commands
17
- @cards = @directory.find('*.card')
18
- @commands = ['edit', 'list']
19
- @cards.each do |card|
20
- @commands << "edit #{card[:name]}"
18
+ @repository.refresh
19
+ @commands = ['create', 'list', 'filter', 'unfilter', 'columns']
20
+ @repository.cards.each do |card|
21
+ @commands << "open #{card['name']}"
22
+ @commands << "destroy #{card['name']}"
23
+ if card['owner'] == @name
24
+ @commands << "unclaim #{card['name']}"
25
+ else
26
+ @commands << "claim #{card['name']}"
27
+ end
21
28
  end
22
29
  end
23
30
 
24
- def edit_command text
25
- card = @cards.find {|card| card[:name] == text}
26
- card ||= { :id => UUIDTools::UUID.random_create.to_s,
27
- :name => text
28
- }
31
+ def create_command name
32
+ @repository.save @repository.find_or_create(name)
33
+ end
34
+
35
+ def open_command text
36
+ card = @repository.find_or_create(name)
29
37
  EntryContext.new(@io, card).push
30
- @directory.store "#{card[:id]}.card", card
38
+ @repository.save card
39
+ end
40
+
41
+ def destroy_command text
42
+ cards = sorted_selection
43
+ text.scan(/\d+/).each do |n|
44
+ card = cards[n.to_i - 1]
45
+ @io.say "destroying \"#{card['name']}\""
46
+ @repository.destroy card
47
+ end
31
48
  end
32
49
 
33
- def list_command text=nil
34
- cards = text ? @cards.select {|card| eval text } : @cards
35
- @io.say "\n#{cards.count} cards"
36
- cards.map {|card| card[:name] }.sort.each {|name| @io.say name }
50
+ def list_command ignored
51
+ cards = sorted_selection
52
+ formatter = TextReportFormatter.new @io
53
+ a = 0
54
+ @columns.each do |column|
55
+ formatter.add_column(column, max_field_length(cards, column))
56
+ end
57
+ formatter.output cards
58
+ end
59
+
60
+ def unfilter_command ignored
61
+ @filter = nil
62
+ end
63
+
64
+ def columns_command text
65
+ @columns = text.split(',') if text
66
+ end
67
+
68
+ def filter_command code
69
+ @filter = code
70
+ begin
71
+ cards = @repository.cards.select {|card| eval @filter }
72
+ @io.say "#{cards.count} cards match filter"
73
+ rescue Exception => e
74
+ @io.say "Invalid expression:\n#{e.message}"
75
+ @filter = nil
76
+ end
77
+ end
78
+
79
+ def claim_command name
80
+ set_key name, 'owner', @name
81
+ end
82
+
83
+ def unclaim_command name
84
+ set_key name, 'owner', nil
85
+ end
86
+ private
87
+ def max_field_length cards, name
88
+ cards.map {|v| v[name] ? v[name].length : 0 }.max
89
+ end
90
+
91
+ def sorted_selection
92
+ cards = @filter ? @repository.cards.select {|card| eval @filter } : @repository.cards
93
+ cards.sort {|a,b| a['name'] <=> b['name'] }
94
+ end
95
+
96
+ def set_key name, key, value
97
+ card = @repository.find_card(name)
98
+ if card
99
+ card[key] = value
100
+ @repository.save card
101
+ else
102
+ @io.say "unknown card #{text}"
103
+ end
37
104
  end
38
105
  end
39
106
  end
@@ -0,0 +1,38 @@
1
+ module Cardigan
2
+ class TextReportFormatter
3
+ def initialize io
4
+ @io = io
5
+ @columns = []
6
+ @heading = 'index'
7
+ @width = 2 + @heading.length + 1
8
+ end
9
+
10
+ def add_column name, length
11
+ longer = [name.length, length].max
12
+ @columns << [name, longer]
13
+ @width += longer + 3
14
+ end
15
+
16
+ def output hashes
17
+ hline
18
+ row 'index', @columns.map {|tuple| tuple.first }
19
+ hline
20
+ hashes.each_with_index do |h,i|
21
+ row i.to_s, @columns.map {|tuple| h[tuple.first]}
22
+ end
23
+ hline
24
+ end
25
+ private
26
+ def hline
27
+ @io.say ' ' + '-' * @width
28
+ end
29
+
30
+ def row first, values
31
+ a = "| #{first.ljust(@heading.length)} | "
32
+ @columns.each_with_index do |tuple, index|
33
+ a << " #{values[index].to_s.ljust(tuple[1])} |"
34
+ end
35
+ @io.say a
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cardigan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Ryall
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-10 00:00:00 +11:00
12
+ date: 2010-03-12 00:00:00 +11:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -68,7 +68,9 @@ files:
68
68
  - lib/cardigan/directory.rb
69
69
  - lib/cardigan/entry_context.rb
70
70
  - lib/cardigan/io.rb
71
+ - lib/cardigan/repository.rb
71
72
  - lib/cardigan/root_context.rb
73
+ - lib/cardigan/text_report_formatter.rb
72
74
  - bin/cardigan
73
75
  - README.rdoc
74
76
  - MIT-LICENSE