ursm-ditz 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|