djanowski-helm 0.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/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2008 Damian Janowski
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1 @@
1
+ Helm
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'rake'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/clean'
4
+ require 'spec/rake/spectask'
5
+
6
+ gem_spec_file = 'helm.gemspec'
7
+
8
+ gem_spec = eval(File.read(gem_spec_file)) rescue nil
9
+
10
+ Rake::GemPackageTask.new(gem_spec) do |pkg|
11
+ pkg.need_zip = false
12
+ pkg.need_tar = false
13
+ rm_f FileList['pkg/**/*.*']
14
+ end if gem_spec
15
+
16
+ task :default => :spec
17
+
18
+ desc "Run all specs"
19
+ Spec::Rake::SpecTask.new(:spec) do |t|
20
+ t.spec_opts = ['--options', "\"spec/spec.opts\""]
21
+ t.spec_files = FileList['spec/**/*_spec.rb']
22
+ end
23
+
24
+ desc "Generate the gemspec file."
25
+ task :gemspec do
26
+ require 'erb'
27
+
28
+ File.open(gem_spec_file, 'w') do |f|
29
+ f.write ERB.new(File.read("#{gem_spec_file}.erb")).result(binding)
30
+ end
31
+ end
32
+
33
+ desc "Builds and installs the gem."
34
+ task :install => :repackage do
35
+ `sudo gem install pkg/#{gem_spec.name}-#{gem_spec.version}.gem`
36
+ end
data/bin/helm ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ require File.dirname(__FILE__) + '/../lib/helm'
6
+
7
+ require 'yaml'
8
+
9
+ def load_config(file)
10
+ file = File.expand_path(file)
11
+
12
+ return {} unless File.exist?(file)
13
+
14
+ yaml = YAML::load_file(file)
15
+
16
+ yaml = yield(yaml) if block_given?
17
+
18
+ yaml.each do |k,v|
19
+ ARGV << "--#{k}=#{v}"
20
+ end if yaml
21
+
22
+ yaml
23
+ end
24
+
25
+ def argv(key)
26
+ start = "--#{key}="
27
+
28
+ value = ARGV.detect do |v|
29
+ v =~ /^#{Regexp.escape(start)}/
30
+ end
31
+
32
+ value[start.size..-1] if value
33
+ end
34
+
35
+ local_config = load_config('.helm_config')
36
+
37
+ load_config('~/.helm_config') do |opts|
38
+ opts[argv(:url)]
39
+ end
40
+
41
+ Helm::Commands.const_get(ARGV.first.capitalize).new(Helm::Session.new).run
data/lib/helm.rb ADDED
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/helm/lighthouse'
2
+ require File.dirname(__FILE__) + '/helm/session'
3
+
4
+ require File.dirname(__FILE__) + '/helm/commands/command'
5
+ require File.dirname(__FILE__) + '/helm/commands/info'
6
+ require File.dirname(__FILE__) + '/helm/commands/assign'
7
+ require File.dirname(__FILE__) + '/helm/commands/create'
8
+ require File.dirname(__FILE__) + '/helm/commands/resolve'
@@ -0,0 +1,29 @@
1
+ module Helm
2
+ module Commands
3
+ class Assign < Command
4
+ def run
5
+ ticket = session.ticket
6
+
7
+ if session.milestone
8
+ ticket.milestone_id = session.milestone.id
9
+
10
+ if ticket.save
11
+ puts "##{ticket.id} Milestone changed: #{session.milestone || '(none)'} => #{session.milestone}"
12
+ end
13
+ else
14
+ new_assignee = session.user
15
+
16
+ assignee = session.user(ticket.assigned_user_id) if ticket.assigned_user_id
17
+
18
+ unless ticket.assigned_user_id && ticket.assigned_user_id == new_assignee.id
19
+ ticket.assigned_user_id = new_assignee.id
20
+
21
+ if ticket.save
22
+ puts "##{ticket.id} Assigned user changed: #{assignee || '(none)'} => #{new_assignee}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ module Helm
2
+ module Commands
3
+ class Command
4
+ attr_reader :session
5
+
6
+ def initialize(session)
7
+ @session = session
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,58 @@
1
+ module Lighthouse
2
+ class Ticket < Base
3
+ def body
4
+ attributes['body'] ||= ''
5
+ end
6
+
7
+ def body=(value)
8
+ attributes['body'] = value
9
+ end
10
+ end
11
+ end
12
+
13
+ module Helm
14
+ module Commands
15
+ class Create < Command
16
+ def run
17
+ ticket = nil
18
+
19
+ while line = $stdin.gets
20
+ line.strip!
21
+
22
+ if line.empty?
23
+ save(ticket)
24
+ ticket = nil
25
+ next
26
+ end
27
+
28
+ if ticket.nil?
29
+ ticket = session.new_ticket
30
+ ticket.title = line
31
+ else
32
+ unless line.empty?
33
+ ticket.body << line
34
+ ticket.body << "\n"
35
+ end
36
+ end
37
+ end
38
+
39
+ save(ticket)
40
+ end
41
+
42
+ protected
43
+
44
+ def save(ticket)
45
+ return unless ticket
46
+ ticket.title = ticket.title.sub(/^- ?/, '')
47
+ ticket.title = ticket.title.sub(/\.$/, '')
48
+ ticket.body = ticket.body.strip
49
+ ticket.save
50
+ puts "##{ticket.id} Created"
51
+ # puts "Title: #{ticket.title}"
52
+ # puts "Description: #{ticket.body}"
53
+ # puts "URL: http://citrusbyte.lighthouseapp.com/projects/18337/tickets/#{ticket.id}"
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,16 @@
1
+ module Helm
2
+ module Commands
3
+ class Info < Command
4
+ def run
5
+ ticket = session.ticket
6
+
7
+ puts "##{ticket.id} #{ticket.title}"
8
+
9
+ if ticket.description
10
+ puts "=="
11
+ puts ticket.description
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Helm
2
+ module Commands
3
+ class Resolve < Command
4
+ def run
5
+ ticket = session.ticket
6
+
7
+ ticket.state = 'resolved'
8
+
9
+ if ticket.save
10
+ puts "##{ticket.id} Resolved"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,289 @@
1
+ require 'rubygems'
2
+ require 'activesupport'
3
+ require 'activeresource'
4
+
5
+ # Ruby lib for working with the Lighthouse API's XML interface.
6
+ # The first thing you need to set is the account name. This is the same
7
+ # as the web address for your account.
8
+ #
9
+ # Lighthouse.account = 'activereload'
10
+ #
11
+ # Then, you should set the authentication. You can either use your login
12
+ # credentials with HTTP Basic Authentication or with an API Tokens. You can
13
+ # find more info on tokens at http://lighthouseapp.com/help/using-beacons.
14
+ #
15
+ # # with basic authentication
16
+ # Lighthouse.authenticate('rick@techno-weenie.net', 'spacemonkey')
17
+ #
18
+ # # or, use a token
19
+ # Lighthouse.token = 'abcdefg'
20
+ #
21
+ # If no token or authentication info is given, you'll only be granted public access.
22
+ #
23
+ # This library is a small wrapper around the REST interface. You should read the docs at
24
+ # http://lighthouseapp.com/api.
25
+ #
26
+ module Lighthouse
27
+ class Error < StandardError; end
28
+ class << self
29
+ attr_accessor :email, :password, :host_format, :domain_format, :protocol, :port
30
+ attr_reader :account, :token
31
+
32
+ # Sets the account name, and updates all the resources with the new domain.
33
+ def account=(name)
34
+ resources.each do |klass|
35
+ klass.site = klass.site_format % (host_format % [protocol, domain_format % name, ":#{port}"])
36
+ end
37
+ @account = name
38
+ end
39
+
40
+ # Sets up basic authentication credentials for all the resources.
41
+ def authenticate(email, password)
42
+ @email = email
43
+ @password = password
44
+ end
45
+
46
+ # Sets the API token for all the resources.
47
+ def token=(value)
48
+ resources.each do |klass|
49
+ klass.headers['X-LighthouseToken'] = value
50
+ end
51
+ @token = value
52
+ end
53
+
54
+ def resources
55
+ @resources ||= []
56
+ end
57
+ end
58
+
59
+ self.host_format = '%s://%s%s'
60
+ self.domain_format = '%s.lighthouseapp.com'
61
+ self.protocol = 'http'
62
+ self.port = ''
63
+
64
+ class Base < ActiveResource::Base
65
+ def self.inherited(base)
66
+ Lighthouse.resources << base
67
+ class << base
68
+ attr_accessor :site_format
69
+ end
70
+ base.site_format = '%s'
71
+ super
72
+ end
73
+ end
74
+
75
+ # Find projects
76
+ #
77
+ # Lighthouse::Project.find(:all) # find all projects for the current account.
78
+ # Lighthouse::Project.find(44) # find individual project by ID
79
+ #
80
+ # Creating a Project
81
+ #
82
+ # project = Lighthouse::Project.new(:name => 'Ninja Whammy Jammy')
83
+ # project.save
84
+ # # => true
85
+ #
86
+ # Creating an OSS project
87
+ #
88
+ # project = Lighthouse::Project.new(:name => 'OSS Project')
89
+ # project.access = 'oss'
90
+ # project.license = 'mit'
91
+ # project.save
92
+ #
93
+ # OSS License Mappings
94
+ #
95
+ # 'mit' => "MIT License",
96
+ # 'apache-2-0' => "Apache License 2.0",
97
+ # 'artistic-gpl-2' => "Artistic License/GPLv2",
98
+ # 'gpl-2' => "GNU General Public License v2",
99
+ # 'gpl-3' => "GNU General Public License v3",
100
+ # 'lgpl' => "GNU Lesser General Public License"
101
+ # 'mozilla-1-1' => "Mozilla Public License 1.1"
102
+ # 'new-bsd' => "New BSD License",
103
+ # 'afl-3' => "Academic Free License v. 3.0"
104
+
105
+ #
106
+ # Updating a Project
107
+ #
108
+ # project = Lighthouse::Project.find(44)
109
+ # project.name = "Lighthouse Issues"
110
+ # project.public = false
111
+ # project.save
112
+ #
113
+ # Finding tickets
114
+ #
115
+ # project = Lighthouse::Project.find(44)
116
+ # project.tickets
117
+ #
118
+ class Project < Base
119
+ def tickets(options = {})
120
+ Ticket.find(:all, :params => options.update(:project_id => id))
121
+ end
122
+
123
+ def messages(options = {})
124
+ Message.find(:all, :params => options.update(:project_id => id))
125
+ end
126
+
127
+ def milestones(options = {})
128
+ Milestone.find(:all, :params => options.update(:project_id => id))
129
+ end
130
+
131
+ def bins(options = {})
132
+ Bin.find(:all, :params => options.update(:project_id => id))
133
+ end
134
+
135
+ def changesets(options = {})
136
+ Changeset.find(:all, :params => options.update(:project_id => id))
137
+ end
138
+
139
+ def to_s
140
+ name
141
+ end
142
+ end
143
+
144
+ class User < Base
145
+ def memberships
146
+ Membership.find(:all, :params => {:user_id => id})
147
+ end
148
+
149
+ def to_s
150
+ name
151
+ end
152
+ end
153
+
154
+ class Membership < Base
155
+ site_format << '/users/:user_id'
156
+ def save
157
+ raise Error, "Cannot modify memberships from the API"
158
+ end
159
+ end
160
+
161
+ class Token < Base
162
+ def save
163
+ raise Error, "Cannot modify Tokens from the API"
164
+ end
165
+ end
166
+
167
+ # Find tickets
168
+ #
169
+ # Lighthouse::Ticket.find(:all, :params => { :project_id => 44 })
170
+ # Lighthouse::Ticket.find(:all, :params => { :project_id => 44, :q => "state:closed tagged:committed" })
171
+ #
172
+ # project = Lighthouse::Project.find(44)
173
+ # project.tickets
174
+ # project.tickets(:q => "state:closed tagged:committed")
175
+ #
176
+ # Creating a Ticket
177
+ #
178
+ # ticket = Lighthouse::Ticket.new(:project_id => 44)
179
+ # ticket.title = 'asdf'
180
+ # ...
181
+ # ticket.tags << 'ruby' << 'rails' << '@high'
182
+ # ticket.save
183
+ #
184
+ # Updating a Ticket
185
+ #
186
+ # ticket = Lighthouse::Ticket.find(20, :params => { :project_id => 44 })
187
+ # ticket.state = 'resolved'
188
+ # ticket.tags.delete '@high'
189
+ # ticket.save
190
+ #
191
+ class Ticket < Base
192
+ attr_writer :tags
193
+ site_format << '/projects/:project_id'
194
+
195
+ def id
196
+ attributes['number'] ||= nil
197
+ number
198
+ end
199
+
200
+ def to_s
201
+ title
202
+ end
203
+
204
+ def tags
205
+ attributes['tag'] ||= nil
206
+ @tags ||= tag.blank? ? [] : parse_with_spaces(tag)
207
+ end
208
+
209
+ def description
210
+ @description ||= version_body
211
+ end
212
+
213
+ def save_with_tags
214
+ self.tag = @tags.collect do |tag|
215
+ tag.include?(' ') ? tag.inspect : tag
216
+ end.join(" ") if @tags.is_a?(Array)
217
+ @tags = nil ; save_without_tags
218
+ end
219
+
220
+ alias_method_chain :save, :tags
221
+
222
+ private
223
+ # taken from Lighthouse Tag code
224
+ def parse_with_spaces(list)
225
+ tags = []
226
+
227
+ # first, pull out the quoted tags
228
+ list.gsub!(/\"(.*?)\"\s*/ ) { tags << $1; "" }
229
+
230
+ # then, get whatever's left
231
+ tags.concat list.split(/\s/)
232
+
233
+ cleanup_tags(tags)
234
+ end
235
+
236
+ def cleanup_tags(tags)
237
+ returning tags do |tag|
238
+ tag.collect! do |t|
239
+ unless tag.blank?
240
+ t.downcase!
241
+ t.gsub! /(^')|('$)/, ''
242
+ t.gsub! /[^a-z0-9 \-_@\!']/, ''
243
+ t.strip!
244
+ t
245
+ end
246
+ end
247
+ tag.compact!
248
+ tag.uniq!
249
+ end
250
+ end
251
+
252
+ def version_body
253
+ version = versions.detect do |v|
254
+ v.body and v.body.any?
255
+ end and version.body
256
+ end
257
+ end
258
+
259
+ class Message < Base
260
+ site_format << '/projects/:project_id'
261
+ end
262
+
263
+ class Milestone < Base
264
+ site_format << '/projects/:project_id'
265
+
266
+ def to_s
267
+ title
268
+ end
269
+ end
270
+
271
+ class Bin < Base
272
+ site_format << '/projects/:project_id'
273
+ end
274
+
275
+ class Changeset < Base
276
+ site_format << '/projects/:project_id'
277
+ end
278
+
279
+ class Change < Array; end
280
+ end
281
+
282
+ module ActiveResource
283
+ class Connection
284
+ private
285
+ def authorization_header
286
+ (Lighthouse.email || Lighthouse.password ? { 'Authorization' => 'Basic ' + ["#{Lighthouse.email}:#{Lighthouse.password}"].pack('m').delete("\r\n") } : {})
287
+ end
288
+ end
289
+ end
@@ -0,0 +1,28 @@
1
+ require 'uri'
2
+ require 'lib/lighthouse'
3
+
4
+ module Helm
5
+ class Project
6
+ attr_accessor :url, :title, :token
7
+
8
+ def initialize(url)
9
+ @url = url
10
+ end
11
+
12
+ protected
13
+
14
+ def account
15
+ @account ||= uri.host.split('.').first
16
+ end
17
+
18
+ def uri
19
+ @uri ||= URI.parse(url)
20
+ end
21
+
22
+ def configure
23
+ Lighthouse.account = account
24
+ Lighthouse.token = token
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,88 @@
1
+ gem 'choice'
2
+ require 'choice'
3
+
4
+ module Helm
5
+ class Session
6
+ attr_reader :options
7
+
8
+ def initialize
9
+ Choice.options do
10
+ option :url do
11
+ long '--url'
12
+ desc 'The project URL'
13
+ end
14
+
15
+ option :token do
16
+ long '--token'
17
+ desc 'The token to authenticate against the server'
18
+ end
19
+
20
+ option :project do
21
+ long '--project'
22
+ short '-p'
23
+ desc 'The project title'
24
+ end
25
+ end
26
+
27
+ @options = Choice.choices
28
+
29
+ configure
30
+ end
31
+
32
+ def project
33
+ @project ||= Lighthouse::Project.find(:all).detect {|p| p.name == options.project }
34
+ end
35
+
36
+ def new_ticket
37
+ Lighthouse::Ticket.new(:project_id => project.id)
38
+ end
39
+
40
+ def ticket(id = nil)
41
+ Lighthouse::Ticket.find(id || ticket_id, :params => {:project_id => project.id})
42
+ end
43
+
44
+ def milestone(id = nil)
45
+ if id
46
+ Lighthouse::Milestone.find(id)
47
+ else
48
+ @milestone ||= Lighthouse::Milestone.find(:all, :params => {:project_id => project.id}).detect {|m| m.title == ARGV[2] }
49
+ end
50
+ end
51
+
52
+ def ticket_id
53
+ ARGV[1].to_i
54
+ end
55
+
56
+ def user(id = nil)
57
+ if id
58
+ Lighthouse::User.find(id)
59
+ else
60
+ @user ||= Lighthouse::User.find(Lighthouse::Token.find(token).user_id)
61
+ end
62
+ end
63
+
64
+ protected
65
+
66
+ def account
67
+ @account ||= uri.host.split('.').first
68
+ end
69
+
70
+ def uri
71
+ @uri ||= URI.parse(url)
72
+ end
73
+
74
+ def url
75
+ options.url
76
+ end
77
+
78
+ def token
79
+ options.token
80
+ end
81
+
82
+ def configure
83
+ Lighthouse.account = account
84
+ Lighthouse.token = token
85
+ end
86
+
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: djanowski-helm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Damian Janowski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-06 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: choice
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.1.2
23
+ version:
24
+ description:
25
+ email: damian.janowski@gmail.com
26
+ executables:
27
+ - helm
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README.textile
32
+ files:
33
+ - lib/helm/commands/assign.rb
34
+ - lib/helm/commands/command.rb
35
+ - lib/helm/commands/create.rb
36
+ - lib/helm/commands/info.rb
37
+ - lib/helm/commands/resolve.rb
38
+ - lib/helm/lighthouse.rb
39
+ - lib/helm/project.rb
40
+ - lib/helm/session.rb
41
+ - lib/helm.rb
42
+ - README.textile
43
+ - LICENSE
44
+ - Rakefile
45
+ has_rdoc: false
46
+ homepage:
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --line-numbers
50
+ - --inline-source
51
+ - --title
52
+ - helm
53
+ - --main
54
+ - README.textile
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.2.0
73
+ signing_key:
74
+ specification_version: 2
75
+ summary: A command-line tool for Lighthouse.
76
+ test_files: []
77
+