beastie 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/README.textile +66 -5
- data/lib/beastie/issue.rb +53 -35
- data/lib/beastie/project_list.rb +24 -0
- data/lib/beastie/version.rb +1 -1
- data/lib/beastie.rb +108 -60
- data/test/test_project_list.rb +47 -0
- metadata +14 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f24bc36744a8be167db9a4331e94ecabcab1554
|
4
|
+
data.tar.gz: dd0690cf2c6cf69b88a7db87ec05dc5d6084eaa7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a1650acd6767af4d3eeef5e74e71da0024732badab0d388493bd8540f6805418993139db9025621a2e2252e97369eede0429b6012d765e9558585578440f178
|
7
|
+
data.tar.gz: 7ecedb24b9f338fe7ebe4b546dd3df8742b94e231855614ef62e782ad46c5c265cd0e1107f364aff017bd8180b2d411ffbf49fdbfdee95dc8b4e1d6a7d61cc69
|
data/README.textile
CHANGED
@@ -40,11 +40,56 @@ Main commands:
|
|
40
40
|
|
41
41
|
- @beastie help@ := unleashes the real power of @beastie@.
|
42
42
|
|
43
|
-
h2.
|
43
|
+
h2. Managing Different Projects
|
44
44
|
|
45
|
-
|
45
|
+
By default @beastie@ uses the *current directory* when executing a command. While this makes gives a lot of freedom in choosing one's standards, it also require a lot of discipline (you always need to make sure you are in the right directory) and can be inconvenient at times.
|
46
46
|
|
47
|
-
|
47
|
+
For this reason, from version 0.3, @beastie@ supports the following two options to specify the directory to use when executing a command:
|
48
|
+
|
49
|
+
* option @-d@ (@--directory@) to specify the destination directory
|
50
|
+
* option @-p@ (@--project@) to use a specific project for a directory
|
51
|
+
|
52
|
+
*Option @-d@.* Use @-d <dir>@ (or @--directory <dir>@) to specify the directory in which the command is executed.
|
53
|
+
|
54
|
+
For instance:
|
55
|
+
|
56
|
+
<pre>
|
57
|
+
beastie -d ~/issues show
|
58
|
+
</pre>
|
59
|
+
|
60
|
+
will show all issues stored in the @~/issue@ directory.
|
61
|
+
|
62
|
+
*Option @-p@.* Use @-p <name>@ (or @--project <name>@) to specify the name of a project and @beastie@ will perform the operation on the directory associated to @<name>@ in the @~/.beastie_projects@ file.
|
63
|
+
|
64
|
+
Entries in the @.beastie_projects@ file look like:
|
65
|
+
|
66
|
+
<pre>
|
67
|
+
<name>:
|
68
|
+
dir: <dir>
|
69
|
+
<another name>:
|
70
|
+
dir: <another dir>
|
71
|
+
</pre>
|
72
|
+
|
73
|
+
For instance, if @.beastie_projects@ contains:
|
74
|
+
|
75
|
+
<pre>
|
76
|
+
beastie:
|
77
|
+
dir: /Users/guest/beastie_issues
|
78
|
+
</pre>
|
79
|
+
|
80
|
+
then
|
81
|
+
|
82
|
+
<pre>
|
83
|
+
$ beastie -p beastie show
|
84
|
+
</pre>
|
85
|
+
|
86
|
+
will show all the issues stored in the @/Users/guest/beastie_issues@ directory.
|
87
|
+
|
88
|
+
Use only one of @-d@ or @-p@; if you do not, @-d@ has precedence.
|
89
|
+
|
90
|
+
h2. Remarks and Warnings
|
91
|
+
|
92
|
+
Beastie generates human-readable filenames, following the convention "Jekyll":http://jekyllrb.com has for blog posts. Selecting issues using filenames, however, is a bit clumsy and to simplify operations @beastie@ assigns a number to each issue, which can be used to reference them. The number can be seen with the @list@ command and depends upon the order in which issues are listed in the directory. Thus *the same issue might be assigned a different id over time*, if the order in which files are read changes (e.g., if a new back-dated issue is added by hand).
|
48
93
|
|
49
94
|
Beastie does not have a specific workflow for bug statutes.
|
50
95
|
|
@@ -52,17 +97,33 @@ Beastie does not perform syntax checks when reading data. This can be changed b
|
|
52
97
|
|
53
98
|
Beastie asks various information about a bug. Change the @ISSUE_FIELDS@ variable, if you are not happy with the default fieldset.
|
54
99
|
|
100
|
+
Beastie does not have fancy sorting and filtering functions. The unix commands @sort@ and @grep@ can be reasonable work-arounds. For instance the list of open bugs can be gotten with:
|
101
|
+
|
102
|
+
<pre>
|
103
|
+
beastie list | grep open
|
104
|
+
</pre>
|
105
|
+
|
106
|
+
To sort issues by priority:
|
107
|
+
|
108
|
+
<pre>
|
109
|
+
beastie list | grep -v "^ID" | sort -n -k 4
|
110
|
+
</pre>
|
111
|
+
|
112
|
+
Exceptions apply.
|
113
|
+
|
55
114
|
|
56
115
|
h2. Similar solutions
|
57
116
|
|
58
117
|
There are different command-line bug tracking systems. The ones I came across with before re-inventing the wheel include: ditz, "bugs everywhere":http://bugseverywhere.org, "ticgit-Ng":https://github.com/jeffWelling/ticgit, "bugzyrb":https://github.com/rkumar/bugzyrb, "git-issues":https://github.com/duplys/git-issues, "later":https://github.com/qznc/later.
|
59
118
|
|
60
|
-
|
119
|
+
So... why did I re-invent the wheel?
|
61
120
|
|
62
121
|
# for fun
|
63
122
|
# human-readable filenames, so that I can manage issues without using beastie, if I want
|
64
123
|
# a "programmable" fieldset (see @lib/beastie/issue.rb@)
|
65
|
-
# keeping the solution simple
|
124
|
+
# keeping the solution simple (280 lines of ruby code, according to @sloccount@)
|
125
|
+
|
126
|
+
Use @beastie@! According to @sloccount@, you using a software which costed $8,033! (... as you might guess, COCOMO does not work well for small systems.)
|
66
127
|
|
67
128
|
h2. Author
|
68
129
|
|
data/lib/beastie/issue.rb
CHANGED
@@ -35,7 +35,8 @@ module Beastie
|
|
35
35
|
# * "prompt" is what is asked to the user. Use an empty string for
|
36
36
|
# a value which is filled automatically.
|
37
37
|
#
|
38
|
-
# input function and default value are evaluated, so that computation can
|
38
|
+
# input function and default value are evaluated, so that computation can
|
39
|
+
# be performed
|
39
40
|
#
|
40
41
|
# - title, created, and status are compulsory: do not delete them
|
41
42
|
# (gen_filename depends upon title and created; the close
|
@@ -67,12 +68,18 @@ module Beastie
|
|
67
68
|
"title" => "%-30s"
|
68
69
|
}
|
69
70
|
|
70
|
-
#
|
71
|
-
attr_reader :
|
72
|
-
|
71
|
+
# the directory where all issues of this instance are stored
|
72
|
+
attr_reader :dir
|
73
|
+
|
74
|
+
# the filename of this issue.
|
75
|
+
# IT IS ALWAYS A BASENAME. @dir is added only when needed (e.g. load)
|
73
76
|
attr_reader :filename
|
74
77
|
|
75
|
-
|
78
|
+
# the values (a Hash) of this issue
|
79
|
+
attr_reader :issue
|
80
|
+
|
81
|
+
def initialize directory
|
82
|
+
@dir = directory
|
76
83
|
@issue = Hash.new
|
77
84
|
end
|
78
85
|
|
@@ -84,40 +91,57 @@ module Beastie
|
|
84
91
|
end
|
85
92
|
end
|
86
93
|
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
94
|
+
# initialize all fields with the default values
|
95
|
+
# (and set title to the argument)
|
96
|
+
def set_fields title
|
97
|
+
ISSUE_FIELDS.keys.each do |k|
|
98
|
+
@issue[k] = eval(ISSUE_FIELDS[k][DEFAULT])
|
99
|
+
end
|
100
|
+
@issue['title'] = title
|
91
101
|
end
|
92
102
|
|
93
103
|
def change field, value
|
94
104
|
@issue[field] = value
|
95
105
|
end
|
96
106
|
|
107
|
+
# load from command line
|
108
|
+
def load filename
|
109
|
+
@filename = File.basename(filename)
|
110
|
+
@issue = YAML.load_file(File.join(@dir, @filename))
|
111
|
+
end
|
112
|
+
|
113
|
+
# load by issue id
|
114
|
+
# @dir must be set, which is always the case because of
|
115
|
+
# the constructor
|
116
|
+
def load_n n
|
117
|
+
load id_to_full_filename n
|
118
|
+
end
|
119
|
+
|
120
|
+
def id_to_full_filename n
|
121
|
+
Dir.glob(File.join(@dir, '*.{yml,yaml}'))[n - 1]
|
122
|
+
end
|
123
|
+
|
124
|
+
# return the full filename, if @filename is set
|
125
|
+
# (load, save, ...)
|
126
|
+
def full_filename
|
127
|
+
File.join(@dir, @filename)
|
128
|
+
end
|
129
|
+
|
97
130
|
# save object to file
|
98
131
|
def save
|
99
132
|
@filename = @filename || gen_filename
|
100
|
-
|
101
|
-
file = File.open(@filename, 'w') { |f|
|
133
|
+
file = File.open(File.join(@dir, @filename), 'w') { |f|
|
102
134
|
f.puts @issue.to_yaml
|
103
135
|
}
|
104
|
-
|
105
|
-
puts "Issue saved to #{filename}"
|
106
|
-
end
|
107
|
-
|
108
|
-
# return the n-th filename
|
109
|
-
def self.filename n
|
110
|
-
Dir.glob('*.{yml,yaml}')[n - 1]
|
111
136
|
end
|
112
137
|
|
113
|
-
# count all issues in current directory
|
114
|
-
|
115
|
-
|
116
|
-
Dir.glob('*.{yml,yaml}').size
|
138
|
+
# count all issues in current directory to get the maximum ID
|
139
|
+
def count
|
140
|
+
Dir.glob(File.join(@dir, '*.{yml,yaml}')).size
|
117
141
|
end
|
118
142
|
|
119
143
|
# list all issues in current directory
|
120
|
-
def
|
144
|
+
def list
|
121
145
|
# print header
|
122
146
|
printf "ID "
|
123
147
|
REPORT_FIELDS.keys.each do |key|
|
@@ -127,7 +151,7 @@ module Beastie
|
|
127
151
|
|
128
152
|
# print issues
|
129
153
|
file_no = 0
|
130
|
-
Dir.glob('*.{yml,yaml}') do |file|
|
154
|
+
Dir.glob(File.join(@dir, '*.{yml,yaml}')) do |file|
|
131
155
|
data = YAML.load_file(file)
|
132
156
|
file_no += 1
|
133
157
|
|
@@ -139,15 +163,6 @@ module Beastie
|
|
139
163
|
end
|
140
164
|
end
|
141
165
|
|
142
|
-
# initialize all fields with the default values
|
143
|
-
# (and set title to the argument)
|
144
|
-
def set_fields title
|
145
|
-
ISSUE_FIELDS.keys.each do |k|
|
146
|
-
@issue[k] = eval(ISSUE_FIELDS[k][DEFAULT])
|
147
|
-
end
|
148
|
-
@issue['title'] = title
|
149
|
-
end
|
150
|
-
|
151
166
|
private
|
152
167
|
|
153
168
|
# read n-lines (terminated by a ".")
|
@@ -161,13 +176,16 @@ module Beastie
|
|
161
176
|
gets.chomp.to_i
|
162
177
|
end
|
163
178
|
|
164
|
-
#
|
179
|
+
# generate a unique filename for this issue
|
180
|
+
#
|
181
|
+
# (notice that @dir is prepended, to make sure it is unique
|
182
|
+
# in the right directory)
|
165
183
|
def gen_filename
|
166
184
|
name = @issue["created"].strftime("%Y-%m-%d-") +
|
167
185
|
@issue["title"].gsub(/\W+/, "_") +
|
168
186
|
".yaml"
|
169
187
|
n = 1
|
170
|
-
while File.exist?(name)
|
188
|
+
while File.exist?(File.join(@dir, name))
|
171
189
|
name = File.basename(name, ".yaml") + "-" + n.to_s + ".yaml"
|
172
190
|
n += 1
|
173
191
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Beastie
|
4
|
+
class ProjectList
|
5
|
+
PROJECT_FILE="#{Dir.home}/.beastie_projects"
|
6
|
+
|
7
|
+
def self.project_dir project_name
|
8
|
+
projects = read
|
9
|
+
|
10
|
+
if projects and projects[project_name]
|
11
|
+
projects[project_name]["dir"]
|
12
|
+
else
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def self.read
|
20
|
+
File.exists?(PROJECT_FILE) ? YAML.load_file(PROJECT_FILE) : nil
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/lib/beastie/version.rb
CHANGED
data/lib/beastie.rb
CHANGED
@@ -3,41 +3,53 @@ require 'optparse'
|
|
3
3
|
|
4
4
|
require_relative "beastie/version"
|
5
5
|
require_relative "beastie/issue"
|
6
|
+
require_relative "beastie/project_list"
|
6
7
|
|
7
8
|
module Beastie
|
8
9
|
|
9
|
-
#
|
10
|
+
# add an option to optparser to accept an existing pathname as option
|
10
11
|
OptionParser.accept(Pathname) do |pn|
|
11
12
|
Pathname.new(pn) if pn
|
12
13
|
raise OptionParser::InvalidArgument, pn if not Dir.exist?(pn)
|
13
14
|
end
|
14
15
|
|
15
|
-
# Bestie manages issues from the command line.
|
16
|
-
# Each issue is a text file in YAML, whose name is Jekyll-post like: DATE-TITLE.yml
|
17
|
-
#
|
18
|
-
# Two simple commands
|
19
|
-
# - beastie new (create a new issue in the current directory
|
20
|
-
# - beastie list (list relevant firelds of issues stored in the current directory)
|
21
|
-
|
22
16
|
class Runner
|
23
17
|
# the editor to use with the edit command
|
24
18
|
EDITOR = "emacsclient"
|
25
19
|
|
26
20
|
def self.run(args)
|
27
21
|
|
28
|
-
#
|
22
|
+
# default directory is ".", unless -p is specified
|
23
|
+
dir = "."
|
24
|
+
OptionParser.new do |opts|
|
25
|
+
opts.on("-p", "--project name", String,
|
26
|
+
"Use project's dir for operations") do |name|
|
27
|
+
dir = ProjectList.project_dir name
|
28
|
+
|
29
|
+
if dir == nil then
|
30
|
+
puts "beastie error: nothing known about project #{name}.\n"
|
31
|
+
puts ""
|
32
|
+
puts "add the following lines to #{ProjectList::PROJECT_FILE}"
|
33
|
+
puts ""
|
34
|
+
puts "#{name}:"
|
35
|
+
puts " dir: <directory where #{name} issues live>"
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-d", "--directory name", String,
|
41
|
+
"Use this directory for operations") do |name|
|
42
|
+
dir = name
|
43
|
+
end
|
44
|
+
end.order!.parse!
|
45
|
+
|
46
|
+
if not Dir.exists?(dir)
|
47
|
+
puts "beastie error: the directory does not exist"
|
48
|
+
puts ""
|
49
|
+
puts "if you used -p, please check the #{ProjectList::PROJECT_FILE} file"
|
50
|
+
exit 1
|
51
|
+
end
|
29
52
|
|
30
|
-
# global_options = OptionParser.new do |opts|
|
31
|
-
# opts.banner = "Usage: beastie [global options] <command> [[command options] <args>]"
|
32
|
-
|
33
|
-
# # Mandatory argument.
|
34
|
-
# opts.on("-d", "--directory DIR", Pathname,
|
35
|
-
# "Use DIR as the directory to store (and retrieve) issues") do |dir|
|
36
|
-
# options[:dir] = dir
|
37
|
-
# end
|
38
|
-
# end
|
39
|
-
|
40
|
-
# global_options.order!
|
41
53
|
command = args[0]
|
42
54
|
args.shift
|
43
55
|
|
@@ -50,50 +62,53 @@ module Beastie
|
|
50
62
|
exit 1
|
51
63
|
end
|
52
64
|
|
53
|
-
issue = Issue.new
|
65
|
+
issue = Issue.new dir
|
54
66
|
issue.ask
|
55
67
|
issue.save
|
56
|
-
|
57
|
-
when "edit"
|
58
|
-
if args.size != 1 or not digits_only(args[0]) or args[0].to_i > Issue.count
|
59
|
-
puts "beastie error: please specify an issue.\n\n"
|
60
|
-
help
|
61
|
-
exit 1
|
62
|
-
end
|
63
|
-
|
64
|
-
issue_no = args[0].to_i
|
65
|
-
shell_editor = `echo ${EDITOR}`.chomp
|
66
|
-
editor = shell_editor == "" ? EDITOR : shell_editor
|
67
|
-
system("#{editor} #{Issue.filename issue_no}")
|
68
|
+
puts "Issue saved to #{issue.full_filename}."
|
68
69
|
|
69
70
|
when "nedit"
|
70
71
|
title = args.join(" ") # get all arguments (so that no " are necessary)
|
72
|
+
|
71
73
|
if title == ""
|
72
74
|
puts "beastie error: please specify the title of the issue.\n"
|
73
75
|
help
|
74
76
|
exit 1
|
75
77
|
end
|
76
78
|
|
77
|
-
issue = Issue.new
|
79
|
+
issue = Issue.new dir
|
78
80
|
issue.set_fields title
|
79
81
|
issue.save
|
82
|
+
system("#{editor_cmd} #{issue.full_filename}")
|
80
83
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
+
when "edit"
|
85
|
+
issue = Issue.new dir
|
86
|
+
|
87
|
+
if args.size != 1 or not digits_only(args[0]) or args[0].to_i > issue.count
|
88
|
+
puts "beastie error: please specify a valid identifier.\n\n"
|
89
|
+
help
|
90
|
+
exit 1
|
91
|
+
end
|
92
|
+
|
93
|
+
issue_no = args[0].to_i
|
94
|
+
system("#{editor_cmd} #{issue.id_to_full_filename issue_no}")
|
84
95
|
|
85
96
|
when "show"
|
86
|
-
|
97
|
+
issue = Issue.new dir
|
98
|
+
|
99
|
+
if args.size != 1 or not digits_only(args[0]) or args[0].to_i > issue.count
|
87
100
|
puts "beastie error: please specify an issue.\n"
|
88
101
|
help
|
89
102
|
exit 1
|
90
103
|
end
|
91
104
|
|
92
105
|
issue_no = args[0].to_i
|
93
|
-
system("cat #{
|
106
|
+
system("cat #{issue.id_to_full_filename issue_no}")
|
107
|
+
|
108
|
+
when "modify", "change"
|
109
|
+
issue = Issue.new dir
|
94
110
|
|
95
|
-
|
96
|
-
if args.size != 3 or not digits_only(args[0]) or args[0].to_i > Issue.count
|
111
|
+
if args.size != 3 or not digits_only(args[0]) or args[0].to_i > issue.count
|
97
112
|
puts "beastie error: could not parse command line.\n"
|
98
113
|
help
|
99
114
|
exit 1
|
@@ -102,26 +117,30 @@ module Beastie
|
|
102
117
|
issue_no = args[0].to_i
|
103
118
|
field = args[1]
|
104
119
|
value = args[2]
|
105
|
-
|
106
|
-
issue.
|
120
|
+
|
121
|
+
issue.load_n issue_no
|
107
122
|
issue.change field, value
|
108
123
|
issue.save
|
124
|
+
puts "Issue #{issue_no} has now #{field} set to #{value}."
|
109
125
|
|
110
126
|
when "close"
|
111
|
-
|
127
|
+
issue = Issue.new dir
|
128
|
+
|
129
|
+
if args.size != 1 or not digits_only(args[0]) or args[0].to_i > issue.count
|
112
130
|
puts "beastie error: please specify an issue.\n"
|
113
131
|
help
|
114
132
|
exit 1
|
115
133
|
end
|
116
134
|
|
117
135
|
issue_no = args[0].to_i
|
118
|
-
issue
|
119
|
-
issue.load(Issue.filename issue_no)
|
136
|
+
issue.load_n issue_no
|
120
137
|
issue.change "status", "closed"
|
121
138
|
issue.save
|
139
|
+
puts "Issue #{issue_no} is now closed."
|
122
140
|
|
123
141
|
when "list"
|
124
|
-
|
142
|
+
issue = Issue.new dir
|
143
|
+
issue.list
|
125
144
|
|
126
145
|
when "help"
|
127
146
|
help
|
@@ -138,25 +157,54 @@ module Beastie
|
|
138
157
|
private
|
139
158
|
|
140
159
|
def self.help
|
141
|
-
puts
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
160
|
+
puts <<-eos
|
161
|
+
beastie [-p <project> | -d <dir>] <command> [<args>]
|
162
|
+
|
163
|
+
A simple command-line bug-tracking system
|
164
|
+
|
165
|
+
Global options:
|
166
|
+
-p <project> (--project) command will operate on <project> (*)
|
167
|
+
-d <dir> (--directory) command will operate on directory <dir>
|
168
|
+
|
169
|
+
Commands:
|
170
|
+
new create a new issue in current directory
|
171
|
+
nedit title create an issue template and edit it with default editor
|
172
|
+
list list all issues stored in current directory
|
173
|
+
edit N edit issue with id N (where N is the output of the list command)
|
174
|
+
show N show issue with id N (where N is the output of the list command)
|
175
|
+
change N f v change value of field 'f' to 'v' in id N
|
176
|
+
modify N f v change value of field 'f' to 'v' in id N
|
177
|
+
close N shortcut for 'change N status closed'
|
178
|
+
version print version number
|
179
|
+
|
180
|
+
(*) To use this option, create a file #{ProjectList::PROJECT_FILE} containing
|
181
|
+
entries in the form:
|
182
|
+
|
183
|
+
<project1>:
|
184
|
+
dir: <dir1>
|
185
|
+
<project2>:
|
186
|
+
dir: <dir2>
|
187
|
+
|
188
|
+
For instance:
|
189
|
+
|
190
|
+
beastie:
|
191
|
+
dir: /Users/guest/beastie
|
192
|
+
|
193
|
+
(in which case -p beastie is equivalent to -d /Users/guest/beastie)
|
194
|
+
eos
|
154
195
|
end
|
155
196
|
|
156
197
|
# check if str is composed by digits only
|
157
198
|
def self.digits_only str
|
158
199
|
str.each_char.map { |x| x >= '0' and x <= '9'}.all?
|
159
200
|
end
|
201
|
+
|
202
|
+
# get an editor
|
203
|
+
def self.editor_cmd
|
204
|
+
shell_editor = `echo ${EDITOR}`.chomp
|
205
|
+
shell_editor == "" ? EDITOR : shell_editor
|
206
|
+
end
|
207
|
+
|
160
208
|
end
|
161
209
|
|
162
210
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative "../lib/beastie/project_list"
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "tempfile"
|
5
|
+
|
6
|
+
# we need to override the PROJECT_FILE
|
7
|
+
class MyTestProjectList < Beastie::ProjectList
|
8
|
+
# a hack to change the PROJECT_FILE constant to point to string
|
9
|
+
def self.project_file string
|
10
|
+
PROJECT_FILE.replace string
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class TestProjectList < Test::Unit::TestCase
|
15
|
+
# if the project file does not exist, nil is returned
|
16
|
+
def test_no_project_file
|
17
|
+
MyTestProjectList.project_file Tempfile.new('foo').path
|
18
|
+
assert_equal(nil, MyTestProjectList.project_dir('foo'))
|
19
|
+
end
|
20
|
+
|
21
|
+
# the file exists, it might or might not contain an entry
|
22
|
+
def test_project_file
|
23
|
+
MyTestProjectList.project_file Tempfile.new('foo').path
|
24
|
+
File.open(MyTestProjectList::PROJECT_FILE, "w") do |f|
|
25
|
+
f.puts <<-eos
|
26
|
+
foo:
|
27
|
+
dir: /a/b/c
|
28
|
+
eos
|
29
|
+
end
|
30
|
+
assert_equal("/a/b/c", MyTestProjectList.project_dir('foo'))
|
31
|
+
assert_equal(nil, MyTestProjectList.project_dir('foolish'))
|
32
|
+
end
|
33
|
+
|
34
|
+
# the file exists, but it is wrongly configured (no dir entry)
|
35
|
+
def test_wrong_project_file
|
36
|
+
MyTestProjectList.project_file Tempfile.new('foo').path
|
37
|
+
File.open(MyTestProjectList::PROJECT_FILE, "w") do |f|
|
38
|
+
f.puts <<-eos
|
39
|
+
foo:
|
40
|
+
directory: /a/b/c
|
41
|
+
eos
|
42
|
+
end
|
43
|
+
assert_equal(nil, MyTestProjectList.project_dir('foo'))
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beastie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adolfo Villafiorita
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
description: A command-line issue and bug tracking system
|
@@ -46,7 +46,7 @@ executables:
|
|
46
46
|
extensions: []
|
47
47
|
extra_rdoc_files: []
|
48
48
|
files:
|
49
|
-
- .gitignore
|
49
|
+
- ".gitignore"
|
50
50
|
- Gemfile
|
51
51
|
- LICENSE.txt
|
52
52
|
- README.textile
|
@@ -55,7 +55,9 @@ files:
|
|
55
55
|
- bin/beastie
|
56
56
|
- lib/beastie.rb
|
57
57
|
- lib/beastie/issue.rb
|
58
|
+
- lib/beastie/project_list.rb
|
58
59
|
- lib/beastie/version.rb
|
60
|
+
- test/test_project_list.rb
|
59
61
|
homepage: https://github.com/avillafiorita/beastie
|
60
62
|
licenses:
|
61
63
|
- MIT
|
@@ -66,20 +68,21 @@ require_paths:
|
|
66
68
|
- lib
|
67
69
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
70
|
requirements:
|
69
|
-
- -
|
71
|
+
- - ">="
|
70
72
|
- !ruby/object:Gem::Version
|
71
73
|
version: '0'
|
72
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
75
|
requirements:
|
74
|
-
- -
|
76
|
+
- - ">="
|
75
77
|
- !ruby/object:Gem::Version
|
76
78
|
version: '0'
|
77
79
|
requirements: []
|
78
80
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.
|
81
|
+
rubygems_version: 2.2.1
|
80
82
|
signing_key:
|
81
83
|
specification_version: 4
|
82
84
|
summary: A command-line issue and bug tracking system which uses a file per bug, yaml
|
83
85
|
for data storage and it is not opinionated about versioning system, workflows, fieldsets,
|
84
86
|
etc. Useful for small and personal projects when high formality is not required.
|
85
|
-
test_files:
|
87
|
+
test_files:
|
88
|
+
- test/test_project_list.rb
|