OSDN Git Service

Add release and file command.
[osdn-codes/osdn-cli.git] / lib / osdn / cli / command / relfile.rb
diff --git a/lib/osdn/cli/command/relfile.rb b/lib/osdn/cli/command/relfile.rb
new file mode 100644 (file)
index 0000000..c41c592
--- /dev/null
@@ -0,0 +1,123 @@
+require 'osdn/cli/command/frs_base'
+require 'pathname'
+
+module OSDN; module CLI; module Command
+  class Relfile < FrsBase
+    def help
+      puts "#{$0} relfile [opts] [list]"
+      puts "#{$0} relfile [opts] create <target-file>"
+      puts "#{$0} relfile [opts] update <numeric-file-id>"
+      puts "#{$0} relfile [opts] delete <numeric-file-id>"
+      puts "Options:"
+      puts "  -f --format=<pretty|json>  Set output format"
+      puts "  -p --project=<project>     Target project (numeric id or name)"
+      puts "     --package=<project>     Target package (numeric id)"
+      puts "     --release=<project>     Target release (numeric id)"
+      puts "  -v --visibility=<public|private|hidden>"
+    end
+
+    def self.description
+      "Manipulate release (includes by package) of project"
+    end
+
+    def process_options
+      opts = GetoptLong.new(
+        [ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
+        [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
+        [ '--package', GetoptLong::REQUIRED_ARGUMENT ],
+        [ '--release', GetoptLong::REQUIRED_ARGUMENT ],
+        [ '--visibility', '-v', GetoptLong::REQUIRED_ARGUMENT ],
+      )
+      opts.each do |opt, arg|
+        case opt
+        when '--format'
+          arg == 'json' and
+            self.format = arg
+        when '--project'
+          arg.empty? or
+            @target_proj = arg
+        when '--package'
+          arg.empty? or
+            @target_package = arg
+        when '--release'
+          arg.empty? or
+            @target_release = arg
+        when '--visibility'
+          unless %w(public private hidden).member?(arg)
+            logger.fatal "Invalid visibility status: #{arg}"
+            exit
+          end
+          @visibility = arg
+        end
+      end
+    end
+    
+    def list
+      release = api.get_release target_proj, target_package, target_release
+      list = release.files
+      if format == 'json'
+        puts list.map{|i| i.to_hash}.to_json
+      else
+        list.each do |f|
+          puts format_file(f)
+        end
+      end
+    end
+
+    def create
+      filename = ARGV.shift
+      if !filename
+        logger.fatal "Target filename is missing."
+        help
+        return
+      end
+      file = Pathname('.') + filename
+      logger.debug "Calculating digest for #{file}..."
+      digests = {
+        sha256: hexdigest(Digest::SHA256, file),
+        sha1:   hexdigest(Digest::SHA1, file),
+        md5:    hexdigest(Digest::MD5, file),
+      }
+      fio = file.open
+      logger.level <= Logger::INFO and
+        OSDN::CLI._show_progress = true
+      logger.info "Starting upload #{file}..."
+      f = api.create_release_file target_proj, target_package, target_release, fio, visibility: @visibility
+      fio.close
+      OSDN::CLI._show_progress = false
+      if digests.find { |type, dig| dig != f.send("digest_#{type}") }
+        logger.error "File digests are mismatch! Upload file #{file} may be broken! Please check."
+      else
+        logger.info "Upload completed."
+      end
+      puts format_file(f)
+    end
+
+    def update
+      target_id = ARGV.shift
+      if !target_id
+        logger.fatal "Target file ID is missing."
+        help
+        return
+      end
+      if @visibility.nil?
+        logger.fatal "Visibility status is missing. Use '-v <public|private|hidden>'."
+        return
+      end
+      f = api.update_release_file target_proj, target_package, target_release, target_id, visibility: @visibility
+      logger.info "file #{target_id} has been updated."
+      puts format_file(f)
+    end
+
+    def delete
+      target_id = ARGV.shift
+      if !target_id
+        logger.fatal "Target file ID is missing."
+        help
+        return
+      end
+      f = api.delete_release_file target_proj, target_package, target_release, target_id
+      logger.info "file #{target_id} has been deleted."
+    end
+  end
+end; end; end