class WarpEngine::ShelfService
Builds one shelf (a WarpEngine::Shelves shelf): a folder of the file container that holds the latest build of every listed title of a platform under a fixed name, with an INDEX.TXT listing them. A flat shelf holds one file a title, a folders shelf one folder a title and kind.
Constants
- CHUNK
-
The read size, in bytes, when copying a file and computing its CRC32.
- Entry
-
One title and kind on the shelf: the shelf
file(or folder) name, the assetkind,version,sizeandcrc32of the source, thetitle,authoranddescriptionof the software, thesourcepath, thesoftwareand, on afoldersshelf, thefolderspec. - HEADER
-
The first line of the index: the format version and the field names.
- INFO_FILE
-
The program description file written into each folder of a
foldersshelf. - LINE_LIMIT
-
The longest index line, in bytes; the description is cut to fit.
- MANIFEST_FILE
-
The file list (
crc32 size pathper file) written into each folder of afoldersshelf. - Result
-
The outcome of
sync!: theshelf, theentrieson it, theskippedsoftwares, the entrieswritten, the file namesremoved, and whether the index text changed. - Skip
-
A software left off the shelf, with the
reason.
Attributes
The WarpEngine::Shelves shelf being built.
Public Class Methods
Source
# File app/services/warp_engine/shelf_service.rb, line 55 def self.clean(text) I18n.transliterate(text.to_s).gsub(/[|\r\n\t]/, " ").gsub(/[^\x20-\x7E]/, "").squeeze(" ").strip end
Returns text as printable ASCII for the index: transliterated, with |, tabs and line breaks turned into spaces, other characters dropped and spaces squeezed.
Source
# File app/services/warp_engine/shelf_service.rb, line 63 def initialize(shelf) @shelf = shelf end
- shelf
-
the
WarpEngine::Shelvesshelf to build
Public Instance Methods
Source
# File app/services/warp_engine/shelf_service.rb, line 74 def plan entries = [] skipped = [] taken = {} candidates.each do |software| found, reasons = consider(software) skipped << Skip.new(software: software, reason: reasons.join("; ")) if found.empty? found.each do |entry| if taken.key?(entry.file) skipped << Skip.new(software: software, reason: "#{entry.file} is taken by #{taken[entry.file].name}") else taken[entry.file] = software entries << entry end end end [ entries.sort_by { |entry| [ entry.title.to_s.downcase, entry.file ] }, skipped ] end
Decides what the shelf holds, without touching the disk: for every kept, ungated software of the platform with a listed status, the latest release that has each kind of the shelf. A name already taken (by an older software) skips the newer one.
Returns [entries, skipped]: the Entry list sorted by title, and the Skip list.
Source
# File app/services/warp_engine/shelf_service.rb, line 105 def sync!(dry_run: false) entries, skipped = plan with_lock do previous = read_index written = entries.select { |entry| stale?(entry, previous[entry.file]) } (entries - written).each { |entry| entry.crc32 = previous.dig(entry.file, :crc32) } removed = removable(previous) - entries.map(&:file) unless dry_run FileUtils.mkdir_p(shelf.directory) written.each { |entry| place(entry) } end index = render(entries) index_changed = index != current_index_text unless dry_run replace_index(index) if index_changed removed.each { |file| FileUtils.rm_rf(File.join(shelf.directory, file)) } end Result.new(shelf: shelf, entries: entries, skipped: skipped, written: written, removed: removed, index_changed: index_changed) end end
Brings the shelf folder in line with plan, under an exclusive file lock: copies (or unpacks) the entries whose version, size or source changed, replaces the index when its text changes, then removes the files (or, on a folders shelf, the formerly listed folders) that left the shelf. Entries not rewritten keep the CRC32 of the previous index.
- dry_run
-
when
true, only computes theResultand writes nothing
Returns a Result. Raises ArgumentError when a folder zip holds an unsafe path.