Tracker 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +0,0 @@
1
- require 'rubygems'
2
- require_gem 'activerecord'
3
-
4
- # Fields are bug_id (int), date (date), description (text).
5
- class BugDescription < ActiveRecord::Base
6
- belongs_to :bug
7
- before_save :save_date_time
8
- before_update :save_date_time
9
-
10
- private
11
- # Saves date_time as current time
12
- def save_date_time
13
- self.date_time = Time.now.to_s(:db)
14
- end
15
- end
@@ -1,44 +0,0 @@
1
- require "rubygems"
2
- require_gem "activerecord"
3
-
4
- # This module handles the connection to a database. There are only two methods, one to connect, one to create (connect_to_database and create_database, repsectively).
5
- module Database
6
-
7
- # This method should be called when starting the script to connect the program
8
- # to the database.
9
- def self.connect_to_database(database)
10
- # Start the script by connecting to the sqlite3 datbase
11
- ActiveRecord::Base.establish_connection(
12
- :adapter => "sqlite3",
13
- :database => database
14
- )
15
- end
16
-
17
- # If no database currently exists, this method will create one using
18
- # ActiveRecord's migrations
19
- def self.create_database(database)
20
- puts "Creating database '#{database}' in current directory..."
21
- connect_to_database(database)
22
-
23
- # Creates the bugs table
24
- ActiveRecord::Schema.define do
25
- create_table "bugs" do |t|
26
- t.column "name", :string
27
- t.column "priority", :int
28
- t.column "area", :string
29
- t.column "status", :boolean, :default => false
30
- t.column "date_time", :datetime
31
- end
32
- end
33
-
34
- # Creates the bug_descriptions
35
- ActiveRecord::Schema.define do
36
- create_table "bug_descriptions" do |t|
37
- t.column "bug_id", :int
38
- t.column "date_time", :datetime
39
- t.column "description", :text
40
- end
41
- end
42
- end
43
-
44
- end
@@ -1,16 +0,0 @@
1
- # This module includes static methods that do not fall into cateogries. These are just helper methods for various algorithms throughout the source code.
2
- module Helper
3
-
4
- # Takes a hash and returns the conditions sql for an ActiveRecord find method
5
- def self.hash_to_sql(hash)
6
- conditions = Array.new
7
- hash.each do |attribute, term|
8
- conditions << "#{attribute} = ?"
9
- end
10
- sql_string = conditions.join(" and ")
11
- sql = [sql_string]
12
- hash.each { |attribute, term| sql << term }
13
- return sql
14
- end
15
-
16
- end
@@ -1,175 +0,0 @@
1
- require File.dirname(__FILE__) + "/prompter.rb"
2
- require File.dirname(__FILE__) + "/database.rb"
3
- require File.dirname(__FILE__) + "/action.rb"
4
- require File.dirname(__FILE__) + "/bug.rb"
5
- require File.dirname(__FILE__) + "/bug_description.rb"
6
- require 'yaml'
7
-
8
- # The Interface's job is to act as the interface between the user and the Action module. The Interface will make sure that messages are outputted to the user and pass along actions to the Action module depending on whatever the command is.
9
- class Interface
10
-
11
- # Let the tracker interface have access to the bugger - controller
12
- def initialize()
13
- @filename = "trac"
14
- config = {}
15
- if File.exist?(ENV['HOME'] + "/.tracrc")
16
- config = open(ENV['HOME'] + '/.tracrc') { |f| YAML.load(f) }
17
- end
18
- @all_options = ["name", "priority", "area", "description"].delete_if { |i| config.has_key? i }
19
- end
20
-
21
- # Parses ARGV and executes the correct bugger operations
22
- # Will print out to the user whatever the user requested
23
- def parse_command(command_line_arguments)
24
- # Parse the command
25
- hash = args_to_hash(command_line_arguments)
26
- command = command_line_arguments[0]
27
- if command_line_arguments.size > 1 && command_line_arguments[1][0,1] != "-"
28
- get_name_or_id(command_line_arguments[1], hash)
29
- end
30
-
31
- # Perform the correct action for whatever command it is
32
- if command.include?("append") # Appends a description to existing bug
33
- hash = include_name_or_id(hash)
34
- hash[:description] = Prompter.description? if !hash.has_key?(:description)
35
- Action.append_description(hash)
36
- elsif command.include?("areas")
37
- puts "Searched ticket areas are:"
38
- Action.list_areas(hash).each { |area| puts " * " + area }
39
- elsif command.include?("names")
40
- puts "Searched ticket names are:"
41
- Action.list_names(hash).each { |name| puts " * " + name }
42
- elsif command.include?("close") # Closes an existing bug
43
- hash = include_name_or_id(hash)
44
- Action.close_bug(hash)
45
- elsif command.include?("delete") # Deletes the bug from the database
46
- hash = include_name_or_id(hash)
47
- Action.delete_bug(hash)
48
- elsif command.include?("list") # Lists either all open bugs or bugs by conditions
49
- bugs = Action.list_bugs(hash)
50
- puts bugs.collect { |bug| get_print_info(bug) }.join("\n") if bugs.size > 0
51
- elsif command.include?("new") # Creates a new bug
52
- set_options(@all_options, hash)
53
- Action.new_bug(hash)
54
- elsif command.include?("open") # Opens a closed bug
55
- hash = include_name_or_id(hash)
56
- Action.open_bug(hash)
57
- elsif command.include?("update")
58
- hash = include_name_or_id(hash)
59
- Action.update_bug(hash)
60
- elsif command.include?("help") || command.include?("--help") # Prints usage
61
- if !hash.has_key?(:name)
62
- print_usage
63
- elsif
64
- method_name = "help_" + hash[:name]
65
- if Action.respond_to?(method_name)
66
- Action.send(method_name)
67
- else
68
- puts "The command #{hash[:name]} doesn't exist - try 'trac help' for a list of commands."
69
- end
70
- end
71
- else
72
- puts "Try '#{@filename} help'."
73
- end
74
- end
75
-
76
-
77
- private
78
- # Changes ARGV into a hash, ie. trac --name NAME --priority 2 becomes {:name => "NAME", :priority => 2}
79
- def args_to_hash(args)
80
- hash = Hash.new
81
- hash[:id] = args[args.index("--id") + 1].to_i if args.include?("--id")
82
- hash[:id] = args[args.index("-i") + 1].to_i if args.include?("-i")
83
- hash[:name] = args[args.index("--name") + 1] if args.include?("--name")
84
- hash[:name] = args[args.index("-n") + 1] if args.include?("-n")
85
- hash[:priority] = args[args.index("--priority") + 1].to_i if args.include?("--priority")
86
- hash[:priority] = args[args.index("-p") + 1].to_i if args.include?("-p")
87
- hash[:area] = args[args.index("--area") + 1] if args.include?("--area")
88
- hash[:area] = args[args.index("-a") + 1] if args.include?("-a")
89
- hash[:description] = args[args.index("--description") + 1] if args.include?("--description")
90
- hash[:description] = args[args.index("-d") + 1] if args.include?("-d")
91
- hash[:status] = false if args.include?("--open") or args.include?("-o")
92
- hash[:status] = true if args.include?("--closed") or args.include?("-c")
93
- return hash
94
- end
95
-
96
- # Inspects the hash 'given' to see if it has the 'needed' keys. If it doesn't,
97
- # will prompt the user for items.
98
- def set_options(needed, given)
99
- needed.each do |item|
100
- if !given.has_key?(item.to_sym)
101
- given[item.to_sym] = Prompter.send(item+"?")
102
- end
103
- end
104
- return given
105
- end
106
-
107
- # If the given hash doesn't include an :id or :name key, prompts the user for
108
- # an :id key and inserts it into the hash
109
- def include_name_or_id(hash)
110
- return hash if hash.has_key?(:name) or hash.has_key?(:id)
111
- hash[:id] = Prompter.id?
112
- return hash
113
- end
114
-
115
- # Determines if a given argument is an id or name and includes it in a hash as
116
- # long as no other id or name was already included in the hash
117
- def get_name_or_id(name_or_id, hash = Hash.new)
118
- hash[:id] = name_or_id.to_i if name_or_id.to_i.kind_of?(Fixnum) && !hash.has_key?(:name) && name_or_id.to_i != 0
119
- hash[:name] = name_or_id if name_or_id.kind_of?(String) && !hash.has_key?(:id)
120
- return hash
121
- end
122
-
123
- # Returns the info for a bug to be printed out to the user
124
- def get_print_info(bug)
125
- working_string = String.new
126
- working_string << "Ticket(#{bug.id}): #{bug.name}\n" if bug.id < 10
127
- working_string << "Ticket(#{bug.id}): #{bug.name}\n" if bug.id >= 10 && bug.id < 100
128
- working_string << "Ticket(#{bug.id}): #{bug.name}\n" if bug.id >= 100
129
- working_string << "Priority: #{bug.priority}\n" unless bug.priority.nil?
130
- working_string << "Area: #{bug.area}\n" unless bug.area.nil?
131
- working_string << "Description - #{bug.date_time.to_s(:short)}:\n"
132
- descriptions = bug.bug_descriptions.collect { |desc| " * " + desc.description }.join
133
- working_string << descriptions
134
- return working_string
135
- end
136
-
137
- # Prints a description out
138
- def print_description(description)
139
- puts description.description # The description method
140
- puts "-"
141
- end
142
-
143
- # Tracker's usage
144
- def print_usage
145
- puts "usage: #{@filename} <command> [options] [-f DIRECTORY | DATABASE]"
146
- puts ""
147
- puts "Available commands:"
148
- puts " create"
149
- puts " append [-i ID | -n NAME | -d DESCRIPTION]"
150
- puts " close [-i ID | -n NAME]"
151
- puts " delete [-i ID | -n NAME]"
152
- puts " list [-i ID | -n NAME | -p PRIORITY | -a AREA | -c | -o]"
153
- puts " help [command]"
154
- puts " new [-n NAME | -p PRIORITY | -a AREA | -d DESCRIPTION]"
155
- puts " open [-i ID | -n NAME]"
156
- puts " update [-i ID | -n NAME | -p PRIORITY | -a AREA]"
157
- puts " areas [-n NAME | -p PRIORITY | -c | -o]"
158
- puts " names [-a AREA | -p PRIORITY | -c | -o]"
159
- puts ""
160
- puts "Available options:"
161
- puts " -i ID | --id ID"
162
- puts " -n NAME | --name NAME"
163
- puts " -p PRIORITY | --priority PRIORITY"
164
- puts " -a AREA | --area AREA"
165
- puts " -d DESCRIPTION | --description DESCRIPTION"
166
- puts " -c | --closed"
167
- puts " -o | --open"
168
- puts " -f FILE | --file FILE"
169
- puts ""
170
- puts "Tracker is a command-line client for a bugs/features database. The database is kept in a flat file '.tracker_db' in the current directory."
171
- puts ""
172
- puts "To create a '.tracker_db' file, try using '#{@filename} create'."
173
- end
174
-
175
- end
@@ -1,66 +0,0 @@
1
- # Prompts the user for information. All prompts are contained into this class. All methods are class methods.
2
- class Prompter
3
-
4
- # Asks for id
5
- def self.id?
6
- self.int("id")
7
- end
8
-
9
- # Asks for area
10
- def self.area?
11
- self.string("area")
12
- end
13
-
14
- # Ask for priority - int
15
- def self.priority?
16
- self.int("priority")
17
- end
18
-
19
- # Asks for a name
20
- def self.name?
21
- self.string("name")
22
- end
23
-
24
- # Asks for description. Terminate with ^d on empty line.
25
- def self.description?
26
- self.text("description")
27
- end
28
-
29
- private
30
- # Prompt for a string
31
- def self.string(term)
32
- print term.capitalize + ": "
33
- STDIN.gets.gsub("\n", "")
34
- end
35
-
36
- # Prompt for an int
37
- def self.int(term)
38
- print term.capitalize + ": "
39
- STDIN.gets.to_i
40
- end
41
-
42
- # Prompt for text. Terminate with ^d on empty line.
43
- def self.text(term)
44
- # Create the method
45
- puts term.capitalize + ":"
46
- text = String.new
47
- string = STDIN.gets
48
- while string
49
- text += string
50
- string = STDIN.gets
51
- end
52
- return text
53
- end
54
-
55
- # Prompt for a yes or no.
56
- def self.boolean(term)
57
- print term.capitalize + ": "
58
- string = STDIN.gets
59
- if string.include?("Y") || string.include?("y")
60
- return true
61
- else
62
- return false
63
- end
64
- end
65
-
66
- end
@@ -1,147 +0,0 @@
1
- require "test/unit"
2
-
3
- require File.dirname(__FILE__) + "/../lib/action.rb"
4
- require File.dirname(__FILE__) + "/../lib/database.rb"
5
- require File.dirname(__FILE__) + "/../lib/bug_description.rb"
6
-
7
- class TestAction < Test::Unit::TestCase
8
- def setup
9
- Database::connect_to_database(".tracker_db")
10
- @bug_names = ["First", "Second", "Third", "Fourth"]
11
- @bug_ids = [1, 2, 3, 4]
12
- @bug_priorities = [1, 2, 3, 4]
13
- @bug_areas = ["One", "Two", "Three", "Four"]
14
- @bug_status = [true, true, false, false]
15
- @descriptions =
16
- ["First description", "Second description", "Third description"]
17
- end
18
-
19
- def teardown
20
- # Delete all bugs that aren't in the migration
21
- bugs = Bug.find(:all)
22
- bugs.delete_if { |bug| @bug_ids.include?(bug.id) }
23
- bugs.each { |bug| bug.destroy }
24
- end
25
-
26
- def test_append_description
27
- bug = Bug.create(:name => "test_append_description",
28
- :priority => 1, :area => "none")
29
- Action.append_description(:id => bug.id, :description => "Hello")
30
- Action.append_description(:name => "test_append_description",
31
- :description => "World")
32
- assert_equal(bug.bug_descriptions[0].description, "Hello")
33
- assert_equal(bug.bug_descriptions[1].description, "World")
34
- end
35
-
36
- # An empty description should NOT be appened.
37
- def test_append_description_that_is_empty
38
- bug = Bug.create(:name => "test_append_empty_description",
39
- :priority => 1, :area => "none")
40
- descriptions_to_test = ["", " ", " ", "\n", "\n\n", " \n ", "\n ", " \n"]
41
- descriptions_to_test.each do |string|
42
- Action.append_description(:name => "test_append_empty_description",
43
- :description => string)
44
- end
45
- bug = Bug.find(bug.id)
46
- assert_equal(0, bug.bug_descriptions.size)
47
- end
48
-
49
- def test_close_bug
50
- bug = Bug.find_by_status(false)
51
- Action.close_bug(:id => bug.id)
52
- bug = Bug.find_by_id(bug.id)
53
- assert(bug.closed?)
54
- bug.status = false
55
- bug.save
56
- end
57
-
58
- def test_delete_bug
59
- bug = Bug.create(:name => "test_delete_bug",
60
- :priority => 2, :area => "none")
61
- Action.delete_bug(:name => "test_delete_bug")
62
- assert(!Bug.find_by_name("test_delete_bug"))
63
- end
64
-
65
- def test_list_bugs
66
- bugs = Action.list_bugs
67
- bugs.each { |bug| assert(@bug_names.include?(bug.name)) }
68
- bugs = Action.list_bugs(:name => "First")
69
- assert_equal(0, bugs.size)
70
- bugs = Action.list_bugs(:status => false)
71
- assert_equal(2, bugs.size)
72
- end
73
-
74
- # Make sure the listed bugs with a condition are ALL opened
75
- def test_open_list_bugs
76
- first = Bug.create(:name => "Another open bug", :area => "Four")
77
- second = Bug.create(:name => "Another closed bug",
78
- :area => "Four", :status => true)
79
- bugs = Action.list_bugs(:area => "Four")
80
- bugs.each { |bug| assert(bug.open?) }
81
- end
82
-
83
- def test_new_bug
84
- bug = Action.new_bug(:name => "test_new_bug",
85
- :priority => 1, :area => "none",
86
- :description => "This is a test description")
87
- assert(bug)
88
- assert(Bug.find_by_name("test_new_bug"))
89
- assert_equal(Bug.find_by_name("test_new_bug").name, "test_new_bug")
90
- assert_equal(bug.bug_descriptions[0].description,
91
- "This is a test description")
92
- end
93
-
94
- def test_open_bug
95
- bug = Bug.find_by_status(true)
96
- Action.open_bug(:id => bug.id)
97
- bug = Bug.find_by_id(bug.id)
98
- assert(bug.open?)
99
- bug.status = true
100
- bug.save
101
- end
102
-
103
- def test_update_bug
104
- bug = Bug.create(:name => "test_update_bug",
105
- :priority => 1, :area => "none")
106
- assert(bug)
107
- Action.update_bug(:id => bug.id, :name => "new_name",
108
- :priority => 2, :area => "Nothing")
109
- bug = Bug.find_by_id(bug.id)
110
- assert_equal("new_name", bug.name)
111
- assert_equal("Nothing", bug.area)
112
- assert_equal(2, bug.priority)
113
- end
114
-
115
- # Should list all _open_ areas
116
- def test_list_areas
117
- areas = Action.list_areas
118
- known_areas = ["Four", "Three"]
119
- areas.each { |area| assert(known_areas.include?(area)) }
120
- end
121
-
122
- # Should list all bug areas with the condition given
123
- def test_list_areas_with_conditions
124
- areas = Action.list_areas(:name => "Fourth")
125
- assert_equal("Four", areas[0])
126
- areas = Action.list_areas(:priority => 3)
127
- assert_equal("Three", areas[0])
128
- end
129
-
130
- # Should list all _open_ bug names
131
- def test_list_names
132
- names = Action.list_names
133
- known_names = ["Fourth", "Third"]
134
- names.each { |name| assert(known_names.include?(name)) }
135
- end
136
-
137
- # Should list all _open_ bug names with the conditions given
138
- def test_list_names_with_conditions
139
- names = Action.list_names(:name => "Third")
140
- assert_equal("Third", names[0])
141
- names = Action.list_names(:priority => 2)
142
- assert_equal(nil, names[0])
143
- names = Action.list_names(:priority => 2, :status => true)
144
- assert_equal("Second", names[0])
145
- end
146
-
147
- end