ursm-ditz 0.4 → 0.5
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.
- data/Changelog +15 -0
- data/INSTALL +20 -0
- data/LICENSE +674 -0
- data/Manifest.txt +40 -0
- data/PLUGINS.txt +140 -0
- data/README.txt +43 -27
- data/Rakefile +36 -3
- data/ReleaseNotes +6 -0
- data/bin/ditz +49 -63
- data/contrib/completion/ditz.bash +25 -9
- data/lib/ditz.rb +52 -7
- data/lib/ditz/file-storage.rb +54 -0
- data/lib/{hook.rb → ditz/hook.rb} +1 -1
- data/lib/{html.rb → ditz/html.rb} +42 -4
- data/lib/{lowline.rb → ditz/lowline.rb} +31 -11
- data/lib/{model-objects.rb → ditz/model-objects.rb} +53 -21
- data/lib/ditz/model.rb +321 -0
- data/lib/{operator.rb → ditz/operator.rb} +122 -67
- data/lib/ditz/plugins/git-sync.rb +83 -0
- data/lib/{plugins → ditz/plugins}/git.rb +57 -18
- data/lib/ditz/plugins/issue-claiming.rb +174 -0
- data/lib/ditz/plugins/issue-labeling.rb +161 -0
- data/lib/{util.rb → ditz/util.rb} +4 -0
- data/lib/{view.rb → ditz/view.rb} +0 -0
- data/lib/{views.rb → ditz/views.rb} +7 -4
- data/man/{ditz.1 → man1/ditz.1} +1 -1
- data/setup.rb +1585 -0
- data/share/ditz/blue-check.png +0 -0
- data/{lib → share/ditz}/component.rhtml +7 -5
- data/share/ditz/green-bar.png +0 -0
- data/share/ditz/green-check.png +0 -0
- data/share/ditz/index.rhtml +130 -0
- data/share/ditz/issue.rhtml +119 -0
- data/share/ditz/issue_table.rhtml +28 -0
- data/share/ditz/red-check.png +0 -0
- data/share/ditz/release.rhtml +98 -0
- data/share/ditz/style.css +226 -0
- data/share/ditz/unassigned.rhtml +23 -0
- data/share/ditz/yellow-bar.png +0 -0
- metadata +50 -28
- data/lib/index.rhtml +0 -113
- data/lib/issue.rhtml +0 -111
- data/lib/issue_table.rhtml +0 -33
- data/lib/model.rb +0 -208
- data/lib/plugins/issue-claiming.rb +0 -92
- data/lib/release.rhtml +0 -69
- data/lib/style.css +0 -127
- data/lib/trollop.rb +0 -518
- data/lib/unassigned.rhtml +0 -31
- data/lib/vendor/yaml_waml.rb +0 -28
data/Manifest.txt
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Changelog
|
2
|
+
INSTALL
|
3
|
+
LICENSE
|
4
|
+
Manifest.txt
|
5
|
+
PLUGINS.txt
|
6
|
+
README.txt
|
7
|
+
Rakefile
|
8
|
+
ReleaseNotes
|
9
|
+
bin/ditz
|
10
|
+
contrib/completion/_ditz.zsh
|
11
|
+
contrib/completion/ditz.bash
|
12
|
+
lib/ditz.rb
|
13
|
+
lib/ditz/file-storage.rb
|
14
|
+
lib/ditz/hook.rb
|
15
|
+
lib/ditz/html.rb
|
16
|
+
lib/ditz/lowline.rb
|
17
|
+
lib/ditz/model-objects.rb
|
18
|
+
lib/ditz/model.rb
|
19
|
+
lib/ditz/operator.rb
|
20
|
+
lib/ditz/plugins/git-sync.rb
|
21
|
+
lib/ditz/plugins/git.rb
|
22
|
+
lib/ditz/plugins/issue-claiming.rb
|
23
|
+
lib/ditz/plugins/issue-labeling.rb
|
24
|
+
lib/ditz/util.rb
|
25
|
+
lib/ditz/view.rb
|
26
|
+
lib/ditz/views.rb
|
27
|
+
share/ditz/index.rhtml
|
28
|
+
share/ditz/issue.rhtml
|
29
|
+
share/ditz/issue_table.rhtml
|
30
|
+
share/ditz/release.rhtml
|
31
|
+
share/ditz/unassigned.rhtml
|
32
|
+
share/ditz/component.rhtml
|
33
|
+
share/ditz/style.css
|
34
|
+
share/ditz/blue-check.png
|
35
|
+
share/ditz/green-bar.png
|
36
|
+
share/ditz/green-check.png
|
37
|
+
share/ditz/red-check.png
|
38
|
+
share/ditz/yellow-bar.png
|
39
|
+
man/man1/ditz.1
|
40
|
+
setup.rb
|
data/PLUGINS.txt
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
Ditz plugin documentation
|
2
|
+
-------------------------
|
3
|
+
|
4
|
+
Ditz features a code plugin system for adding and extending commands, fields,
|
5
|
+
and output. Ditz's plugin system is used to add optional functionality to Ditz.
|
6
|
+
|
7
|
+
If you're interested in writing a plugin, look at the simple plugins in
|
8
|
+
lib/ditz/plugin/, and see
|
9
|
+
http://all-thing.net/2008/07/ditz-04-and-magic-of-ruby-dsls.html
|
10
|
+
If you're interested using plugins, read on.
|
11
|
+
|
12
|
+
Ditz loads specific plugins by looking for a .ditz-plugins file in the project
|
13
|
+
root. The format of this file is a YAML array of strings, where each string is
|
14
|
+
a plugin name. You can write this by hand like this:
|
15
|
+
|
16
|
+
- my-plugin
|
17
|
+
- another-plugin
|
18
|
+
|
19
|
+
I.e. one plugin name per line, prefixed by "- " as the first two characters of each line.
|
20
|
+
|
21
|
+
For each listed plugin name, Ditz looks for a file named
|
22
|
+
"lib/ditz/plugin/<name>.rb" within Ruby's default search path. Assuming Ditz is
|
23
|
+
installed in a standard manner, you should have available to you the following
|
24
|
+
shipped plugins:
|
25
|
+
|
26
|
+
1. git
|
27
|
+
2. git-sync
|
28
|
+
3. issue-claiming
|
29
|
+
4. issue-labeling
|
30
|
+
|
31
|
+
git
|
32
|
+
---
|
33
|
+
|
34
|
+
This plugin allows issues to be associated with git commits and git
|
35
|
+
branches. Git commits can be easily tagged with a ditz issue with the 'ditz
|
36
|
+
commit' command, and both 'ditz show' and the ditz HTML output will then
|
37
|
+
contain a list of associated commits for each issue.
|
38
|
+
|
39
|
+
Issues can also be assigned a single git feature branch. In this case, all
|
40
|
+
commits on that branch will listed as commits for that issue. This
|
41
|
+
particular feature is fairly rudimentary, however---it assumes the reference
|
42
|
+
point is the 'master' branch, and once the feature branch is merged back
|
43
|
+
into master, the list of commits disappears.
|
44
|
+
|
45
|
+
Two configuration variables are added, which, when specified, are used to
|
46
|
+
construct HTML links for the git commit id and branch names in the generated
|
47
|
+
HTML output.
|
48
|
+
|
49
|
+
Commands added:
|
50
|
+
ditz set-branch: set the git branch of an issue
|
51
|
+
ditz commit: run git-commit, and insert the issue id into the commit
|
52
|
+
message.
|
53
|
+
|
54
|
+
Usage:
|
55
|
+
1. add a line "- git" to the .ditz-plugins file in the project root
|
56
|
+
2. run ditz reconfigure, and enter the URL prefixes, if any, from
|
57
|
+
which to create commit and branch links.
|
58
|
+
3. use 'ditz commit' with abandon.
|
59
|
+
|
60
|
+
git-sync
|
61
|
+
--------
|
62
|
+
|
63
|
+
This plugin is useful for when you want synchronized, non-distributed issue
|
64
|
+
coordination with other developers, and you're using git. It allows you to
|
65
|
+
synchronize issue updates with other developers by using the 'ditz sync'
|
66
|
+
command, which does all the git work of sending and receiving issue change
|
67
|
+
for you. However, you have to set things up in a very specific way for this
|
68
|
+
to work:
|
69
|
+
|
70
|
+
1. Your ditz state must be on a separate branch. I recommend calling it
|
71
|
+
'bugs'. Create this branch, do a ditz init, and push it to the remote
|
72
|
+
repo. (This means you won't be able to mingle issue change and code
|
73
|
+
change in the same commits. If you care.)
|
74
|
+
2. Make a checkout of the bugs branch in a separate directory, but NOT in
|
75
|
+
your code checkout. If you're developing in a directory called "project",
|
76
|
+
I recommend making a ../project-bugs/ directory, cloning the repo there
|
77
|
+
as well, and keeping that directory checked out to the 'bugs' branch.
|
78
|
+
(There are various complicated things you can do to make that directory
|
79
|
+
share git objects with your code directory, but I wouldn't bother unless
|
80
|
+
you really care about disk space. Just make it an independent clone.)
|
81
|
+
3. Set that directory as your issue-dir in your .ditz-config file in your
|
82
|
+
code checkout directory. (This file should be in .gitignore, btw.)
|
83
|
+
4. Run 'ditz reconfigure' and fill in the local branch name, remote
|
84
|
+
branch name, and remote repo for the issue tracking branch.
|
85
|
+
|
86
|
+
Once that's set up, 'ditz sync' will change to the bugs checkout dir, bundle
|
87
|
+
up any changes you've made to issue status, push them to the remote repo,
|
88
|
+
and pull any new changes in too. All ditz commands will read from your bugs
|
89
|
+
directory, so you should be able to use ditz without caring about where
|
90
|
+
things are anymore.
|
91
|
+
|
92
|
+
This complicated setup is necessary to avoid accidentally mingling code
|
93
|
+
change and issue change. With this setup, issue change is synchronized,
|
94
|
+
but how you synchronize code is still up to you.
|
95
|
+
|
96
|
+
Usage:
|
97
|
+
0. read all the above text very carefully
|
98
|
+
1. add a line "- git-sync" to the .ditz-plugins file in the project
|
99
|
+
root
|
100
|
+
2. run 'ditz reconfigure' and answer its questions
|
101
|
+
3. run 'ditz sync' with abandon
|
102
|
+
|
103
|
+
issue-claiming
|
104
|
+
--------------
|
105
|
+
|
106
|
+
This plugin allows people to claim issues. This is useful for avoiding
|
107
|
+
duplication of work---you can check to see if someone's claimed an
|
108
|
+
issue before starting to work on it, and you can let people know what
|
109
|
+
you're working on.
|
110
|
+
|
111
|
+
Commands added:
|
112
|
+
ditz claim: claim an issue for yourself
|
113
|
+
ditz unclaim: unclaim a claimed issue
|
114
|
+
ditz mine: show all issues claimed by you
|
115
|
+
ditz claimed: show all claimed issues, by developer
|
116
|
+
ditz unclaimed: show all unclaimed issues
|
117
|
+
|
118
|
+
Usage:
|
119
|
+
1. add a line "- issue-claiming" to the .ditz-plugins file in the project
|
120
|
+
root
|
121
|
+
2. use the above commands to abandon
|
122
|
+
|
123
|
+
issue-labeling
|
124
|
+
--------------
|
125
|
+
|
126
|
+
This plugin allows label issues. This can replace the issue component
|
127
|
+
and/or issue types (bug,feature,task), by providing a more flexible
|
128
|
+
to organize your issues.
|
129
|
+
|
130
|
+
Commands added:
|
131
|
+
ditz new_label [label]: create a new label for the project
|
132
|
+
ditz label <issue> <labels>: label an issue with some labels
|
133
|
+
ditz unlabel <issue> [labels]: remove some label(s) of an issue
|
134
|
+
ditz labeled <labels> [release]: show all issues with these labels
|
135
|
+
|
136
|
+
Usage:
|
137
|
+
1. add a line "- issue-labeling" to the .ditz-plugins file in the project
|
138
|
+
root
|
139
|
+
2. use the above commands to abandon
|
140
|
+
|
data/README.txt
CHANGED
@@ -14,7 +14,18 @@ Ditz maintains an issue database directory on disk, with files written in a
|
|
14
14
|
line-based and human-editable format. This directory can be kept under version
|
15
15
|
control, alongside project code.
|
16
16
|
|
17
|
-
|
17
|
+
Ditz provides a simple, console-based interface for creating and updating the
|
18
|
+
issue database files, and some basic static HTML generation capabilities for
|
19
|
+
producing world-readable status pages (for a demo, see the ditz ditz page).
|
20
|
+
|
21
|
+
Ditz includes a robust plugin system for adding commands, model fields, and
|
22
|
+
modifying output. See PLUGINS.txt for documentation on the pre-shipped plugins.
|
23
|
+
|
24
|
+
Ditz currently offers no central public method of bug submission.
|
25
|
+
|
26
|
+
== USING DITZ
|
27
|
+
|
28
|
+
There are several different ways to use Ditz:
|
18
29
|
|
19
30
|
1. Treat issue change the same as code change: include it as part of commits,
|
20
31
|
and merge it with changes from other developers, resolving conflicts in the
|
@@ -24,12 +35,18 @@ There are several different ways to use ditz:
|
|
24
35
|
commits.
|
25
36
|
3. Keep the issue database separate and not under VCS at all.
|
26
37
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
38
|
+
All of these options are supported; the choice of which to use depends on your
|
39
|
+
workflow.
|
40
|
+
|
41
|
+
Option #1 is probably most appropriate for the unsynchronized, distributed
|
42
|
+
development, since it allows individual developers to modify issue state with a
|
43
|
+
minimum of hassle. Option #2 is most suitable for synchronized development, as
|
44
|
+
issue state change can be transmitted independently of code change (see also
|
45
|
+
the git-sync plugin) and can act as a sychronization mechanism. Option #3 is
|
46
|
+
only useful with some other distribution mechanism, like a central web
|
47
|
+
interface.
|
31
48
|
|
32
|
-
== SYNOPSIS
|
49
|
+
== COMMANDLINE SYNOPSIS
|
33
50
|
|
34
51
|
# set up project. creates the bugs.yaml file.
|
35
52
|
1. ditz init
|
@@ -53,16 +70,17 @@ It currently offers no central public method of bug submission.
|
|
53
70
|
|
54
71
|
== THE DITZ DATA MODEL
|
55
72
|
|
56
|
-
Ditz includes the bare minimum set of features necessary for
|
57
|
-
development. Features like time spent, priority, assignment of
|
58
|
-
developers, due dates, etc. are purposely
|
73
|
+
By default, Ditz includes the bare minimum set of features necessary for
|
74
|
+
open-source development. Features like time spent, priority, assignment of
|
75
|
+
tasks to developers, due dates, etc. are purposely relegated to the plugin
|
76
|
+
system.
|
59
77
|
|
60
|
-
A
|
78
|
+
A Ditz project consists of issues, releases and components.
|
61
79
|
|
62
80
|
Issues:
|
63
|
-
Issues are the fundamental currency of issue tracking. A
|
64
|
-
a feature or a bug, but this distinction doesn't affect anything
|
65
|
-
how they're displayed.
|
81
|
+
Issues are the fundamental currency of issue tracking. A Ditz issue is either
|
82
|
+
a feature or a bug, but this distinction currently doesn't affect anything
|
83
|
+
other than how they're displayed.
|
66
84
|
|
67
85
|
Each issue belongs to exactly one component, and is part of zero or one
|
68
86
|
releases.
|
@@ -72,9 +90,13 @@ Issues:
|
|
72
90
|
developers, present and future. Issue ids are typically not exposed to the
|
73
91
|
user.
|
74
92
|
|
75
|
-
Issues also have a non-exportable name, which is short and
|
76
|
-
All
|
77
|
-
|
93
|
+
Issues also have a non-global, non-exportable name, which is short and
|
94
|
+
human-readable. All Ditz commands use issue names in addition to issue ids.
|
95
|
+
Issue names (but not issue ids) may change in certain circumstances, e.g.
|
96
|
+
after a "ditz drop" command.
|
97
|
+
|
98
|
+
Issue names can be specified in comments, titles and descriptions, and Ditz
|
99
|
+
will automatically rewrite them as necessary when they change.
|
78
100
|
|
79
101
|
Components:
|
80
102
|
There is always one "general" component, named after the project itself. In
|
@@ -82,20 +104,14 @@ Components:
|
|
82
104
|
with the question of which component to assign an issue to.
|
83
105
|
|
84
106
|
Components simply provide a way of organizing issues, and have no real
|
85
|
-
functionality. Issues are
|
86
|
-
|
107
|
+
functionality. Issues names are derived from the component they're assigned
|
108
|
+
to.
|
87
109
|
|
88
110
|
Releases:
|
89
111
|
A release is the primary grouping mechanism for issues. Status commands like
|
90
112
|
"ditz status" and "ditz todo" always group issues by release. When a release
|
91
|
-
is 100% complete, it can be marked as released,
|
92
|
-
|
93
|
-
|
94
|
-
== FUTURE WORK
|
95
|
-
|
96
|
-
In future releases, Ditz will have a plugin architecture to allow tighter
|
97
|
-
integration with specific SCMs and developer communication channels. (See
|
98
|
-
http://ditz.rubyforge.org/ditz/issue-0704dafe4aef96279364013aba177a0971d425cb.html)
|
113
|
+
is 100% complete, it can be marked as released, and its issues will cease
|
114
|
+
appearing in Ditz status and todo messages.
|
99
115
|
|
100
116
|
== LEARNING MORE
|
101
117
|
|
@@ -104,7 +120,7 @@ http://ditz.rubyforge.org/ditz/issue-0704dafe4aef96279364013aba177a0971d425cb.ht
|
|
104
120
|
|
105
121
|
== REQUIREMENTS
|
106
122
|
|
107
|
-
* trollop >= 1.8.2
|
123
|
+
* trollop >= 1.8.2, if running via RubyGems.
|
108
124
|
|
109
125
|
== INSTALLATION
|
110
126
|
|
data/Rakefile
CHANGED
@@ -5,8 +5,8 @@ $:.unshift "lib"
|
|
5
5
|
require 'ditz'
|
6
6
|
|
7
7
|
class Hoe
|
8
|
-
def
|
9
|
-
end
|
8
|
+
def extra_dev_deps; @extra_dev_deps.reject { |x| x[0] == "hoe" } end
|
9
|
+
end
|
10
10
|
|
11
11
|
Hoe.new('ditz', Ditz::VERSION) do |p|
|
12
12
|
p.rubyforge_name = 'ditz'
|
@@ -17,9 +17,10 @@ Hoe.new('ditz', Ditz::VERSION) do |p|
|
|
17
17
|
p.url = "http://ditz.rubyforge.org"
|
18
18
|
p.changes = p.paragraphs_of('Changelog', 0..0).join("\n\n")
|
19
19
|
p.email = "wmorgan-ditz@masanjin.net"
|
20
|
+
p.extra_deps = [['trollop', '>= 1.9'], ['kakutani-yaml_waml', '>= 0.3']]
|
20
21
|
end
|
21
22
|
|
22
|
-
WWW_FILES = FileList["www/*"] + %w(README.txt)
|
23
|
+
WWW_FILES = FileList["www/*"] + %w(README.txt PLUGINS.txt)
|
23
24
|
|
24
25
|
task :upload_webpage => WWW_FILES do |t|
|
25
26
|
sh "rsync -essh -cavz #{t.prerequisites * ' '} wmorgan@rubyforge.org:/var/www/gforge-projects/ditz/"
|
@@ -30,4 +31,36 @@ task :upload_report do |t|
|
|
30
31
|
sh "rsync -essh -cavz ditz wmorgan@rubyforge.org:/var/www/gforge-projects/ditz/"
|
31
32
|
end
|
32
33
|
|
34
|
+
task :plugins do |t|
|
35
|
+
sh "ruby -w ./make-plugins.txt.rb > PLUGINS.txt"
|
36
|
+
end
|
37
|
+
|
38
|
+
task :really_check_manifest do |t|
|
39
|
+
f1 = Tempfile.new "manifest"; f1.close
|
40
|
+
f2 = Tempfile.new "manifest"; f2.close
|
41
|
+
sh "git ls-files | egrep -v \"^bugs/\" | sort > #{f1.path}"
|
42
|
+
sh "sort Manifest.txt > #{f2.path}"
|
43
|
+
|
44
|
+
f3 = Tempfile.new "manifest"; f3.close
|
45
|
+
sh "diff -u #{f1.path} #{f2.path} > #{f3.path}; /bin/true"
|
46
|
+
|
47
|
+
left, right = [], []
|
48
|
+
IO.foreach(f3.path) do |l|
|
49
|
+
case l
|
50
|
+
when /^\-\-\-/
|
51
|
+
when /^\+\+\+/
|
52
|
+
when /^\-(.*)\n$/; left << $1
|
53
|
+
when /^\+(.*)\n$/; right << $2
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
puts
|
58
|
+
puts "Tracked by git but not in Manifest.txt:"
|
59
|
+
puts left.empty? ? " <nothing>" : left.map { |l| " " + l }
|
60
|
+
|
61
|
+
puts
|
62
|
+
puts "In Manifest.txt, but not tracked by git:"
|
63
|
+
puts right.empty? ? " <nothing>" : right.map { |l| " " + l }
|
64
|
+
end
|
65
|
+
|
33
66
|
# vim: syntax=ruby
|
data/ReleaseNotes
CHANGED
data/bin/ditz
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
#!/usr/bin/ruby1.8
|
2
2
|
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("#{File.dirname($0)}/../lib"))
|
4
|
+
|
3
5
|
## requires are split in two for efficiency reasons: ditz should be really
|
4
6
|
## fast when using it for completion.
|
5
7
|
$KCODE = "u"
|
6
8
|
|
7
|
-
require 'operator'
|
9
|
+
require 'ditz/operator'
|
8
10
|
op = Ditz::Operator.new
|
9
11
|
|
10
12
|
## a secret option for shell completion
|
@@ -13,14 +15,19 @@ if ARGV.include? '--commands'
|
|
13
15
|
exit 0
|
14
16
|
end
|
15
17
|
|
16
|
-
|
18
|
+
begin
|
19
|
+
require 'rubygems'
|
20
|
+
# list version dependant gems here.
|
21
|
+
gem 'kakutani-yaml_waml', '>= 0.3'
|
22
|
+
gem 'trollop', '>= 1.9'
|
23
|
+
rescue LoadError
|
24
|
+
end
|
25
|
+
|
17
26
|
require 'fileutils'
|
18
27
|
require 'pathname'
|
19
28
|
require 'trollop'; include Trollop
|
20
29
|
require "ditz"
|
21
|
-
require "vendor/yaml_waml"
|
22
30
|
|
23
|
-
PROJECT_FN = "project.yaml"
|
24
31
|
CONFIG_FN = ".ditz-config"
|
25
32
|
PLUGIN_FN = ".ditz-plugins"
|
26
33
|
|
@@ -33,10 +40,10 @@ $opts = options do
|
|
33
40
|
opt :config_file, "Configuration file", :default => File.join(config_dir || ".", CONFIG_FN)
|
34
41
|
opt :plugins_file, "Plugins file", :default => File.join(plugin_dir || ".", PLUGIN_FN)
|
35
42
|
opt :verbose, "Verbose output", :default => false
|
36
|
-
opt :no_comment, "Skip asking for a comment", :default => false
|
37
43
|
opt :list_hooks, "List all hooks and descriptions, and quit.", :short => 'l', :default => false
|
38
44
|
stop_on_unknown
|
39
45
|
end
|
46
|
+
$verbose = true if $opts[:verbose]
|
40
47
|
|
41
48
|
Ditz::HookManager.register :startup, <<EOS
|
42
49
|
Executes at startup
|
@@ -77,18 +84,10 @@ if $opts[:list_hooks]
|
|
77
84
|
exit 0
|
78
85
|
end
|
79
86
|
|
80
|
-
|
81
|
-
Ditz::
|
82
|
-
YAML::load_file$opts[:plugins_file]
|
87
|
+
begin
|
88
|
+
Ditz::load_plugins $opts[:plugins_file]
|
83
89
|
rescue SystemCallError => e
|
84
90
|
Ditz::debug "can't load plugins file: #{e.message}"
|
85
|
-
[]
|
86
|
-
end
|
87
|
-
|
88
|
-
plugins.each do |p|
|
89
|
-
fn = Ditz::find_ditz_file "plugins/#{p}.rb"
|
90
|
-
Ditz::debug "loading plugin #{p.inspect} from #{fn}"
|
91
|
-
load fn
|
92
91
|
end
|
93
92
|
|
94
93
|
config = begin
|
@@ -109,49 +108,40 @@ EOS
|
|
109
108
|
end
|
110
109
|
end
|
111
110
|
|
112
|
-
cmd = ARGV.shift || "todo"
|
113
111
|
issue_dir = Pathname.new(config.issue_dir || $opts[:issue_dir])
|
112
|
+
cmd = ARGV.shift || "todo"
|
113
|
+
unless op.has_operation? cmd
|
114
|
+
die "no such command: #{cmd}"
|
115
|
+
end
|
114
116
|
|
115
117
|
case cmd # some special commands not handled by Ditz::Operator
|
116
118
|
when "init"
|
117
119
|
die "#{issue_dir} directory already exists" if issue_dir.exist?
|
118
120
|
issue_dir.mkdir
|
119
|
-
fn = issue_dir + PROJECT_FN
|
121
|
+
fn = issue_dir + Ditz::FileStorage::PROJECT_FN
|
120
122
|
project = op.init
|
121
123
|
project.save! fn
|
122
124
|
puts "Ok, #{issue_dir} directory created successfully."
|
123
125
|
exit
|
126
|
+
when "reconfigure" # might not be able to load the project
|
127
|
+
op.do cmd, nil, config, ARGV
|
128
|
+
exit
|
124
129
|
when "help"
|
125
|
-
op.do
|
130
|
+
op.do cmd, nil, nil, ARGV
|
126
131
|
exit
|
127
132
|
end
|
128
133
|
|
129
|
-
project_root = Ditz::find_dir_containing(issue_dir + PROJECT_FN)
|
130
|
-
die "No #{issue_dir} directory---use 'ditz init' to initialize" unless project_root
|
131
|
-
project_root += issue_dir
|
134
|
+
$project_root = Ditz::find_dir_containing(issue_dir + Ditz::FileStorage::PROJECT_FN)
|
135
|
+
die "No #{issue_dir} directory---use 'ditz init' to initialize" unless $project_root
|
136
|
+
$project_root += issue_dir
|
132
137
|
|
138
|
+
storage = Ditz::FileStorage.new $project_root
|
133
139
|
project = begin
|
134
|
-
|
135
|
-
Ditz::debug "loading project from #{fn}"
|
136
|
-
project = Ditz::Project.from fn
|
137
|
-
|
138
|
-
fn = project_root + "issue-*.yaml"
|
139
|
-
Ditz::debug "loading issues from #{fn}"
|
140
|
-
project.issues = Dir[fn].map { |fn| Ditz::Issue.from fn }
|
141
|
-
Ditz::debug "found #{project.issues.size} issues"
|
142
|
-
project
|
140
|
+
storage.load
|
143
141
|
rescue SystemCallError, Ditz::Project::Error => e
|
144
142
|
die "#{e.message} (use 'init' to initialize)"
|
145
143
|
end
|
146
144
|
|
147
|
-
project.validate!
|
148
|
-
project.issues.each { |p| p.project = project}
|
149
|
-
project.assign_issue_names!
|
150
|
-
|
151
|
-
unless op.has_operation? cmd
|
152
|
-
die "no such command: #{cmd}"
|
153
|
-
end
|
154
|
-
|
155
145
|
Ditz::HookManager.run :startup, project, config
|
156
146
|
|
157
147
|
Ditz::debug "executing command #{cmd}"
|
@@ -165,47 +155,43 @@ rescue Errno::EPIPE, Interrupt
|
|
165
155
|
exit 1
|
166
156
|
end
|
167
157
|
|
168
|
-
## save project.yaml
|
169
|
-
dirty = project.each_modelobject { |o| break true if o.changed? } || false
|
170
|
-
if dirty
|
171
|
-
fn = project_root + PROJECT_FN
|
172
|
-
Ditz::debug "project is dirty, saving #{fn}"
|
173
|
-
project.save! fn
|
174
|
-
end
|
175
|
-
|
176
|
-
## project issues are not model fields proper, so they must be
|
177
|
-
## saved independently.
|
178
158
|
changed_issues = project.issues.select { |i| i.changed? }
|
179
|
-
changed_issues
|
180
|
-
i.pathname ||= (project_root + "issue-#{i.id}.yaml")
|
181
|
-
i.project ||= project # hack: not set on new issues
|
182
|
-
Ditz::debug "issue #{i.name} is dirty, saving #{i.pathname}"
|
183
|
-
i.save! i.pathname
|
184
|
-
end
|
159
|
+
changed_not_added_issues = changed_issues - project.added_issues
|
185
160
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
end
|
161
|
+
storage.save project
|
162
|
+
|
163
|
+
## at this point, for compatibility with older hook stuff, we set the pathname
|
164
|
+
## directly on the issues.
|
191
165
|
|
166
|
+
project.issues.each { |i| i.pathname = storage.filename_for_issue(i) }
|
192
167
|
unless project.added_issues.empty?
|
193
168
|
unless Ditz::HookManager.run :after_add, project, config, project.added_issues
|
194
169
|
puts "You may have to inform your SCM that the following files have been added:"
|
195
|
-
project.added_issues.each { |i| puts " " + i
|
170
|
+
project.added_issues.each { |i| puts " " + storage.filename_for_issue(i) }
|
196
171
|
end
|
197
172
|
end
|
198
173
|
|
199
174
|
unless project.deleted_issues.empty?
|
200
175
|
unless Ditz::HookManager.run :after_delete, project, config, project.deleted_issues
|
201
176
|
puts "You may have to inform your SCM that the following files have been deleted:"
|
202
|
-
project.deleted_issues.each { |i| puts " " + i
|
177
|
+
project.deleted_issues.each { |i| puts " " + storage.filename_for_issue(i) }
|
203
178
|
end
|
204
179
|
end
|
205
180
|
|
206
|
-
changed_not_added_issues = changed_issues - project.added_issues
|
207
181
|
unless changed_not_added_issues.empty?
|
208
|
-
Ditz::HookManager.run :after_update, project, config, changed_not_added_issues
|
182
|
+
unless Ditz::HookManager.run :after_update, project, config, changed_not_added_issues
|
183
|
+
puts "You may have to inform your SCM that the following files have been modified:"
|
184
|
+
changed_not_added_issues.each { |i| puts " " + storage.filename_for_issue(i) }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
## hack upon a hack
|
189
|
+
if project.changed?
|
190
|
+
project.pathname = storage.filename_for_project
|
191
|
+
unless Ditz::HookManager.run :after_update, project, config, [project]
|
192
|
+
puts "You may have to inform your SCM that the following files have been modified:"
|
193
|
+
puts " " + storage.filename_for_project
|
194
|
+
end
|
209
195
|
end
|
210
196
|
|
211
197
|
config.save! $opts[:config_file] if config.changed?
|