beastie 0.1.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c52cc68533324dfc1d94ca88426850744b211c0a
4
+ data.tar.gz: aec85bee46e23870970efe04ff84f5db48f1cedc
5
+ SHA512:
6
+ metadata.gz: 17dbb387afdd0873ae92597dc069be60b549efb6ad744da231cf60c248f8160284769bd0a1161b02200de9962886a2b4220249fa13b636e3c1753ed827e1f991
7
+ data.tar.gz: 385fef52bde1882313043b40208db029a081c07a5a2f296c31cbc9f7ddd37e66d861fd00f2273149c4612b24b1e34769fd9e5223b6f4d258fcdc97d6142653eb
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *~
2
+ .DS_Store
3
+ *.gem
4
+ *.rbc
5
+ .bundle
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in beastie.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Adolfo Villafiorita
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,79 @@
1
+ h1. Beastie
2
+
3
+ A bare-bones command-line bug tracking system for personal or small projects which require little formality.
4
+
5
+ h2. Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ <pre>
10
+ gem 'beastie'
11
+ </pre>
12
+
13
+ And then execute:
14
+
15
+ <pre>
16
+ $ bundle
17
+ </pre>
18
+
19
+ Or install it yourself as:
20
+
21
+ <pre>
22
+ $ gem install beastie
23
+ </pre>
24
+
25
+ h2. Usage
26
+
27
+ Beastie is a bug tracking system at its bare essentials.
28
+
29
+ Main commands:
30
+
31
+ - @beastie new@ := asks information about an issue and generate a YAML file in the current directory.
32
+
33
+ - @beastie list@ := reads all YAML files in the current directory and generate a list of all the issues.
34
+
35
+ - @beastie show N@ := shows issue @N@, where @N@ is the identifier shown by the @beastie list@ command.
36
+
37
+ - @beastie edit N@ := edits issue @N@. The commands invokes the editor set in the shell @EDITOR@ variable or use @emacsclient@ if @EDITOR@ is unset.
38
+
39
+ - @beastie help@ := unleashes the real power of @beastie@.
40
+
41
+ h2. Limitations and Warnings
42
+
43
+ Beastie uses the *current directory* for all operations. While this gives a lot of flexibility and freedom in choosing one's standards, it also requires discipline: so, make sure you select one directory where issues are stored and always invoke @beastie@ from that directory.
44
+
45
+ Beastie tries to generate 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 parsed. 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).
46
+
47
+ Beastie does not have a specific workflow for bug statutes.
48
+
49
+ Beastie does not perform syntax checks when reading data. This can be changed by specifying appropriate input functions in the @ISSUE_FIELDS@ variable (@lib/beastie/issue.rb@).
50
+
51
+ Beastie asks various information about a bug. Change the @ISSUE_FIELDS@ variable, if you are not happy with the default fieldset.
52
+
53
+
54
+ h2. Similar solutions
55
+
56
+ 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.
57
+
58
+ Why did I re-invent the wheel?
59
+
60
+ # for fun
61
+ # human-readable filenames, so that I can manage issues without using beastie, if I want
62
+ # a "programmable" fieldset (see @lib/beastie/issue.rb@)
63
+ # keeping the solution simple
64
+
65
+ h2. Author
66
+
67
+ Adolfo Villafiorita
68
+
69
+ h2. License
70
+
71
+ "MIT":https://github.com/avillafiorita/beastie/blob/master/LICENSE.txt
72
+
73
+ h2. Contributing
74
+
75
+ 1. Fork it
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/beastie.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'beastie/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "beastie"
8
+ spec.version = Beastie::VERSION
9
+ spec.authors = ["Adolfo Villafiorita"]
10
+ spec.email = ["adolfo.villafiorita@me.com"]
11
+ spec.description = %q{A command-line issue and bug tracking system}
12
+ spec.summary = %q{A command-line issue and bug tracking system which uses a file per bug, yaml for data storage and it is not opinionated about versioning system, workflows, fieldsets, etc. Useful for small and personal projects when high formality is not required.}
13
+ spec.homepage = "https://github.com/avillafiorita/beastie"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
data/bin/beastie ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/beastie'
4
+
5
+ Beastie::Runner.run(ARGV)
6
+
@@ -0,0 +1,151 @@
1
+ require 'date'
2
+ require 'tempfile'
3
+ require 'yaml'
4
+
5
+ module Beastie
6
+ class Issue
7
+ # A default issue has:
8
+ #
9
+ # - title
10
+ # - status
11
+ # - created
12
+ # - component
13
+ # - priority
14
+ # - severity
15
+ # - points
16
+ # - type
17
+ # - description
18
+ #
19
+ # Customizing the fields:
20
+ #
21
+ # - the fields aske by the new command are specified by the
22
+ # ISSUE_FIELDS variable
23
+ #
24
+ # - for each field, the structure if the following:
25
+ #
26
+ # field name => init value, prompt
27
+ #
28
+ # where
29
+ # * "init value" is evaluated (use "gets.chomp" to ask input)
30
+ # * prompt is what is asked to the user. Use an empty string for
31
+ # a value which is filled automatically.
32
+ #
33
+ # - title, created, and status are compulsory: do not delete them
34
+ # (gen_filename depends upon title and created; the close
35
+ # command depends upon status)
36
+ #
37
+ ISSUE_FIELDS = {
38
+ "title" => ["gets.chomp", "Short description of the issue"],
39
+ "status" => ["'open'", ""],
40
+ "created" => ["Date.today", ""],
41
+ "component" => ["gets.chomp", "Component affected by the issue"],
42
+ "priority" => ["get_int", "Priority (an integer number, e.g., from 1 to 5)"],
43
+ "severity" => ["get_int", "Severity (an integer number, e.g., from 1 to 5)"],
44
+ "points" => ["get_int", "Points (an integer estimating the difficulty of the issue)"],
45
+ "type" => ["gets.chomp", "Type (e.g., story, task, bug, refactoring)"],
46
+ "description" => ["get_lines", "Longer description (terminate with '.')"]
47
+ }
48
+
49
+ # which fields go to the report and formatting options
50
+ REPORT_FIELDS = {
51
+ "status" => "%-10s",
52
+ "type" => "%-10s",
53
+ "priority" => "%8s",
54
+ "severity" => "%8s",
55
+ "created" => "%-10s",
56
+ "title" => "%-32s"
57
+ }
58
+
59
+ # these keep the actual values
60
+ attr_reader :issue
61
+ # the filename, after the issue has been saved or if it has been loaded
62
+ attr_reader :filename
63
+
64
+ # interactively ask from command line all fields specified in ISSUE_FIELDS
65
+ def ask
66
+ @issue = Hash.new
67
+
68
+ ISSUE_FIELDS.keys.each do |key|
69
+ puts "#{ISSUE_FIELDS[key][1]}: " if ISSUE_FIELDS[key][1] != ""
70
+ @issue[key] = (eval ISSUE_FIELDS[key][0]) || ""
71
+ end
72
+ end
73
+
74
+ # load from command line
75
+ def load filename
76
+ @filename = filename
77
+ @issue = YAML.load_file(filename)
78
+ end
79
+
80
+ def change field, value
81
+ @issue[field] = value
82
+ end
83
+
84
+ # save object to file
85
+ def save
86
+ @filename = @filename || gen_filename
87
+
88
+ file = File.open(@filename, 'w') { |f|
89
+ f.puts @issue.to_yaml
90
+ }
91
+
92
+ puts "Issue saved to #{filename}"
93
+ end
94
+
95
+ # return the n-th filename
96
+ def self.filename n
97
+ Dir.glob('*.{yml,yaml}')[n - 1]
98
+ end
99
+
100
+ # list all issues in current directory
101
+ def self.list
102
+ # print header
103
+ printf "ID "
104
+ REPORT_FIELDS.keys.each do |key|
105
+ printf REPORT_FIELDS[key] + " ", key
106
+ end
107
+ printf "\n"
108
+
109
+ # print issues
110
+ file_no = 0
111
+ Dir.glob('*.{yml,yaml}') do |file|
112
+ data = YAML.load_file(file)
113
+ file_no += 1
114
+
115
+ printf "%3d ", file_no
116
+ REPORT_FIELDS.keys.each do |key|
117
+ printf REPORT_FIELDS[key] + " ", data[key]
118
+ end
119
+ printf "\n"
120
+ end
121
+ end
122
+
123
+ private
124
+
125
+ # read n-lines (terminated by a ".")
126
+ def get_lines
127
+ $/ = "."
128
+ STDIN.gets.chomp(".")
129
+ end
130
+
131
+ # read an integer
132
+ def get_int
133
+ gets.chomp.to_i
134
+ end
135
+
136
+ # return a unique filename for this issue
137
+ def gen_filename
138
+ name = @issue["created"].strftime("%Y-%m-%d-") +
139
+ @issue["title"].gsub(/\W+/, "_") +
140
+ ".yaml"
141
+ n = 1
142
+ while File.exist?(name)
143
+ name = File.basename(name, ".yaml") + "-" + n.to_s + ".yaml"
144
+ n += 1
145
+ end
146
+
147
+ name
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,3 @@
1
+ module Beastie
2
+ VERSION = "0.1.1"
3
+ end
data/lib/beastie.rb ADDED
@@ -0,0 +1,110 @@
1
+ require 'pathname'
2
+ require 'optparse'
3
+
4
+ require_relative "beastie/version"
5
+ require_relative "beastie/issue"
6
+
7
+ module Beastie
8
+
9
+ # tell option parser to accept an existing directory
10
+ OptionParser.accept(Pathname) do |pn|
11
+ Pathname.new(pn) if pn
12
+ raise OptionParser::InvalidArgument, pn if not Dir.exist?(pn)
13
+ end
14
+
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
+ class Runner
23
+ # the editor to use with the edit command
24
+ EDITOR = "emacsclient"
25
+
26
+ def self.run(args)
27
+
28
+ # options = {}
29
+
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
+ command = args[0]
42
+ args.shift
43
+
44
+ case command
45
+
46
+ when "new"
47
+ issue = Issue.new
48
+ issue.ask
49
+ issue.save
50
+
51
+ when "edit"
52
+ issue_no = args[0].to_i
53
+ shell_editor = `echo ${EDITOR}`.chomp
54
+ editor = shell_editor == "" ? EDITOR : shell_editor
55
+ system("#{editor} #{Issue.filename issue_no}")
56
+
57
+ when "show"
58
+ issue_no = args[0].to_i
59
+ system("cat #{Issue.filename issue_no}")
60
+
61
+ when "change"
62
+ issue_no = args[0].to_i
63
+ field = args[1]
64
+ value = args[2]
65
+ issue = Issue.new
66
+ issue.load(Issue.filename issue_no)
67
+ issue.change field, value
68
+ issue.save
69
+
70
+ when "close"
71
+ issue_no = args[0].to_i
72
+ issue = Issue.new
73
+ issue.load(Issue.filename issue_no)
74
+ issue.change "status", "closed"
75
+ issue.save
76
+
77
+ when "list"
78
+ Beastie::Issue.list
79
+
80
+ when "help"
81
+ help
82
+
83
+ when "version"
84
+ puts "beastie version #{VERSION}"
85
+
86
+ else
87
+ help
88
+ end
89
+
90
+ end
91
+
92
+ private
93
+
94
+ def self.help
95
+ puts "beastie command args"
96
+ puts ""
97
+ puts "A simple command-line bug-tracking system"
98
+ puts ""
99
+ puts "Commands:"
100
+ puts " new create a new issue in current directory"
101
+ puts " list list all issues stored in current directory"
102
+ puts " edit N edit issue with id N (where N is the output of the list command)"
103
+ puts " show N show issue with id N (where N is the output of the list command)"
104
+ puts " change N f v change value of field 'f' to 'v' in id N"
105
+ puts " close N shortcut for 'change N status closed'"
106
+ puts " version print version number"
107
+ end
108
+
109
+ end
110
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beastie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Adolfo Villafiorita
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A command-line issue and bug tracking system
42
+ email:
43
+ - adolfo.villafiorita@me.com
44
+ executables:
45
+ - beastie
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.textile
53
+ - Rakefile
54
+ - beastie.gemspec
55
+ - bin/beastie
56
+ - lib/beastie.rb
57
+ - lib/beastie/issue.rb
58
+ - lib/beastie/version.rb
59
+ homepage: https://github.com/avillafiorita/beastie
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.0.14
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: A command-line issue and bug tracking system which uses a file per bug, yaml
83
+ for data storage and it is not opinionated about versioning system, workflows, fieldsets,
84
+ etc. Useful for small and personal projects when high formality is not required.
85
+ test_files: []