lh 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/bin/lh +61 -0
- data/lib/lh.rb +177 -1
- metadata +33 -10
- data/test/lh-test.rb +0 -0
data/Gemfile
ADDED
data/bin/lh
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'lh'
|
4
|
+
require 'trollop'
|
5
|
+
|
6
|
+
SUB_COMMANDS = %w(i init n new s show u update o open c close)
|
7
|
+
global_opts = Trollop::options do
|
8
|
+
version
|
9
|
+
banner <<-EOS
|
10
|
+
lh 0.0.3 (c) Matthew Trost 2011
|
11
|
+
::: command-line interface to Lighthouse
|
12
|
+
|
13
|
+
Usage:
|
14
|
+
lh [i]nit (initialize lh to your Lighthouse project)
|
15
|
+
lh [n]ew (create new ticket)
|
16
|
+
lh [s]how (show ticket or list of tickets)
|
17
|
+
lh [u]pdate (add comment to ticket)
|
18
|
+
lh [o]pen (mark ticket as open; assign to default user)
|
19
|
+
lh [c]lose (close ticket to default closed state)
|
20
|
+
EOS
|
21
|
+
stop_on SUB_COMMANDS
|
22
|
+
end
|
23
|
+
|
24
|
+
cmd = ARGV.shift
|
25
|
+
cmd_opts = case cmd
|
26
|
+
when 'init', 'i'
|
27
|
+
Trollop::options do
|
28
|
+
opt :account, 'Lighthouse account ID', :type => :string
|
29
|
+
opt :token, 'Lighthouse API token', :type => :string
|
30
|
+
opt :user, 'Lighthouse username', :type => :string
|
31
|
+
opt :password, 'Lighthouse password', :type => :string
|
32
|
+
opt :default_project 'Default project name or ID', :type => :string
|
33
|
+
end
|
34
|
+
when 'new', 'n'
|
35
|
+
Trollop::options do
|
36
|
+
opt :user, 'User to assign ticket', :type => :string
|
37
|
+
opt :project, 'Project to assign ticket', :type => :string
|
38
|
+
opt :milestone, 'Milestone to assign ticket', :type => :string
|
39
|
+
opt :title, 'Title of ticket', :type => :string
|
40
|
+
opt :message, 'Ticket message', :type => :string
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
sub_cmd = ARGV.shift
|
45
|
+
case cmd
|
46
|
+
when 'init', 'i'
|
47
|
+
Lh.init(cmd_opts)
|
48
|
+
when 'new', 'n'
|
49
|
+
Lh::Ticket.create(cmd_opts)
|
50
|
+
when 'show', 's'
|
51
|
+
Lh::Ticket.show(sub_cmd)
|
52
|
+
when 'update', 'u'
|
53
|
+
Lh::Ticket.update(sub_cmd)
|
54
|
+
when 'open', 'o'
|
55
|
+
Lh::Ticket.open(sub_cmd)
|
56
|
+
when 'close', 'c'
|
57
|
+
Lh::Ticket.close(sub_cmd)
|
58
|
+
else
|
59
|
+
end
|
60
|
+
|
61
|
+
|
data/lib/lh.rb
CHANGED
@@ -1,2 +1,178 @@
|
|
1
|
-
|
1
|
+
require 'yaml'
|
2
|
+
require 'lighthouse-api'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
class Object
|
6
|
+
def blank?
|
7
|
+
respond_to?(:empty?) ? empty? : !self
|
8
|
+
end
|
9
|
+
|
10
|
+
def present?
|
11
|
+
!blank?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class String
|
16
|
+
def is_i?
|
17
|
+
!!(self =~ /^[-+]?[0-9]+$/)
|
18
|
+
end
|
2
19
|
end
|
20
|
+
|
21
|
+
class Lh
|
22
|
+
class Ticket
|
23
|
+
def self.create (opts)
|
24
|
+
Lh::Session.establish
|
25
|
+
|
26
|
+
if opts[:project].present?
|
27
|
+
proj_id = Lh::Project.id_from_input(
|
28
|
+
opts[:project],
|
29
|
+
Lh::Project.return_all_filtered)
|
30
|
+
else
|
31
|
+
proj_id = Lh.get_dproj()
|
32
|
+
end
|
33
|
+
|
34
|
+
ticket = ::Lighthouse::Ticket.new(:project_id => proj_id.to_i)
|
35
|
+
raise Lh::Error::InvalidOpts, 'Supply a ticket title.' if opts[:title].empty?
|
36
|
+
ticket.title = opts[:title]
|
37
|
+
ticket.body = opts[:message] if opts[:message].present?
|
38
|
+
|
39
|
+
ticket.save
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.show (opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.update (opts)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.open (opts)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.close (opts)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.init (opts = {})
|
56
|
+
opts_filt = Lh.filter_opts(Lh.validate_opts(opts))
|
57
|
+
Lh.write_config(opts_filt)
|
58
|
+
Lh::Session.establish(opts_filt)
|
59
|
+
Lh.assign_default_project(opts_filt)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.validate_opts (opts)
|
63
|
+
raise Lh::Error::InvalidOpts, 'Account name required.' if opts[:account].nil?
|
64
|
+
if opts[:user].present?
|
65
|
+
raise Lh::Error::InvalidOpts, 'Password required.' if opts[:password].nil?
|
66
|
+
elsif opts[:token].nil?
|
67
|
+
raise Lh::Error::InvalidOpts, 'Token or credentials required.'
|
68
|
+
end
|
69
|
+
opts
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.filter_opts (opts)
|
73
|
+
{ account: opts[:account],
|
74
|
+
token: opts[:token],
|
75
|
+
user: opts[:user],
|
76
|
+
password: opts[:password],
|
77
|
+
default_project: opts[:default_project] }
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.write_config (opts)
|
81
|
+
FileUtils.rm_rf('.lh')
|
82
|
+
Dir::mkdir('.lh')
|
83
|
+
File.open('.lh/config.yml', 'w') do |file|
|
84
|
+
file.write(opts.to_yaml)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.assign_default_project (opts)
|
89
|
+
if opts[:default_project].nil?
|
90
|
+
opts[:default_project] = Lh.find_dproj()
|
91
|
+
else
|
92
|
+
opts[:default_project] = Lh.parse_proj(opts[:default_project])
|
93
|
+
end
|
94
|
+
Lh.write_config(opts)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.get_dproj
|
98
|
+
Lh.load_opts[:default_project]
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.find_dproj
|
102
|
+
projects = Lh::Project.return_all_filtered
|
103
|
+
if projects.length == 1
|
104
|
+
projects[0][:id].to_i
|
105
|
+
elsif projects.length > 1
|
106
|
+
Lh.ask_dproj(projects)
|
107
|
+
else
|
108
|
+
raise "Your account doesn't have any projects."
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.ask_dproj (projects)
|
113
|
+
print 'Your account has multiple projects. Set a default (recommended)? [Yn]: '
|
114
|
+
if %w(y Y).include?(gets.chomp)
|
115
|
+
print 'Enter the project name or id: '
|
116
|
+
Lh::Project.id_from_input(gets.chomp, projects)
|
117
|
+
else
|
118
|
+
puts "Set the project with `--project <id>' in all subsequent commands."
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.parse_proj (proj)
|
123
|
+
Lh::Project.id_from_input(proj, Lh::Project.return_all_filtered)
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.load_opts
|
127
|
+
begin
|
128
|
+
YAML::load(File.open('.lh/config.yml'))
|
129
|
+
rescue
|
130
|
+
puts 'Config file not found in this directory.'
|
131
|
+
puts 'Are you sure you initialized it here?'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
class Session
|
137
|
+
def self.establish (opts = {})
|
138
|
+
if opts.empty? then Lh::Session.establish_with_defaults
|
139
|
+
else Lh::Session.establish_with_opts(opts) end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.establish_with_opts (opts)
|
143
|
+
::Lighthouse.account = opts[:account]
|
144
|
+
if opts[:token].present? then ::Lighthouse.token = opts[:token]
|
145
|
+
else ::Lighthouse.authenticate(opts[:user], opts[:password]) end
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.establish_with_defaults
|
149
|
+
Lh::Session.establish(Lh.load_opts)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
class Project
|
155
|
+
def self.return_all_filtered
|
156
|
+
projects_raw = ::Lighthouse::Project.find(:all)
|
157
|
+
projects_raw.map {|project|
|
158
|
+
{ name: project.name,
|
159
|
+
id: project.id }
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.id_from_input(input, projects)
|
164
|
+
id = projects.map {|project|
|
165
|
+
if input.is_i? then project[:id] if input.to_i == project[:id]
|
166
|
+
else project[:id] if input == project[:name] end
|
167
|
+
}
|
168
|
+
raise "Project '#{input}' not found. Try again." if id.nil?
|
169
|
+
id[0]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
class Error
|
175
|
+
class InvalidOpts < StandardError
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,21 +9,44 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
13
|
-
dependencies:
|
14
|
-
|
12
|
+
date: 2011-11-23 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: trollop
|
16
|
+
requirement: &2152820320 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2152820320
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: lighthouse-api
|
27
|
+
requirement: &2152819880 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2152819880
|
36
|
+
description: lh provides a command-line interface to the Lighthouse issue-tracking
|
15
37
|
system.
|
16
|
-
email:
|
17
|
-
executables:
|
38
|
+
email: mrtrost@gmail.com
|
39
|
+
executables:
|
40
|
+
- lh
|
18
41
|
extensions: []
|
19
42
|
extra_rdoc_files: []
|
20
43
|
files:
|
21
|
-
- lib/lh.rb
|
22
44
|
- bin/lh
|
23
|
-
-
|
45
|
+
- lib/lh.rb
|
46
|
+
- Gemfile
|
24
47
|
- Rakefile
|
25
48
|
- README.markdown
|
26
|
-
homepage:
|
49
|
+
homepage: https://github.com/matthewtoast/lh
|
27
50
|
licenses: []
|
28
51
|
post_install_message:
|
29
52
|
rdoc_options: []
|
@@ -46,5 +69,5 @@ rubyforge_project:
|
|
46
69
|
rubygems_version: 1.8.8
|
47
70
|
signing_key:
|
48
71
|
specification_version: 3
|
49
|
-
summary: Lighthouse
|
72
|
+
summary: Lighthouse vs. command line
|
50
73
|
test_files: []
|
data/test/lh-test.rb
DELETED
File without changes
|