beastie 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|