osdn-cli 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3376886c75658394fda1f814ebdfe379058ae405
4
+ data.tar.gz: d7c42b6e4e49cf484bdf5f26e6d9a937e89dcda6
5
+ SHA512:
6
+ metadata.gz: 294713c7170970f465d9cfffda467b81eee659666ad1dcecc418e139e61800e626cbdaa724e5e918c20a128fb0025ab85987470c71b06749701f497f35c7d630
7
+ data.tar.gz: 5ce41536e44564b935bb6a87dbb38d3558836fa2b915c935f98a78807fc5bc548a60f4499898948e89c84dc2457cfa9319e8c91dceb1923e8e6dd97c66a2bdf0
data/exe/osdn ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'osdn/cli'
3
+
4
+ cli = OSDN::CLI::Runner.new
5
+ cli.run
@@ -0,0 +1,70 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ module OSDN; module CLI; module Command
5
+ class FrsMkdirs < Base
6
+ def help
7
+ puts "#{$0} frs_mkdirs [opts] [target_dir]"
8
+ puts "Options:"
9
+ puts " -p --project=<project> Target project (numeric id or name)"
10
+ #puts " --package=<package_id> Target package (numeric id)"
11
+ #puts " --release=<release_id> Target release (numeric id)"
12
+ end
13
+
14
+ def run
15
+ update_token
16
+ opts = GetoptLong.new(
17
+ [ '--dry-run', '-n', GetoptLong::NO_ARGUMENT ],
18
+ [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
19
+ )
20
+ opts.each do |opt, arg|
21
+ case opt
22
+ when '--project'
23
+ arg.empty? or
24
+ @target_proj = arg
25
+ end
26
+ end
27
+
28
+ proj_info = api.get_project target_proj # check project existance
29
+
30
+ target_dir = Pathname.new(ARGV.shift || '.')
31
+ FileUtils.mkdir_p target_dir
32
+ update_variables target_dir, project: target_proj
33
+
34
+ logger.debug "Getting Package list..."
35
+ packages = api.list_packages target_proj
36
+ logger.debug "Making each package directry"
37
+
38
+ packages.each do |package|
39
+ logger.info "Making directory for package #{package.name}"
40
+ pdir = target_dir + package.name
41
+ FileUtils.mkdir_p(pdir)
42
+ update_variables pdir, package_id: package.id
43
+ package.releases.each do |release|
44
+ logger.info "Making directory for release #{release.name}"
45
+ rdir = pdir + release.name
46
+ FileUtils.mkdir_p(rdir)
47
+ update_variables rdir, release_id: release.id
48
+ end
49
+ end
50
+ end
51
+
52
+ def self.description
53
+ "Make directory tree for current project release"
54
+ end
55
+
56
+ private
57
+ def target_proj
58
+ @target_proj and return @target_proj
59
+ vars = load_variables
60
+ vars.project && !vars.project.empty? and
61
+ return vars.project
62
+ logger.fatal "No target project is specified."
63
+ exit
64
+ end
65
+
66
+ def api
67
+ OSDNClient::ProjectApi.new
68
+ end
69
+ end
70
+ end; end; end
@@ -0,0 +1,128 @@
1
+ module OSDN; module CLI; module Command
2
+ class FrsUpload < Base
3
+ def help
4
+ puts "#{$0} frs_upload [opts] [target_dir]"
5
+ puts "Options:"
6
+ puts " -n --dry-run Do noting (use with global -v to inspect)"
7
+ puts " -p --project=<project> Target project (numeric id or name)"
8
+ #puts " --package=<project> Target package (numeric id)"
9
+ #puts " --release=<project> Target release (numeric id)"
10
+ puts " -v --visibility=<public|private|hidden>"
11
+ puts " Default visibility for newly created items"
12
+ end
13
+
14
+ def run
15
+ update_token
16
+ opts = GetoptLong.new(
17
+ [ '--dry-run', '-n', GetoptLong::NO_ARGUMENT ],
18
+ [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
19
+ [ '--release', '-r', GetoptLong::REQUIRED_ARGUMENT ],
20
+ [ '--visibility', '-v', GetoptLong::REQUIRED_ARGUMENT ],
21
+ )
22
+ opts.each do |opt, arg|
23
+ case opt
24
+ when '--project'
25
+ arg.empty? or
26
+ @target_proj = arg
27
+ #when '--release'
28
+ # arg.empty? or
29
+ # @target_release = arg
30
+ #when '--package'
31
+ # arg.empty? or
32
+ # @target_package = arg
33
+ when '--visibility'
34
+ unless %w(public private hidden).member?(arg)
35
+ logger.fatal "Invalid visibility status: #{arg}"
36
+ exit
37
+ end
38
+ @visibility = arg
39
+ when '--dry-run'
40
+ @dry_run = true
41
+ end
42
+ end
43
+
44
+ @target_dir = Pathname.new(ARGV.shift || '.')
45
+ proj_info = api.get_project target_proj # check project existance
46
+
47
+ Pathname.glob(@target_dir+'*').each do |pdir|
48
+ unless load_variables(pdir).package_id
49
+ logger.info "Createing new package '#{pdir.basename}'"
50
+ pinfo = api.create_package target_proj, pdir.basename, visibility: @visibility
51
+ update_variables pdir, package_id: pinfo.id
52
+ $stdout.puts "New package '#{pinfo.name}' has been created; #{pinfo.url}"
53
+ end
54
+
55
+ Pathname.glob(pdir + '*').each do |rdir|
56
+ vars = load_variables(rdir)
57
+ rinfo = nil
58
+ if vars.release_id
59
+ rinfo = api.get_release target_proj, target_package(rdir), target_release(rdir)
60
+ else vars.release_id
61
+ logger.info "Createing new release '#{rdir.basename}'"
62
+ rinfo = nil
63
+ if api.respond_to? :create_reelase # TODO: remove, just typo...
64
+ rinfo = api.create_reelase target_proj, target_package(rdir), rdir.basename, visibility: @visibility
65
+ else
66
+ rinfo = api.create_release target_proj, target_package(rdir), rdir.basename, visibility: @visibility
67
+ end
68
+ update_variables rdir, release_id: rinfo.id
69
+ $stdout.puts "New release '#{rinfo.name}' has been created; #{rinfo.url}"
70
+ end
71
+
72
+ Pathname.glob(rdir + '*').each do |file|
73
+ if file.directory?
74
+ logger.error "Skip direcotry #{file}"
75
+ next
76
+ end
77
+
78
+ if rinfo.files.find { |f| f.name == file.basename.to_s }
79
+ logger.warn "Skip already uploaded file '#{file}'"
80
+ else
81
+ logger.info "Uploading file #{file} (#{file.size} bytes)"
82
+ # TODO: show progress bar!
83
+ finfo = api.create_release_file target_proj, target_package(rdir), target_release(rdir), file.open, visibility: @visibility
84
+ logger.info "Upload completed."
85
+ $stdout.puts "New file '#{file}' has been uploaded; #{finfo.url}"
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def self.description
93
+ "Upload local file tree and create package/release implicitly."
94
+ end
95
+
96
+ private
97
+ def target_proj
98
+ @target_proj and return @target_proj
99
+ vars = load_variables(@target_dir)
100
+ vars.project && !vars.project.empty? and
101
+ return vars.project
102
+ logger.fatal "No target project is specified."
103
+ exit
104
+ end
105
+
106
+ def target_package(dir)
107
+ @target_package and return @target_package
108
+ vars = load_variables(dir)
109
+ vars.package_id && !vars.package_id.to_s.empty? and
110
+ return vars.package_id
111
+ logger.fatal "No target package is specified."
112
+ exit
113
+ end
114
+
115
+ def target_release(dir)
116
+ @target_release and return @target_release
117
+ vars = load_variables(dir)
118
+ vars.release_id && !vars.release_id.to_s.empty? and
119
+ return vars.release_id
120
+ logger.fatal "No target release is specified."
121
+ exit
122
+ end
123
+
124
+ def api
125
+ OSDNClient::ProjectApi.new
126
+ end
127
+ end
128
+ end; end; end
@@ -0,0 +1,63 @@
1
+ module OSDN; module CLI; module Command
2
+ class Login < Base
3
+ def run
4
+ logger.debug "Trying login"
5
+ scope = %w(profile group group_write)
6
+
7
+ auth_url = "https://osdn.jp/account/oauth2ui/authorize?client_id=#{CLI.client_id}&state=cli#{Time.now.to_i}&response_type=code&scope=#{scope.join('%20')}"
8
+
9
+ launch_brwoser auth_url
10
+ puts
11
+ authcode = prompt("Type your auth code: ")
12
+ puts
13
+ if authcode.empty?
14
+ logger.error "Empty auth code, login has been canceled."
15
+ return
16
+ end
17
+
18
+ api = OSDNClient::DefaultApi.new
19
+ begin
20
+ set_credential api.token(CLI.client_id, CLI.client_secret, code: authcode)
21
+ rescue OSDNClient::ApiError => e
22
+ begin
23
+ err = JSON.parse(e.response_body)
24
+ logger.fatal err["error_description"]
25
+ rescue
26
+ logger.fatal "Failed to get access token"
27
+ end
28
+ return
29
+ end
30
+ end
31
+
32
+ def launch_brwoser(url)
33
+ puts "Access follwoing URL to get auth code;\n#{url}"
34
+ %w(/usr/bin/xdg-open /usr/bin/X11/xdg-open /usr/local/bin/xdg-open
35
+ /usr/bin/x-www-browser /usr/bin/firefox /usr/local/bin/firefox
36
+ ).each do |bin|
37
+ File.executable?(bin) or next
38
+ exec(bin, url) if fork.nil?
39
+ return
40
+ end
41
+ case RUBY_PLATFORM
42
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
43
+ exec("start #{url}") if fork.nil?
44
+ when /darwin|mac os/
45
+ exec("/usr/bin/open", url) if fork.nil?
46
+ end
47
+ end
48
+
49
+ def prompt(msg = "", newline = false)
50
+ require 'readline'
51
+ msg += "\n" if newline
52
+ Readline.readline(msg, true).to_s.squeeze(" ").strip
53
+ end
54
+
55
+ def help
56
+ puts "#{$0} login"
57
+ end
58
+
59
+ def self.description
60
+ "Login and save access token."
61
+ end
62
+ end
63
+ end; end; end
@@ -0,0 +1,118 @@
1
+ module OSDN; module CLI; module Command
2
+ class Package < Base
3
+ def self.help
4
+ puts "#{$0} package [opts] [list]"
5
+ puts "#{$0} package [opts] create <new-package-name>"
6
+ puts "#{$0} package [opts] update <numeric-package-id> [name]"
7
+ puts "#{$0} package [opts] delete <numeric-package-id>"
8
+ puts "Options:"
9
+ puts " -f --format=<pretty|json> Set output format"
10
+ puts " -p --project=<project> Target project (numeric id or name)"
11
+ puts " -v --visibility=<public|private|hidden>"
12
+ end
13
+
14
+ def self.description
15
+ "Manipulate release package of project"
16
+ end
17
+
18
+ def run
19
+ update_token
20
+ opts = GetoptLong.new(
21
+ [ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
22
+ [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
23
+ [ '--visibility', '-v', GetoptLong::REQUIRED_ARGUMENT ],
24
+ )
25
+ opts.each do |opt, arg|
26
+ case opt
27
+ when '--format'
28
+ arg == 'json' and
29
+ self.format = arg
30
+ when '--project'
31
+ arg.empty? or
32
+ @target_proj = arg
33
+ when '--visibility'
34
+ unless %w(public private hidden).member?(arg)
35
+ logger.fatal "Invalid visibility status: #{arg}"
36
+ exit
37
+ end
38
+ @visibility = arg
39
+ end
40
+ end
41
+ command = ARGV.shift || 'list'
42
+ if !command || command.empty?
43
+ logger.fatal "subcommand is missing."
44
+ help
45
+ return
46
+ end
47
+ if self.respond_to? command
48
+ self.send command
49
+ else
50
+ logger.fatal "Invalid subcommand: #{command}"
51
+ help
52
+ return
53
+ end
54
+ end
55
+
56
+ def list
57
+ list = api.list_packages target_proj
58
+ if format == 'json'
59
+ puts list.to_json
60
+ else
61
+ list.each do |p|
62
+ puts format_package(p)
63
+ end
64
+ end
65
+ end
66
+
67
+ def create
68
+ name = ARGV.shift
69
+ if !name
70
+ logger.fatal "Package name is missing."
71
+ help
72
+ return
73
+ end
74
+ p = api.create_package target_proj, name, visibility: @visibility
75
+ logger.info "New package has been created."
76
+ puts format_package(p)
77
+ end
78
+
79
+ def update
80
+ target_id = ARGV.shift
81
+ args = {name: ARGV.shift}
82
+ if @visibility
83
+ args[:visibility] = @visibility
84
+ end
85
+ p = api.update_package target_proj, target_id, args
86
+ logger.info "Package #{target_id} has been updated."
87
+ puts format_package(p)
88
+ end
89
+
90
+ def delete
91
+ target_id = ARGV.shift
92
+ p = api.delete_package target_proj, target_id
93
+ logger.info "Package #{target_id} has been deleted."
94
+ end
95
+
96
+ private
97
+ def target_proj
98
+ @target_proj and return @target_proj
99
+ vars = load_variables
100
+ vars.project && !vars.project.empty? and
101
+ return vars.project
102
+ logger.fatal "No target project is specified."
103
+ exit
104
+ end
105
+
106
+ def api
107
+ OSDNClient::ProjectApi.new
108
+ end
109
+
110
+ def format_package(p)
111
+ if format == 'json'
112
+ p.to_json
113
+ else
114
+ "##{p.id} #{p.name} (#{p.visibility}, #{[*p.releases].count} releases)\n #{p.url}"
115
+ end
116
+ end
117
+ end
118
+ end; end; end
@@ -0,0 +1,6 @@
1
+ module OSDN
2
+ module CLI
3
+ module Common
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,115 @@
1
+ require 'getoptlong'
2
+ require 'logger'
3
+ require 'pp'
4
+
5
+ module OSDN
6
+ module CLI
7
+ class Runner
8
+ def initialize
9
+ @logger = Logger.new(STDERR)
10
+ @logger.level = Logger::WARN
11
+ @logger.formatter = proc { |severity, time, progname, msg|
12
+ "[%s] %s\n" % [severity, msg]
13
+ }
14
+ end
15
+ attr_reader :logger
16
+
17
+ def parse_opt
18
+ opts = GetoptLong.new(
19
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
20
+ [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
21
+ [ '--quiet', '-q', GetoptLong::NO_ARGUMENT ],
22
+ )
23
+ opts.ordering = GetoptLong::REQUIRE_ORDER
24
+ opts.each do |opt, arg|
25
+ case opt
26
+ when '--help'
27
+ help
28
+ exit 0
29
+ when '--verbose'
30
+ if logger.level == Logger::DEBUG
31
+ OSDNClient.configure do |config|
32
+ config.debugging = true
33
+ end
34
+ end
35
+ logger.level > Logger::DEBUG and
36
+ logger.level -= 1
37
+ when '--quiet'
38
+ logger.level < Logger::UNKNOWN and
39
+ logger.level += 1
40
+ when '--help'
41
+ help
42
+ exit
43
+ end
44
+ end
45
+ logger.debug "Loglevel is #{logger.level}"
46
+ end
47
+
48
+ def get_command_class(command_name)
49
+ class_name = command_name.to_s.split('_').map(&:capitalize).join
50
+ begin
51
+ return self.class.const_get("OSDN::CLI::Command::#{class_name}")
52
+ rescue NameError => e
53
+ logger.fatal "Invalid command name '#{command_name}'. Use 'help' to list commands."
54
+ exit
55
+ end
56
+ false
57
+ end
58
+
59
+ def run
60
+ parse_opt
61
+
62
+ command_name = ARGV.shift
63
+ unless command_name
64
+ help
65
+ exit 1
66
+ end
67
+
68
+ if command_name == 'help'
69
+ help
70
+ exit
71
+ end
72
+
73
+ command = get_command_class(command_name).new(logger)
74
+ logger.debug "Run command #{command_name}"
75
+ begin
76
+ command.run
77
+ rescue OSDNClient::ApiError => e
78
+ begin
79
+ err = JSON.parse(e.response_body)
80
+ if err["message"]
81
+ logger.fatal "#{err["status"]}: #{err["message"]}"
82
+ elsif err["error_description"]
83
+ logger.fatal err["error_description"]
84
+ else
85
+ logger.fatal "Command failed: #{e.inspect}"
86
+ end
87
+ rescue
88
+ logger.fatal "Command failed: #{e.inspect}"
89
+ end
90
+ end
91
+ end
92
+
93
+ def help
94
+ command_name = ARGV.shift
95
+ if command_name
96
+ get_command_class(command_name).new(logger).help
97
+ else
98
+ puts "#{$0} [global-options] <command> [command-options] [args]"
99
+ puts "#{$0} help <command>"
100
+ puts "Global Options:"
101
+ puts " -h --help Show help message. use 'help <command>' for specific command. "
102
+ puts " -v --verbose Increase log level (multiple)"
103
+ puts " -q --quiet Decrease log level (multiple)"
104
+ puts "Avaiable Commands:"
105
+ puts " help"
106
+ OSDN::CLI::Command.constants.each do |c|
107
+ c = c.to_s.split(/(?=[A-Z])/).join('_').downcase
108
+ c == 'base' and next
109
+ puts " %-14s %s" % [c, get_command_class(c).description]
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,5 @@
1
+ module OSDN
2
+ module CLI
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
data/lib/osdn/cli.rb ADDED
@@ -0,0 +1,219 @@
1
+ require "osdn/cli/version"
2
+ require "osdn/cli/runner"
3
+ require 'getoptlong'
4
+ require 'logger'
5
+ require 'pathname'
6
+ require 'yaml'
7
+ require 'fileutils'
8
+ require 'osdn-client'
9
+ require 'hashie'
10
+ require 'json'
11
+
12
+ module OSDN
13
+ module CLI
14
+ @@client_id = "osdn-cli"
15
+ @@client_secret = "not-secret"
16
+ def client_id
17
+ @@client_id
18
+ end
19
+ def client_secret
20
+ @@client_secret
21
+ end
22
+ module_function :client_id, :client_secret
23
+
24
+ module Command
25
+ autoload :Login, 'osdn/cli/command/login'
26
+ autoload :Package, 'osdn/cli/command/package'
27
+ #autoload :Release, 'osdn/cli/command/release'
28
+ #autoload :FrsFile, 'osdn/cli/command/frs_file'
29
+ autoload :FrsMkdirs, 'osdn/cli/command/frs_mkdirs'
30
+ autoload :FrsUpload, 'osdn/cli/command/frs_upload'
31
+
32
+ class Base
33
+ def initialize(logger)
34
+ @logger = logger
35
+ @credential = Hashie::Mash.new
36
+ @format = 'pretty'
37
+ end
38
+ attr_reader :logger
39
+ attr_accessor :credential, :format
40
+
41
+ def credential_path
42
+ Pathname.new(ENV['HOME']) + '.config/osdn/credential.yml'
43
+ end
44
+
45
+ def load_credential
46
+ begin
47
+ stat = credential_path.stat()
48
+ unless credential_path.owned?
49
+ logger.error "Invalid ownership of credential file #{credential_path}, skip loading."
50
+ return
51
+ end
52
+ unless (stat.mode & 0777).to_s(8) == "600"
53
+ logger.error "Invalid permission #{(stat.mode & 0777).to_s(8)} of credential file #{credential_path}, skip loading."
54
+ return
55
+ end
56
+ rescue Errno::ENOENT
57
+ return
58
+ end
59
+ logger.debug "Loading credentials from #{credential_path}"
60
+ @credential = Hashie::Mash.new(YAML.load_file(credential_path))
61
+ set_client_token
62
+ end
63
+
64
+ def write_credential
65
+ FileUtils.mkdir_p credential_path.dirname, verbose: false
66
+ cio = credential_path.open('w', 0600)
67
+ YAML.dump(credential.to_hash, cio)
68
+ cio.close
69
+ end
70
+
71
+ def update_token
72
+ logger.debug "Checking token expires..."
73
+ load_credential
74
+ if credential.expires_at > Time.now + 30
75
+ logger.debug "You have valid access token, skip to refresh."
76
+ return
77
+ end
78
+
79
+ logger.debug "Access token has been expired. Refresh access token..."
80
+ api = OSDNClient::DefaultApi.new
81
+ begin
82
+ set_credential api.token(CLI.client_id, CLI.client_secret, grant_type: 'refresh_token', refresh_token: credential.refresh_token)
83
+ rescue OSDNClient::ApiError => e
84
+ begin
85
+ err = JSON.parse(e.response_body)
86
+ logger.fatal err["error_description"]
87
+ rescue
88
+ logger.fatal "Failed to refresh access token."
89
+ end
90
+ logger.fatal "Please login again."
91
+ return
92
+ end
93
+ logger.debug "Access token refreshed successfully."
94
+ end
95
+
96
+ def set_credential(token, update_expires = true)
97
+ token = Hashie::Mash.new(token.to_hash)
98
+ if update_expires
99
+ token.expires_at = Time.now + token.expires_in.to_i
100
+ end
101
+ token.scope = [*token.scope].join(' ').split(' ')
102
+
103
+ credential.update token
104
+ write_credential
105
+ set_client_token
106
+ end
107
+
108
+ def set_client_token
109
+ if credential.access_token && !credential.access_token.empty?
110
+ OSDNClient.configure do |config|
111
+ config.access_token = credential.access_token
112
+ end
113
+ end
114
+ end
115
+
116
+ def load_variables(path = '.', recursive_merge = true)
117
+ vars = {}
118
+ path = Pathname.new(Dir.getwd) + path
119
+ cur_dir = Pathname.new('/')
120
+ if recursive_merge
121
+ path.each_filename do |d|
122
+ cur_dir = cur_dir + d
123
+ vf = cur_dir + '.osdn.vars'
124
+ vf.exist? or next
125
+ begin
126
+ logger.debug "Load and merge variables from #{vf}"
127
+ vars.update YAML.load_file(vf.to_s)
128
+ rescue => e
129
+ logger.warn "Failed to load variables from #{vf}; #{e.message}"
130
+ end
131
+ end
132
+ else
133
+ begin
134
+ path = path+'.osdn.vars'
135
+ if path.exist?
136
+ logger.debug "Load and merge variables from #{path}"
137
+ vars.update YAML.load_file(path)
138
+ end
139
+ rescue => e
140
+ logger.warn "Failed to load variables from #{path}; #{e.message}"
141
+ end
142
+ end
143
+ logger.debug "Variables: #{vars.inspect}"
144
+ Hashie::Mash.new(vars)
145
+ end
146
+
147
+ def write_variables(vars, dir = nil)
148
+ path = Pathname.new(dir || '.') + '.osdn.vars'
149
+ logger.info "Save variables to #{path}"
150
+ vio = path.open('w')
151
+ YAML.dump(vars.to_hash, vio)
152
+ vio.close
153
+ end
154
+
155
+ def update_variables(dir, vars)
156
+ write_variables(load_variables(dir, false).merge(vars), dir)
157
+ end
158
+ end
159
+
160
+ class Ping < Base
161
+ def run
162
+ update_token
163
+ api = OSDNClient::DefaultApi.new
164
+ pp api.ping
165
+ end
166
+
167
+ def help
168
+ puts "#{$0} ping"
169
+ end
170
+
171
+ def self.description
172
+ "Test API request."
173
+ end
174
+ end
175
+
176
+ class Vars < Base
177
+ def run
178
+ subcommand = ARGV.shift ||'show'
179
+ self.send subcommand
180
+ end
181
+
182
+ def show
183
+ name = ARGV.shift
184
+ if name
185
+ puts load_variables[name]
186
+ else
187
+ pp load_variables
188
+ end
189
+ end
190
+
191
+ def set
192
+ name, value = ARGV.shift, ARGV.shift
193
+ if !name || name.empty?
194
+ logger.fatal "Missing variable name"
195
+ help
196
+ exit
197
+ end
198
+ if !value || value.empty?
199
+ logger.fatal "Missing variable value"
200
+ help
201
+ exit
202
+ end
203
+ vars = load_variables('.', false)
204
+ vars[name] = value
205
+ write_variables vars
206
+ end
207
+
208
+ def help
209
+ puts "#{$0} vars show [name] -- Show current variable"
210
+ puts "#{$0} vars set <name> <value> -- Save variable to .osdn.vars"
211
+ end
212
+
213
+ def self.description
214
+ "Get/set request environment variable."
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
data/lib/osdn-cli.rb ADDED
@@ -0,0 +1 @@
1
+ require 'osdn/cli'
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: osdn-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - OSDN
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: osdn-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: hashie
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Non-intaractive manipulation tool for OSDN
84
+ email:
85
+ - admin@osdn.jp
86
+ executables:
87
+ - osdn
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - exe/osdn
92
+ - lib/osdn-cli.rb
93
+ - lib/osdn/cli.rb
94
+ - lib/osdn/cli/command/frs_mkdirs.rb
95
+ - lib/osdn/cli/command/frs_upload.rb
96
+ - lib/osdn/cli/command/login.rb
97
+ - lib/osdn/cli/command/package.rb
98
+ - lib/osdn/cli/common.rb
99
+ - lib/osdn/cli/runner.rb
100
+ - lib/osdn/cli/version.rb
101
+ homepage: https://osdn.jp/projects/osdn-codes/wiki/CommandLineInterface
102
+ licenses: []
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.5.1
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: OSDN Command Line Interface
124
+ test_files: []