class UnityPackage::UnityPackage

Used to create, modify, or read a .unitypackage file.

Constants

Entry

Attributes

missing_meta_error[R]

Public Class Methods

new(unitypackage = nil, missing_meta_error: true) click to toggle source
# File lib/unitypackage/unity_package.rb, line 16
def initialize(unitypackage = nil, missing_meta_error: true)
  @missing_meta_error = missing_meta_error
  @entries = {}

  return unless unitypackage

  File.open(unitypackage, 'rb') do |file|
    load(file)
  end
end

Public Instance Methods

<<(files) click to toggle source
# File lib/unitypackage/unity_package.rb, line 35
def <<(files)
  files = [files] unless files.is_a? Array
  files.each do |file|
    next if File.extname(file) == '.meta'

    file_meta = "#{file}.meta"

    if File.file?(file_meta)
      meta_contents = File.read(file_meta)

      # Note that .meta files are not actually YAML, but this works fine
      guid = YAML.safe_load(meta_contents)['guid']

      entry = Entry.new
      entry.pathname = file
      entry.meta = meta_contents
      entry.asset = File.read(file) if File.file?(file)
      @entries[guid] = entry
    elsif missing_meta_error
      raise IOError, "no meta file for #{file}"
    else
      puts "no meta file for #{file}"
    end
  end
end
each() { |guid, entry| ... } click to toggle source
# File lib/unitypackage/unity_package.rb, line 27
def each
  return to_enum(:each) unless block_given?

  @entries.each do |guid, entry|
    yield(guid, entry)
  end
end
write(io) click to toggle source
# File lib/unitypackage/unity_package.rb, line 61
def write(io)
  Zlib::GzipWriter.wrap(io) do |gz|
    Gem::Package::TarWriter.new(gz) do |tar|
      @entries.sort.each do |guid, entry|
        # ./guid/asset.meta
        tar.add_file_simple("./#{guid}/asset.meta", 0o444, entry.meta.bytesize) do |f|
          f.write(entry.meta)
        end

        # ./guid/pathname
        tar.add_file_simple("./#{guid}/pathname", 0o444, entry.pathname.bytesize) do |f|
          f.write(entry.pathname)
        end

        # ./guid/asset
        next unless entry.asset

        tar.add_file_simple("./#{guid}/asset", 0o444, entry.asset.bytesize) do |f|
          f.write(entry.asset)
        end
      end
    end
  end
end

Private Instance Methods

load(io) click to toggle source
# File lib/unitypackage/unity_package.rb, line 88
def load(io)
  Zlib::GzipReader.wrap(io) do |gz|
    Gem::Package::TarReader.new(gz) do |tar|
      tar.each do |entry|
        guid = entry.full_name.split('/')[-2]
        next unless guid

        file_name = File.basename(entry.full_name).split('.').last

        @entries[guid] ||= Entry.new
        # @entries[guid].instance_variable_set("@#{file_name}", entry.read)

        case file_name
        when 'pathname'
          @entries[guid].pathname = entry.read
        when 'asset'
          @entries[guid].asset = entry.read
        when 'meta'
          @entries[guid].meta = entry.read
        end
      end
    end
  end
end