git-trac 0.0.20080206 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,8 +4,12 @@ module Git
4
4
 
5
5
  class Show < Base #:nodoc:
6
6
 
7
+ def self.summary
8
+ "Show an attachment or a list of attachments"
9
+ end
10
+
7
11
  def banner_arguments
8
- "[ticket[/filename]]"
12
+ "[<ticket> | <attachment> | branches | rebased | today]"
9
13
  end
10
14
 
11
15
  def description
@@ -13,6 +17,11 @@ module Git
13
17
  Show the given ticket attachment. The patch will be highlighted in a manner
14
18
  If the filename is omitted, show a list of attachments for the ticket.
15
19
 
20
+ If the literal word "branches" is given, a list of all remote heads is output,
21
+ followed by the branches that refer to them. A literal "rebased" also shows
22
+ branches that appear to be rebased attachments. These rebased branches will be
23
+ shown in brackets.
24
+
16
25
  Attachments can be downloaded by redirecting to a file. The following example
17
26
  shows how one might download all patches for a given ticket:
18
27
 
@@ -23,21 +32,59 @@ shows how one might download all patches for a given ticket:
23
32
  end
24
33
 
25
34
  def run
26
- each_ticket_argument do |number, filename|
27
- ticket = @repository.ticket(number)
28
- if filename
29
- attachment = ticket.attachment(filename)
30
- @repository.pager(attachment.body, filename =~ /\.(diff|patch)$/)
35
+ if [[], %w(branches), %w(rebased)].include?(@argv)
36
+ puts branches(@argv == %w(rebased))
37
+ return
38
+ elsif %w(today) == @argv
39
+ Pager.new.page(today)
40
+ return
41
+ end
42
+ each_ticket_or_attachment do |ticket|
43
+ if ticket.respond_to?(:body)
44
+ repository.pager(ticket.body, %w(.diff .patch).include?(ticket.extension))
31
45
  else
32
46
  body = ticket.attachments.map do |attachment|
33
- "#{number}/#{attachment.filename}\n"
47
+ "#{attachment.ticket.number}/#{attachment.filename}\n"
34
48
  end.join
35
49
  exit(1) if body.empty?
36
- @repository.pager(body)
50
+ repository.pager(body)
37
51
  end
38
52
  end
39
53
  end
40
54
 
55
+ def branches(rebased = false)
56
+ output = ""
57
+ current_checkout = repository.current_checkout
58
+ branches = []
59
+ repository.each_ref("refs/heads") do |object, ref|
60
+ branches << [ref.sub(/^refs\/heads\//,''), object]
61
+ branches.last << (rebased ? repository.diff_hash(object) : nil)
62
+ end
63
+ repository.each_ref("refs/remotes/trac") do |object, ref|
64
+ current = (object == current_checkout)
65
+ line = ref.sub(/^refs\/remotes\//,'')
66
+ diff_hash = rebased && repository.diff_hash(object)
67
+ branches.each do |(branch,branch_object,branch_hash)|
68
+ if object == branch_object
69
+ line << " <#{branch}>"
70
+ elsif diff_hash == branch_hash
71
+ line << " [#{branch}]"
72
+ current ||= (branch == current_checkout)
73
+ end
74
+ end
75
+ output << (current ? "* " : " ") + line + "\n"
76
+ end
77
+ output
78
+ end
79
+
80
+ def today(days_back = 2)
81
+ require 'hpricot'
82
+ response = repository.get_response("#{repository.url}/timeline?ticket_details=on&max=#{50*days_back}&daysback=#{days_back}&format=rss")
83
+ response.error! unless response.kind_of?(Net::HTTPSuccess)
84
+ h = Hpricot(response.body)
85
+ (h/:title).map {|y| y.inner_text.match(/^(.*) attached to ticket #(\d+)$/) && "#$2/#$1\n"}.compact.join
86
+ end
87
+
41
88
  end
42
89
 
43
90
  end
@@ -24,14 +24,8 @@ module Git
24
24
  "#{@repository.url}/attachment/ticket/#{@number}"
25
25
  end
26
26
 
27
- def get_response(uri)
28
- require 'net/http'
29
- require 'uri'
30
- Net::HTTP.get_response(URI.parse(uri))
31
- end
32
-
33
27
  def csv
34
- response = get_response(url(:tab))
28
+ response = repository.get_response(url(:tab))
35
29
  no_such_ticket if response.kind_of?(Net::HTTPInternalServerError)
36
30
  response.error! unless response.kind_of?(Net::HTTPSuccess)
37
31
  body = response.body
@@ -53,7 +47,7 @@ module Git
53
47
  attr_reader :number
54
48
 
55
49
  def attachments
56
- response = get_response(attachment_url)
50
+ response = repository.get_response(attachment_url)
57
51
  if html = response.body[/<dl class="attachments">.*?<\/dl>/m]
58
52
  return Attachment.from_html(self,html)
59
53
  elsif response.kind_of?(Net::HTTPSuccess)
@@ -77,26 +71,6 @@ module Git
77
71
  "#{repository.git_dir}/refs/remotes/trac/#{number}"
78
72
  end
79
73
 
80
- class Form
81
- def initialize(mech_form)
82
- @mech_form = mech_form
83
- end
84
-
85
- def submit(*args)
86
- @mech_form.submit
87
- end
88
-
89
- def method_missing(method,*args,&block)
90
- if method.to_s[-1] == "=" && @mech_form.fields.name(method.to_s[0..-2]).any?
91
- @mech_form.fields.name(method.to_s[0..-2]).send(:value=,*args,&block)
92
- elsif @mech_form.fields.name(method.to_s).any?
93
- @mech_form.fields.name(method.to_s).send(:value,*args,&block)
94
- else
95
- super(method,*args,&block)
96
- end
97
- end
98
- end
99
-
100
74
  def form
101
75
  repository.agent.get(url).forms.last
102
76
  end
@@ -124,8 +98,9 @@ module Git
124
98
 
125
99
  def upload_patch(options = {})
126
100
  filename = options[:filename] || "#{File.basename(repository.current_checkout)}.patch"
127
- # diff = repository.exec("git-diff","#{options[:branch] || "trunk"}...HEAD")
128
- diff = repository.exec("git","diff", options[:branch] || "trunk...HEAD")
101
+ upstream = options[:upstream] || "refs/remotes/trunk"
102
+ upstream += "...HEAD" unless upstream.include?(".")
103
+ diff = repository.exec("git","diff",upstream)
129
104
  return false if diff.empty?
130
105
  # Don't upload the exact same patch that was pulled down
131
106
  return false if repository.generated_commits[repository.rev_parse("HEAD")] == number
@@ -143,29 +118,20 @@ module Git
143
118
  def cleanup(options = {})
144
119
  revs = []
145
120
  repository.each_ref("refs/remotes/trac/#{number}") do |object, ref|
146
- if File.basename(ref) == options[:attachment] || !options[:attachment]
147
- revs << object
148
- repository.exec("git","update-ref","-d",ref,object)
149
- end
121
+ revs << object
122
+ repository.exec("git","update-ref","-d",ref,object) unless options[:only_branches]
123
+ end
124
+ begin
125
+ Dir.unlink("#{repository.git_dir}/refs/remotes/trac/#{number}")
126
+ rescue Errno::ENOENT, Errno::ENOTEMPTY
150
127
  end
151
- repository.cleanup_branches(*revs)
152
128
  revs.any?
153
129
  end
154
130
 
155
- def fetch(options = {})
131
+ def fetch(options = {}, &block)
156
132
  cleanup(options)
157
- seen = {}
158
- attachments.select do |attachment|
159
- attachment.filename =~ /#{options[:filter] || "\\.(diff|patch)$"}/
160
- end.map do |attachment|
161
- commit, applied = attachment.fetch(options)
162
- yield attachment, applied if block_given?
163
- seen[attachment.name] = commit if commit
164
- end
165
- seen.each do |k,v|
166
- if !File.exists?(path = "#{repository.git_dir}/refs/heads/#{k}")
167
- File.open(path, "w") {|f| f.puts v}
168
- end
133
+ attachments.each do |attachment|
134
+ attachment.fetch(options,&block)
169
135
  end
170
136
  end
171
137
 
@@ -0,0 +1,11 @@
1
+ module Git
2
+ module Trac
3
+ module VERSION #:nodoc:
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ TINY = 0
7
+
8
+ STRING = [MAJOR, MINOR, TINY].join('.')
9
+ end
10
+ end
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-trac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20080206
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Pope
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-02-06 00:00:00 -06:00
12
+ date: 2008-02-11 00:00:00 -06:00
13
13
  default_executable: git-trac
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -21,7 +21,7 @@ dependencies:
21
21
  - !ruby/object:Gem::Version
22
22
  version: 0.6.8
23
23
  version:
24
- description: git-trac takes the repetition out of working with trac and git-svn. Among other features is the ability to easily attach a patch to a ticket and to pull all patches from a ticket and turn them into git branches. Created for (but not limited to) work on the Ruby on Rails core.
24
+ description: git-trac takes the repetition out of working with trac and git-svn. Easily download a patch, apply it at the right point in time, turn it into a commit with useful metadata, and check it out into a branch, all in one command. Created for (but not limited to) work on the Ruby on Rails core.
25
25
  email: ruby@tpope.info
26
26
  executables:
27
27
  - git-trac
@@ -36,19 +36,21 @@ files:
36
36
  - bin/git-trac
37
37
  - lib/git/trac.rb
38
38
  - lib/git/trac/attachment.rb
39
- - lib/git/trac/repository.rb
40
- - lib/git/trac/runner.rb
41
- - lib/git/trac/ticket.rb
42
39
  - lib/git/trac/pager.rb
43
40
  - lib/git/trac/patch.rb
44
- - lib/git/trac/runner/download.rb
45
- - lib/git/trac/runner/show.rb
46
- - lib/git/trac/runner/fetch.rb
47
- - lib/git/trac/runner/cleanup.rb
48
- - lib/git/trac/runner/upload_patch.rb
41
+ - lib/git/trac/repository.rb
42
+ - lib/git/trac/runner.rb
49
43
  - lib/git/trac/runner/apply.rb
50
- - test/execution_test.rb
44
+ - lib/git/trac/runner/cleanup.rb
45
+ - lib/git/trac/runner/fetch.rb
46
+ - lib/git/trac/runner/help.rb
47
+ - lib/git/trac/runner/push.rb
48
+ - lib/git/trac/runner/show.rb
49
+ - lib/git/trac/runner/checkout.rb
50
+ - lib/git/trac/ticket.rb
51
+ - lib/git/trac/version.rb
51
52
  - test/attachment_test.rb
53
+ - test/execution_test.rb
52
54
  has_rdoc: true
53
55
  homepage: http://git-trac.rubyforge.org
54
56
  post_install_message:
@@ -1,44 +0,0 @@
1
- module Git
2
- module Trac
3
- class Runner
4
-
5
- class Download < Base #:nodoc:
6
-
7
- def description
8
- <<-EOF
9
- Download all attachments that look like patches to the current working
10
- directory.
11
-
12
- This command is a candidate for removal. Individual patches can be downloaded
13
- by redirecting git-trac show to a file.
14
- EOF
15
- end
16
-
17
- def banner_arguments
18
- "[options] [ticket[/filename]] ..."
19
- end
20
-
21
- def add_options(opts)
22
- require_ticket_number
23
- opts.separator("Options:")
24
- opts.on("--root DIR","prefix patch paths with DIR") do |dir|
25
- options[:root] = dir
26
- end
27
- end
28
-
29
- def run
30
- each_ticket_argument do |number, filename|
31
- @repository.ticket(number).attachments.each do |attach|
32
- next if filename && attach.filename != filename
33
- File.open(attach.filename, "w") do |f|
34
- f.puts attach.patch.with_root(options[:root])
35
- end
36
- end
37
- end
38
- end
39
-
40
- end
41
-
42
- end
43
- end
44
- end
@@ -1,62 +0,0 @@
1
- module Git
2
- module Trac
3
- class Runner
4
-
5
- class UploadPatch < Base #:nodoc:
6
-
7
- def banner_arguments
8
- "[options] [ticket]"
9
- end
10
-
11
- def description
12
- <<-EOF
13
- Do a `git diff` against trunk (or another branch) and upload the result as an
14
- attachment to a ticket. The potential patch will be shown in a pager and you
15
- will be given the opportunity to cancel.
16
- EOF
17
- end
18
-
19
- def add_options(opts)
20
- require_ticket_number
21
- opts.on("--branch BRANCH", "git diff BRANCH (default trunk...HEAD)") do |b|
22
- options[:branch] = b
23
- end
24
- opts.on("--description TEXT", "use TEXT as description") do |text|
25
- options[:description] = text
26
- end
27
- opts.on("--[no-]force", "do not prompt before uploading") do |force|
28
- options[:force] = force
29
- end
30
- add_local_option(opts)
31
- end
32
-
33
- def run
34
- number = get_ticket_number
35
- fetch_unless_local
36
- ticket = @repository.ticket(number)
37
- if $stdin.tty? && !options[:force]
38
- block = lambda do
39
- @repository.in_work_tree do
40
- system("git","diff", options[:branch] || "trunk...HEAD")
41
- end
42
- description = "##{number} (#{ticket.csv["summary"]}"
43
- cols = ENV["COLUMNS"].to_i
44
- cols = 80 if cols.zero?
45
- description.sub!(/^(.{#{cols-22}}).{4,}/,"\\1...")
46
- print "#{description}) Proceed? [yN] "
47
- $stdin.gets[0,1] == "y"
48
- end
49
- else
50
- block = lambda { true }
51
- end
52
- if uri = ticket.upload_patch(options,&block)
53
- puts uri
54
- else
55
- exit 1
56
- end
57
- end
58
- end
59
-
60
- end
61
- end
62
- end