neptools

Modding tools to Neptunia games
git clone https://git.neptards.moe/neptards/neptools.git
Log | Files | Refs | Submodules | README | LICENSE

package.rb (4374B)


      1 #! /usr/bin/env ruby
      2 
      3 require 'concurrent'
      4 require 'httparty'
      5 require 'minitar'
      6 require 'time'
      7 require 'xz'
      8 require 'zip'
      9 
     10 if ARGV.size < 2
     11   $stderr.puts "Usage: #{$0} version build_number [quick]"
     12   exit 1
     13 end
     14 
     15 VERSION = ARGV[0]
     16 BUILD_NUMBER = ARGV[1].to_i
     17 QUICK = ARGV[2]
     18 
     19 BASE_URL = "https://jenkins.neptards.moe/job/neptools/job/build_test/#{BUILD_NUMBER}/"
     20 
     21 def get_artifacts job
     22   HTTParty.get("#{BASE_URL}/#{job}/api/json?tree=artifacts[relativePath]").
     23     parsed_response['artifacts'].map {|x| x['relativePath'] }
     24 end
     25 
     26 def get_artifact job, path
     27   puts "Getting artifact #{job} #{path}"
     28   HTTParty.get "#{BASE_URL}/#{job}/artifact/#{path}"
     29 end
     30 
     31 NEVER = /(?!x)x/ # regex that never matches
     32 class ComprBase
     33   def self.create name
     34     res = new name
     35     begin
     36       yield res
     37     ensure
     38       res.close
     39     end
     40   end
     41 
     42   def boilerplate
     43     add_local_file 'COPYING'
     44     add_local_file 'COPYING.THIRD_PARTY'
     45     add_local_file 'README.md'
     46   end
     47 
     48   def artifact job, path, mode
     49     art = get_artifact job, path
     50     date = Time.httpdate art.headers['last-modified']
     51     add_file File.basename(path), mode, date, art.body
     52   end
     53 
     54   def artifacts job, filter = //, exe = NEVER
     55     get_artifacts(job).each do |art|
     56       next if art.end_with? '.xml'
     57       artifact job, art, (art =~ exe ? 0755 : 0644) if art =~ filter
     58     end
     59   end
     60 
     61   # do not use rubyzip's File#add: it will add a broken symlink when adding a
     62   # file that is a symlink in the fs
     63   def add_local_file fname
     64     stat = File.stat fname
     65     add_file fname, stat.mode, stat.mtime, File.read(fname)
     66   end
     67 end
     68 
     69 Zip.default_compression = 0 # will zopfli after
     70 class MyZip < ComprBase
     71   def initialize name
     72     name << ".zip"
     73     puts "Generating #{name}"
     74     File.unlink name if File.exists? name
     75     @zip = Zip::File.open name, create: true
     76   end
     77 
     78   def close
     79     @zip.close
     80     system 'advzip', '-z4k', @zip.name, exception: true unless QUICK
     81   end
     82 
     83   def add_file fname, mode, time, body
     84     @zip.get_output_stream fname, permissions: mode, time: time.getutc do |s|
     85       s.write body
     86     end
     87   end
     88 end
     89 
     90 class MyTarXz < ComprBase
     91   def initialize name
     92     name << ".tar.xz"
     93     puts "Generating #{name}"
     94     compr = QUICK ? { level: 0 } : { level: 9, extreme: true }
     95     @xz = XZ::StreamWriter.open name, **compr, external_encoding: Encoding::BINARY
     96     begin
     97       @tar = Minitar::Writer.open @xz
     98       begin
     99         @dir = File.basename(name).gsub /\.[a-zA-Z.]*$/, ''
    100         @tar.mkdir @dir, mode: 0755, uid: 1000, gid: 1000 # todo mtime
    101       rescue
    102         @tar.close
    103         raise
    104       end
    105     rescue
    106       @xz.close
    107       File.unlink name
    108       raise
    109     end
    110   end
    111 
    112   def close
    113     @tar.close
    114     @xz.close
    115   end
    116 
    117   def add_file fname, mode, time, body
    118     time = Time.new time unless time.is_a? Time
    119     @tar.add_file_simple \
    120            "#{@dir}/#{File.basename fname}", mode: mode,
    121            uid: 1000, gid: 1000, mtime: time.to_i, data: body
    122   end
    123 end
    124 
    125 
    126 $pool = Concurrent::FixedThreadPool.new Etc.nprocessors
    127 def post &blk
    128   $pool.post do
    129     begin
    130       blk[]
    131     rescue Exception => e
    132       puts e, e.backtrace
    133       exit! 1
    134     end
    135   end
    136 end
    137 
    138 def gen_set cls, job, name, normal_pat, sym_pat, exe_pat = NEVER
    139   post do
    140     cls.create "pkg/neptools-#{name}-#{VERSION}" do |o|
    141       o.boilerplate
    142       o.artifacts job, normal_pat, exe_pat
    143     end
    144   end
    145   post do
    146     cls.create "pkg/neptools-#{name}-#{VERSION}.symbols" do |o|
    147       o.artifacts job, sym_pat
    148     end
    149   end
    150 
    151   post do
    152     cls.create "pkg/neptools-#{name}-#{VERSION}-debug" do |o|
    153       o.boilerplate
    154       o.artifacts job.gsub(/mode=rel/, 'mode=debug'), //, exe_pat
    155     end
    156   end
    157 end
    158 
    159 gen_set MyZip, 'architecture=arm,lua=no,mode=rel,os_compiler=vita-gcc',
    160         'vita', /\.suprx$/, /\/[^.]+$/
    161 gen_set MyTarXz, 'architecture=amd64,lua=lua,mode=rel,os_compiler=linux_steamrt-clang',
    162         'linux_amd64', /\/[^.]+$/, /\.debug$/, /\/[^.]+$/
    163 
    164 gen_set MyZip, 'architecture=x86,lua=lua,mode=rel,os_compiler=windows_vista-clang_msvc12',
    165         'windows', /\.(exe|dll)$/, /\.pdb$/, /\.exe$/
    166 gen_set MyZip, 'architecture=x86,lua=no,mode=rel,os_compiler=windows_vista-clang_msvc12',
    167         'windows-nolua', /\.(exe|dll)$/, /\.pdb$/, /\.exe$/
    168 gen_set MyZip, 'architecture=x86,lua=ljx,mode=rel,os_compiler=windows_vista-clang_msvc12',
    169         'windows-ljx', /\.(exe|dll)$/, /\.pdb$/, /\.exe$/
    170 
    171 $pool.shutdown
    172 $pool.wait_for_termination