fogbugz 1.0.1 → 1.0.2

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/bin/fogbugz-show CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'typhoeus'
5
- require 'xml'
4
+ require 'net/https'
5
+ require 'uri'
6
+ require 'rexml/document'
6
7
  require 'optparse'
7
- require 'term/ansicolor'
8
+ require 'highline'
8
9
  require 'time'
9
10
 
10
11
  api_url = ENV['FOGBUGZ_API_URL']
@@ -14,7 +15,7 @@ unless api_url
14
15
  end
15
16
 
16
17
  api_token = ENV['FOGBUGZ_API_TOKEN']
17
- unless api_url
18
+ unless api_token
18
19
  puts "Environment variable FOGBUGZ_API_TOKEN must be set."
19
20
  exit 1
20
21
  end
@@ -23,11 +24,6 @@ options = {}
23
24
  optparse = OptionParser.new do |opts|
24
25
  opts.banner = "usage: #{File::basename(__FILE__)} [options] <case>"
25
26
 
26
- options[:verbose] = false
27
- opts.on('-v', '--verbose', 'Output verbose debugging information') do
28
- options[:verbose] = true
29
- end
30
-
31
27
  opts.on_tail('-h', '--help') do
32
28
  puts optparse.help
33
29
  exit 1
@@ -40,108 +36,111 @@ unless ARGV[0]
40
36
  exit 1
41
37
  end
42
38
 
43
- response = Typhoeus::Request.get(api_url,
44
- :verbose => options[:verbose],
45
- :params => {
46
- :cmd => 'search',
47
- :token => api_token,
48
- :cols => 'ixBug,ixBugParent,tags,sTitle,sProject,sArea,sFixFor,sCategory,sPersonAssignedTo,sPriority,hrsCurrEst,events',
49
- :q => ARGV[0] })
50
- if response.code != 200
39
+ uri = URI format("#{api_url}?cmd=search&token=%s&cols=%s&q=%s&max=1",
40
+ URI.escape(api_token),
41
+ URI.escape('ixBug,ixBugParent,tags,sTitle,sProject,sArea,sFixFor,sCategory,sPersonAssignedTo,sPriority,hrsCurrEst,events'),
42
+ URI.escape(ARGV[0]))
43
+ http = Net::HTTP.new(uri.host, uri.port)
44
+ if uri.scheme == 'https'
45
+ http.use_ssl = true
46
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
47
+ end
48
+ response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
49
+ if response.code != '200'
51
50
  puts "HTTP request to #{api_url} failed with code #{response.code}."
52
51
  exit 1
53
52
  end
54
53
 
55
- result = XML::Parser.string(response.body).parse
56
- error = result.find_first('/response/error')
54
+ result = REXML::Document.new(response.body)
55
+ error = result.elements['/response/error']
57
56
  if error
58
- puts "Failed with error: #{error.content}."
57
+ puts "Failed with error: #{error.text}."
59
58
  exit 1
60
59
  end
61
60
 
62
- r = STDOUT.isatty ? Term::ANSIColor::reset : ''
63
- g = STDOUT.isatty ? Term::ANSIColor::green : ''
64
- b = STDOUT.isatty ? Term::ANSIColor::blue : ''
61
+ HighLine.use_color = STDOUT.isatty
62
+ hl = HighLine.new
65
63
 
66
- bug = result.find_first "/response/cases/case[@ixBug='#{ARGV[0]}']"
64
+ bug = result.elements["/response/cases/case[@ixBug='#{ARGV[0]}']"]
67
65
  unless bug
68
66
  puts "Case #{ARGV[0]} does not exist."
69
67
  exit 1
70
68
  end
71
69
 
72
- puts "#{b}case: #{r}#{ARGV[0]}"
70
+ puts "#{hl.color('case:', HighLine::BLUE)} #{ARGV[0]}"
73
71
 
74
- sTitle = bug.find_first('sTitle')
75
- if sTitle and sTitle.content and not sTitle.content.empty?
76
- puts "#{b}title: #{r}#{sTitle.content}"
72
+ sTitle = bug.elements['sTitle']
73
+ if sTitle and sTitle.text and not sTitle.text.empty?
74
+ puts "#{hl.color('title:', HighLine::BLUE)} #{sTitle.text}"
77
75
  end
78
76
 
79
- sPersonAssignedTo = bug.find_first('sPersonAssignedTo')
80
- if sPersonAssignedTo and sPersonAssignedTo.content and
81
- not sPersonAssignedTo.content.empty?
82
- puts "#{b}assignee: #{r}#{sPersonAssignedTo.content}"
77
+ sPersonAssignedTo = bug.elements['sPersonAssignedTo']
78
+ if sPersonAssignedTo and sPersonAssignedTo.text and
79
+ not sPersonAssignedTo.text.empty?
80
+ puts "#{hl.color('assignee:', HighLine::BLUE)} #{sPersonAssignedTo.text}"
83
81
  end
84
82
 
85
- ixBugParent = bug.find_first('ixBugParent')
86
- if ixBugParent and ixBugParent.content and not ixBugParent.content.empty? and
87
- ixBugParent.content != '0'
88
- puts "#{b}parent: #{r}#{ixBugParent.content}"
83
+ ixBugParent = bug.elements['ixBugParent']
84
+ if ixBugParent and ixBugParent.text and not ixBugParent.text.empty? and
85
+ ixBugParent.text != '0'
86
+ puts "#{hl.color('parent:', HighLine::BLUE)} #{ixBugParent.text}"
89
87
  end
90
88
 
91
- tags = bug.find('tags/tag').collect { |tag| tag.content }
89
+ tags = bug.elements.collect('tags/tag') { |tag| tag.text }
92
90
  if tags and not tags.empty?
93
- puts "#{b}tags: #{r}[#{tags.join(', ')}]"
91
+ puts "#{hl.color('tags:', HighLine::BLUE)} [#{tags.join(', ')}]"
94
92
  end
95
93
 
96
- sProject = bug.find_first('sProject')
97
- if sProject and sProject.content and not sProject.content.empty?
98
- puts "#{b}project: #{r}#{sProject.content}"
94
+ sProject = bug.elements['sProject']
95
+ if sProject and sProject.text and not sProject.text.empty?
96
+ puts "#{hl.color('project:', HighLine::BLUE)} #{sProject.text}"
99
97
  end
100
98
 
101
- sArea = bug.find_first('sArea')
102
- if sArea and sArea.content and not sArea.content.empty?
103
- puts "#{b}area: #{r}#{sArea.content}"
99
+ sArea = bug.elements['sArea']
100
+ if sArea and sArea.text and not sArea.text.empty?
101
+ puts "#{hl.color('area:', HighLine::BLUE)} #{sArea.text}"
104
102
  end
105
103
 
106
- sFixFor = bug.find_first('sFixFor')
107
- if sFixFor and sFixFor.content and not sFixFor.content.empty?
108
- puts "#{b}milestone: #{r}#{sFixFor.content}"
104
+ sFixFor = bug.elements['sFixFor']
105
+ if sFixFor and sFixFor.text and not sFixFor.text.empty?
106
+ puts "#{hl.color('milestone:', HighLine::BLUE)} #{sFixFor.text}"
109
107
  end
110
108
 
111
- sCategory = bug.find_first('sCategory')
112
- if sCategory and sCategory.content and not sCategory.content.empty?
113
- puts "#{b}category: #{r}#{sCategory.content}"
109
+ sCategory = bug.elements['sCategory']
110
+ if sCategory and sCategory.text and not sCategory.text.empty?
111
+ puts "#{hl.color('category:', HighLine::BLUE)} #{sCategory.text}"
114
112
  end
115
113
 
116
- sPriority = bug.find_first('sPriority')
117
- if sPriority and sPriority.content and not sPriority.content.empty?
118
- puts "#{b}priority: #{r}#{sPriority.content}"
114
+ sPriority = bug.elements['sPriority']
115
+ if sPriority and sPriority.text and not sPriority.text.empty?
116
+ puts "#{hl.color('priority:', HighLine::BLUE)} #{sPriority.text}"
119
117
  end
120
118
 
121
- hrsCurrEst = bug.find_first('hrsCurrEst')
122
- if hrsCurrEst and hrsCurrEst.content and not hrsCurrEst.content.empty? and
123
- hrsCurrEst.content != '0'
124
- puts "#{b}estimate: #{r}#{hrsCurrEst.content}"
119
+ hrsCurrEst = bug.elements['hrsCurrEst']
120
+ if hrsCurrEst and hrsCurrEst.text and not hrsCurrEst.text.empty? and
121
+ hrsCurrEst.text != '0'
122
+ puts "#{hl.color('estimate:', HighLine::BLUE)} #{hrsCurrEst.text}"
125
123
  end
126
124
 
127
125
  puts "\n"
128
- bug.find('events/event').each do |event|
129
- evtDescription = event.find_first('evtDescription')
130
- if evtDescription and evtDescription.content and
131
- not evtDescription.content.empty?
132
- time = Time.parse(event.find_first('dt').content).localtime
133
- printf("#{g}%s at %s on %s.\n", evtDescription.content,
134
- time.strftime('%-l:%M %p'), time.strftime('%A, %B %e %Y'))
126
+ bug.elements.each('events/event') do |event|
127
+ evtDescription = event.elements['evtDescription']
128
+ if evtDescription and evtDescription.text and
129
+ not evtDescription.text.empty?
130
+ time = Time.parse(event.elements['dt'].text).localtime
131
+ header = format("%s at %s on %s.", evtDescription.text,
132
+ time.strftime('%-l:%M %p'), time.strftime('%A, %B %e %Y'))
133
+ puts hl.color(header, HighLine::GREEN)
135
134
  end
136
135
 
137
- sChanges = event.find_first('sChanges')
138
- if sChanges and sChanges.content and not sChanges.content.empty?
139
- puts "#{b}#{sChanges.content}"
136
+ sChanges = event.elements['sChanges']
137
+ if sChanges and sChanges.text and not sChanges.text.empty?
138
+ puts hl.color(sChanges.text, HighLine::BLUE)
140
139
  end
141
140
 
142
- summary = event.find_first('s')
143
- if summary and summary.content and not summary.content.empty?
144
- puts "#{r}#{summary.content}"
141
+ summary = event.elements['s']
142
+ if summary and summary.text and not summary.text.empty?
143
+ puts summary.text
145
144
  end
146
- puts "#{r}"
145
+ puts ''
147
146
  end
data/bin/fogbugz-start CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'typhoeus'
5
- require 'xml'
4
+ require 'net/https'
5
+ require 'uri'
6
+ require 'rexml/document'
6
7
  require 'optparse'
7
8
 
8
9
  api_url = ENV['FOGBUGZ_API_URL']
@@ -12,7 +13,7 @@ unless api_url
12
13
  end
13
14
 
14
15
  api_token = ENV['FOGBUGZ_API_TOKEN']
15
- unless api_url
16
+ unless api_token
16
17
  puts "Environment variable FOGBUGZ_API_TOKEN must be set."
17
18
  exit 1
18
19
  end
@@ -21,11 +22,6 @@ options = {}
21
22
  optparse = OptionParser.new do |opts|
22
23
  opts.banner = "usage: #{File::basename(__FILE__)} [options] <case>"
23
24
 
24
- options[:verbose] = false
25
- opts.on('-v', '--verbose', 'Output verbose debugging information.') do
26
- options[:verbose] = true
27
- end
28
-
29
25
  opts.on_tail('-h', '--help') do
30
26
  puts optparse.help
31
27
  exit 1
@@ -37,19 +33,22 @@ unless ARGV[0]
37
33
  exit 1
38
34
  end
39
35
 
40
- response = Typhoeus::Request.get(api_url,
41
- :verbose => options[:verbose],
42
- :params => {
43
- :cmd => 'startWork',
44
- :token => api_token,
45
- :ixBug => ARGV[0] })
46
- if response.code != 200
36
+ uri = URI format("#{api_url}?cmd=startWork&token=%s&ixBug=%s",
37
+ URI.escape(api_token), URI.escape(ARGV[0]))
38
+ http = Net::HTTP.new(uri.host, uri.port)
39
+ if uri.scheme == 'https'
40
+ http.use_ssl = true
41
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
42
+ end
43
+ response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
44
+ if response.code != '200'
47
45
  puts "HTTP request to #{api_url} failed with code #{response.code}."
48
46
  exit 1
49
47
  end
50
48
 
51
- error = XML::Parser.string(response.body).parse.find_first('/response/error')
49
+ result = REXML::Document.new(response.body)
50
+ error = result.elements['/response/error']
52
51
  if error
53
- puts "Failed with error: #{error.content}."
52
+ puts "Failed with error: #{error.text}."
54
53
  exit 1
55
54
  end
data/bin/fogbugz-statuses CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'typhoeus'
5
- require 'xml'
4
+ require 'net/https'
5
+ require 'uri'
6
+ require 'rexml/document'
6
7
  require 'optparse'
7
- require 'set'
8
8
 
9
9
  api_url = ENV['FOGBUGZ_API_URL']
10
10
  unless api_url
@@ -13,7 +13,7 @@ unless api_url
13
13
  end
14
14
 
15
15
  api_token = ENV['FOGBUGZ_API_TOKEN']
16
- unless api_url
16
+ unless api_token
17
17
  puts "Environment variable FOGBUGZ_API_TOKEN must be set."
18
18
  exit 1
19
19
  end
@@ -22,11 +22,6 @@ options = {}
22
22
  optparse = OptionParser.new do |opts|
23
23
  opts.banner = "usage: #{File::basename(__FILE__)} [options]"
24
24
 
25
- options[:verbose] = false
26
- opts.on('-v', '--verbose', 'Output verbose debugging information') do
27
- options[:verbose] = true
28
- end
29
-
30
25
  opts.on_tail('-h', '--help') do
31
26
  puts optparse.help
32
27
  exit 1
@@ -39,24 +34,27 @@ optparse = OptionParser.new do |opts|
39
34
  end
40
35
  optparse.parse!
41
36
 
42
- response = Typhoeus::Request.get(api_url,
43
- :verbose => options[:verbose],
44
- :params => {
45
- :cmd => 'listStatuses',
46
- :token => api_token,
47
- :fResolved => options[:resolved] ? 1 : nil })
48
- if response.code != 200
37
+ uri = URI format("#{api_url}?cmd=listStatuses&token=%s%s",
38
+ URI.escape(api_token),
39
+ options[:resolved] ? '&fResolved=1' : '')
40
+ http = Net::HTTP.new(uri.host, uri.port)
41
+ if uri.scheme == 'https'
42
+ http.use_ssl = true
43
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
44
+ end
45
+ response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
46
+ if response.code != '200'
49
47
  puts "HTTP request to #{api_url} failed with code #{response.code}."
50
48
  exit 1
51
49
  end
52
50
 
53
- result = XML::Parser.string(response.body).parse
54
- error = result.find_first('/response/error')
51
+ result = REXML::Document.new(response.body)
52
+ error = result.elements['/response/error']
55
53
  if error
56
- puts "Failed with error: #{error.content}."
54
+ puts "Failed with error: #{error.text}."
57
55
  exit 1
58
56
  end
59
57
 
60
- result.find('/response/statuses/status').map { |s|
61
- s.find_first('sStatus').content
58
+ result.elements.to_a('/response/statuses/status').map { |s|
59
+ s.elements['sStatus'].text
62
60
  }.uniq!.sort!.each { |s| puts s }
data/bin/fogbugz-stop CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'typhoeus'
5
- require 'xml'
4
+ require 'net/https'
5
+ require 'uri'
6
+ require 'rexml/document'
6
7
  require 'optparse'
7
8
 
8
9
  api_url = ENV['FOGBUGZ_API_URL']
@@ -12,7 +13,7 @@ unless api_url
12
13
  end
13
14
 
14
15
  api_token = ENV['FOGBUGZ_API_TOKEN']
15
- unless api_url
16
+ unless api_token
16
17
  puts "Environment variable FOGBUGZ_API_TOKEN must be set."
17
18
  exit 1
18
19
  end
@@ -21,11 +22,6 @@ options = {}
21
22
  optparse = OptionParser.new do |opts|
22
23
  opts.banner = "usage: #{File::basename(__FILE__)} [options]"
23
24
 
24
- options[:verbose] = false
25
- opts.on('-v', '--verbose', 'Output verbose debugging information.') do
26
- options[:verbose] = true
27
- end
28
-
29
25
  opts.on_tail('-h', '--help') do
30
26
  puts optparse.help
31
27
  exit 1
@@ -33,18 +29,21 @@ optparse = OptionParser.new do |opts|
33
29
  end
34
30
  optparse.parse!
35
31
 
36
- response = Typhoeus::Request.get(api_url,
37
- :verbose => options[:verbose],
38
- :params => {
39
- :cmd => 'stopWork',
40
- :token => api_token })
41
- if response.code != 200
32
+ uri = URI format("#{api_url}?cmd=stopWork&token=%s", URI.escape(api_token))
33
+ http = Net::HTTP.new(uri.host, uri.port)
34
+ if uri.scheme == 'https'
35
+ http.use_ssl = true
36
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
37
+ end
38
+ response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
39
+ if response.code != '200'
42
40
  puts "HTTP request to #{api_url} failed with code #{response.code}."
43
41
  exit 1
44
42
  end
45
43
 
46
- error = XML::Parser.string(response.body).parse.find_first('/response/error')
44
+ result = REXML::Document.new(response.body)
45
+ error = result.elements['/response/error']
47
46
  if error
48
- puts "Failed with error: #{error.content}."
47
+ puts "Failed with error: #{error.text}."
49
48
  exit 1
50
49
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 0
8
- - 1
9
- version: 1.0.1
8
+ - 2
9
+ version: 1.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Erik Charlebois
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-05-21 00:00:00 -04:00
17
+ date: 2012-05-22 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: typhoeus
21
+ name: highline
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
@@ -29,30 +29,6 @@ dependencies:
29
29
  version: "0"
30
30
  type: :runtime
31
31
  version_requirements: *id001
32
- - !ruby/object:Gem::Dependency
33
- name: libxml-ruby
34
- prerelease: false
35
- requirement: &id002 !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- segments:
40
- - 0
41
- version: "0"
42
- type: :runtime
43
- version_requirements: *id002
44
- - !ruby/object:Gem::Dependency
45
- name: term-ansicolor
46
- prerelease: false
47
- requirement: &id003 !ruby/object:Gem::Requirement
48
- requirements:
49
- - - ">="
50
- - !ruby/object:Gem::Version
51
- segments:
52
- - 0
53
- version: "0"
54
- type: :runtime
55
- version_requirements: *id003
56
32
  description:
57
33
  email: erikcharlebois@gmail.com
58
34
  executables: