minglemingle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,88 @@
1
+ require 'rbconfig'
2
+ require 'find'
3
+ require 'ftools'
4
+
5
+ include Config
6
+
7
+ $ruby = CONFIG['ruby_install_name']
8
+
9
+ ##
10
+ # Install a binary file. We patch in on the way through to
11
+ # insert a #! line. If this is a Unix install, we name
12
+ # the command (for example) 'mm' and let the shebang line
13
+ # handle running it. Under windows, we add a '.rb' extension
14
+ # and let file associations to their stuff
15
+ #
16
+
17
+ def installBIN(from, opfile)
18
+
19
+ tmp_dir = nil
20
+ for t in [".", "/tmp", "c:/temp", $bindir]
21
+ stat = File.stat(t) rescue next
22
+ if stat.directory? and stat.writable?
23
+ tmp_dir = t
24
+ break
25
+ end
26
+ end
27
+
28
+ fail "Cannot find a temporary directory" unless tmp_dir
29
+ tmp_file = File.join(tmp_dir, "_tmp")
30
+
31
+ File.open(from) do |ip|
32
+ File.open(tmp_file, "w") do |op|
33
+ ruby = File.join($realbindir, $ruby)
34
+ op.puts "#!#{ruby}"
35
+ op.write ip.read
36
+ end
37
+ end
38
+
39
+ opfile += ".rb" if CONFIG["target_os"] =~ /mswin/i
40
+ File::install(tmp_file, File.join($bindir, opfile), 0755, true)
41
+ File::unlink(tmp_file)
42
+ end
43
+
44
+ $sitedir = CONFIG["sitelibdir"]
45
+ unless $sitedir
46
+ version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
47
+ $libdir = File.join(CONFIG["libdir"], "ruby", version)
48
+ $sitedir = $:.find {|x| x =~ /site_ruby/}
49
+ if !$sitedir
50
+ $sitedir = File.join($libdir, "site_ruby")
51
+ elsif $sitedir !~ Regexp.quote(version)
52
+ $sitedir = File.join($sitedir, version)
53
+ end
54
+ end
55
+
56
+ $bindir = CONFIG["bindir"]
57
+
58
+ $realbindir = $bindir
59
+
60
+ bindir = CONFIG["bindir"]
61
+ if (destdir = ENV['DESTDIR'])
62
+ $bindir = destdir + $bindir
63
+ $sitedir = destdir + $sitedir
64
+
65
+ File::makedirs($bindir)
66
+ File::makedirs($sitedir)
67
+ end
68
+
69
+ mm_dest = File.join($sitedir, "mm")
70
+ File::makedirs(mm_dest, true)
71
+ File::chmod(0755, mm_dest)
72
+
73
+ # The library files
74
+
75
+ files = Dir.chdir('lib') { Dir['**/*.rb', '**/*.rake'] }
76
+
77
+ for fn in files
78
+ fn_dir = File.dirname(fn)
79
+ target_dir = File.join($sitedir, fn_dir)
80
+ if ! File.exist?(target_dir)
81
+ File.makedirs(target_dir)
82
+ end
83
+ File::install(File.join('lib', fn), File.join($sitedir, fn), 0644, true)
84
+ end
85
+
86
+ # and the executable
87
+
88
+ installBIN("bin/mm", "mm")
@@ -0,0 +1,81 @@
1
+ # Copyright (c) 2008 Li Xiao
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'mm/utils'
16
+ require 'mm/rest_api'
17
+
18
+ require 'mm/cmds/abstract_command'
19
+ require 'mm/cmds/init'
20
+ require 'mm/cmds/run'
21
+ require 'mm/cmds/svncommit'
22
+ require 'mm/cmds/user'
23
+ require 'mm/cmds/card'
24
+ require 'mm/cmds/cards'
25
+ require 'mm/cmds/favorites'
26
+ require 'mm/cmds/tabs'
27
+ require 'mm/cmds/view'
28
+ require 'mm/cmds/help'
29
+
30
+ module MM
31
+ VERSION="0.0.1"
32
+
33
+ module API
34
+ def team_members
35
+ return @team_members if defined?(@team_members)
36
+ init(Resource::User)
37
+ @team_members = Resource::User.find(:all)
38
+ end
39
+
40
+ def property_definitions
41
+ return @property_definitions if defined?(@property_definitions)
42
+ init(Resource::PropertyDefinition)
43
+ @property_definitions = Resource::PropertyDefinition.find(:all)
44
+ end
45
+
46
+ def favorites
47
+ init(Resource::Favorite)
48
+ Resource::Favorite.find(:all)
49
+ end
50
+
51
+ def create_transition_execution(attrs)
52
+ init(Resource::TransitionExecution)
53
+ Resource::TransitionExecution.create(attrs)
54
+ end
55
+
56
+ def find_card(options)
57
+ init(Resource::Card)
58
+ Resource::Card.find(:first, options)
59
+ end
60
+
61
+ def find_card_by_number(number)
62
+ init(Resource::Card)
63
+ Resource::Card.find(number)
64
+ end
65
+
66
+ def find_cards(options)
67
+ init(Resource::Card)
68
+ Resource::Card.find(:all, :params => options)
69
+ end
70
+
71
+ def init(klass)
72
+ Command::Init.new.do_once(klass)
73
+ end
74
+
75
+ def execute_cmd(cmd)
76
+ %x[#{cmd}]
77
+ end
78
+ end
79
+ end
80
+
81
+ MM::Command::AbstractCommand.send(:include, MM::API)
@@ -0,0 +1,78 @@
1
+ # Copyright (c) 2008 Li Xiao
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require 'mm/repository'
15
+
16
+ module MM
17
+ module Command
18
+ class AbstractCommand
19
+ def run(argv)
20
+ if respond_to?(:option_parser)
21
+ option_parser.parse!(argv)
22
+ end
23
+ parse(argv) unless argv.empty?
24
+ cache_options
25
+ view do_once
26
+ end
27
+
28
+ def view(result)
29
+ output result
30
+ end
31
+
32
+ def options
33
+ @options ||= Repository.new[self.class.name] || {}
34
+ end
35
+
36
+ def parse(argv)
37
+ end
38
+
39
+ def doc
40
+ puts(respond_to?(:option_parser) ? option_parser : "No document.")
41
+ end
42
+
43
+ def cache_options
44
+ Repository.new[self.class.name] = options
45
+ end
46
+
47
+ def output(message=nil)
48
+ if block_given?
49
+ output yield
50
+ return
51
+ elsif message.is_a?(String)
52
+ puts message
53
+ elsif options[:attr]
54
+ value = if pd = property_definitions.find{|pd| pd.name.downcase == options[:attr].downcase}
55
+ property_value(pd, message)
56
+ else
57
+ message.send(options[:attr])
58
+ end
59
+ output(" * #{options[:attr]}: #{value}")
60
+ else
61
+ output(message.to_yaml)
62
+ end
63
+ end
64
+
65
+ def property_value(pd, card)
66
+ obj_value = card.send(pd.column_name)
67
+ case
68
+ when pd.card_property?(obj_value)
69
+ find_card(:id => obj_value).short_summarization
70
+ when pd.user_property?(obj_value)
71
+ team_members.find{|u|u.id==obj_value}.name
72
+ else
73
+ obj_value
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2008 Li Xiao
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require 'mm/cmds/abstract_command'
15
+
16
+ module MM
17
+ module Command
18
+ class Card < AbstractCommand
19
+ def view(card)
20
+ if options[:attr] || options[:show_all]
21
+ super(card)
22
+ else
23
+ super(card.summarization)
24
+ end
25
+ end
26
+
27
+ def do_once
28
+ output "card number => #{options[:number]}"
29
+ find_card_by_number(options[:number])
30
+ end
31
+
32
+ def parse(argv)
33
+ options[:number] = argv[0].gsub(/[^\d]/, '').strip
34
+ end
35
+
36
+ def option_parser
37
+ OptionParser.new do |opts|
38
+ opts.banner = "usage: mm card <card_number>"
39
+ opts.separator ""
40
+ opts.separator "Synopsis:"
41
+ opts.separator "mm card 1 => find card by card number 1 and show all attributes"
42
+ opts.separator "mm card 1 -a description => find card by card number 1 and show its description"
43
+ opts.separator ""
44
+ opts.separator "Options:"
45
+
46
+ opts.on_tail("-a", "--attribute ATTR_NAME", "show specified attribute value") do |attr_name|
47
+ options[:attr] = attr_name
48
+ end
49
+
50
+ opts.on_tail("-s", "--show_all", "show all card attributes") do
51
+ options[:show_all] = true
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2008 Li Xiao
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require 'mm/cmds/abstract_command'
15
+
16
+ module MM
17
+ module Command
18
+ class Cards < AbstractCommand
19
+ def view(cards)
20
+ cards.each do |card|
21
+ output '----------'
22
+ output card.short_summarization
23
+ if options[:attrs]
24
+ options[:attrs].each do |attr_name|
25
+ options[:attr] = attr_name
26
+ output card
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def do_once
33
+ output "card list params => #{options.inspect}"
34
+ find_cards(options)
35
+ end
36
+
37
+ def parse(argv)
38
+ view_options = argv.join(' ').strip
39
+ options.merge!(eval(view_options =~ /^\{.*\}$/ ? view_options : "{#{view_options}}"))
40
+ end
41
+
42
+ def option_parser
43
+ OptionParser.new do |opts|
44
+ opts.banner = "usage: mm cards [options]"
45
+ opts.separator ""
46
+ opts.separator "Synopsis:"
47
+ opts.separator "mm cards \"{:view => 'favorite/tab name'}\" => find cards by favorite's/tab's name"
48
+ opts.separator "mm cards \"{:view => 'favorite/tab name', :page => 2}\" => find cards in the page 2 by favorite's/tab's name"
49
+ opts.separator ""
50
+ opts.separator "Options:"
51
+ opts.on("-a att_name1,attr_name2", Array, "show specified attribute value.") do |names|
52
+ options[:attrs] = names
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2008 Li Xiao
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require 'mm/cmds/abstract_command'
15
+
16
+ #not finished yet
17
+ module MM
18
+ module Command
19
+ class Favorites < AbstractCommand
20
+ def view(favorites)
21
+ output "All favorites: \n#{favorites.collect{|f| " * #{f.name}"}.join("\n")}"
22
+ end
23
+
24
+ def do_once
25
+ favorites
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2008 Li Xiao
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require 'mm/cmds/abstract_command'
15
+
16
+ module MM
17
+ module Command
18
+ class Help < AbstractCommand
19
+ def do_once
20
+ return doc if options[:cmd].blank?
21
+ "#{MM.cmd_instance(options[:cmd]).doc}\n"
22
+ rescue Exception => e
23
+ "Unknow subcommand: #{options[:cmd]}\n#{doc}\n"
24
+ end
25
+
26
+ def parse(argv)
27
+ options[:cmd] = argv.first
28
+ end
29
+
30
+ #don't want to cache options of this command
31
+ def cache_options
32
+ end
33
+
34
+ def doc
35
+ %{
36
+ mingle mingle, version #{MM::VERSION}
37
+ Type 'mm help <subcommand>' for help on a specific subcommand.
38
+
39
+ Queck start:
40
+ * Suppose I am working on a project pet_store checked out at '~/pet_store'.
41
+ * cd ~/pet_store
42
+ * mm init http://my_login:password@mingle_server/projects/pet_store
43
+ * mm cards => list first page cards on All tab
44
+ * mm view My Work -a owner,priority => list cards on card list view named 'My Work' including property owner and priority
45
+ * mm card 102 => show name and description of the card
46
+ * mm run 'Start fix #102' => run transition 'Start fix' on card 102
47
+ * mm svnci -m "[complete development #1 with 'fixed revision' => \#{revision}, resolution => fixed (some comment)] blabla..." => commit code and run transition script inside of []
48
+ * mm view => show view cached which is 'My Work' with property 'owner' and 'priority' by last time using view command
49
+ * mm card => show card cached number of which is 102 by last time using card command
50
+
51
+ Available subcommands:
52
+ help [subcommand] show help doc of subcommand
53
+ init [url] init MingleMingle working directory with Mingle REST api project base url
54
+ card [number] show card content by card number
55
+ cards [params] show cards by params, it will do nothing without params.
56
+ user [id/login] show user info by id/login
57
+ view name show cards find by view/tab name
58
+ run script run transition
59
+ svncommit(svnci) run transition execution script inside the commit message after committed code(subversion)
60
+
61
+ MingleMingle is a tool for integrating Mingle(http://studios.thoughtworks.com/) with command-line
62
+ For additional information, see http://minglemingle.rubyforge.org
63
+ Notes:
64
+ * In the command line, should use \\! instead of !.
65
+ * There would be a '.mm_pstore' file created for cache in the MingleMingle working directory.
66
+ }
67
+ end
68
+ end
69
+ end
70
+ end