osdn-cli 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []