summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2016-01-08 12:35:49 +0100
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2016-01-14 12:48:15 +0100
commit387b27813d1d496c015f4f174812b4761c32648d (patch)
tree59061040f651df04895060bfc48d9b5f36ee5f34 /lib
parent09c82c6fdc494de0d64cb58b4b61a86104ff1131 (diff)
downloadgitlab-ce-387b27813d1d496c015f4f174812b4761c32648d.tar.gz
Change format of artifacts metadata from text to binary 0.0.1
This changes the format of metadata to handle paths, that may contain whitespace characters, new line characters and non-UTF-8 characters. Now those paths along with metadata in JSON format are stored as length-prefixed strings (uint32 prefix). Metadata file has a custom format: 1. First string field is metadata version field (string) 2. Second string field is metadata errors field (JSON strong) 3. All subsequent fields is pair of path (string) and path metadata in JSON format. Path's metadata contains all fields that where possible to extract from ZIP archive like date of modification, CRC, compressed size, uncompressed size and comment.
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/ci/build/artifacts/metadata.rb68
1 files changed, 58 insertions, 10 deletions
diff --git a/lib/gitlab/ci/build/artifacts/metadata.rb b/lib/gitlab/ci/build/artifacts/metadata.rb
index 1f3000e7c8a..d90a64fdbb8 100644
--- a/lib/gitlab/ci/build/artifacts/metadata.rb
+++ b/lib/gitlab/ci/build/artifacts/metadata.rb
@@ -17,18 +17,33 @@ module Gitlab
File.exists?(@file)
end
+ def full_version
+ gzip do|gz|
+ read_string(gz) do |size|
+ raise StandardError, 'Artifacts metadata file empty!' unless size
+ end
+ end
+ end
+
+ def version
+ full_version.match(/\w+ (\d+\.\d+\.\d+)/).captures.first
+ end
+
+ def errors
+ gzip do|gz|
+ read_string(gz) # version
+ JSON.parse(read_string(gz))
+ end
+ end
+
def match!
raise StandardError, 'Metadata file not found !' unless exists?
- paths, metadata = [], []
- each do |line|
- next unless line =~ %r{^#{Regexp.escape(@path)}[^/\s]*/?\s}
- path, meta = line.split(' ')
- paths.push(path)
- metadata.push(meta)
+ gzip do |gz|
+ read_string(gz) # version field
+ read_string(gz) # errors field
+ iterate_entries(gz)
end
-
- [paths, metadata.map { |meta| JSON.parse(meta, symbolize_names: true) }]
end
def to_string_path
@@ -38,11 +53,44 @@ module Gitlab
private
- def each
+ def iterate_entries(gz)
+ paths, metadata = [], []
+
+ until gz.eof? do
+ begin
+ path = read_string(gz)
+ meta = read_string(gz)
+
+ next unless path =~ %r{^#{Regexp.escape(@path)}[^/\s]*/?$}
+
+ paths.push(path)
+ metadata.push(JSON.parse(meta, symbolize_names: true))
+ rescue JSON::ParserError
+ next
+ end
+ end
+
+ [paths, metadata]
+ end
+
+ def read_string_size(gz)
+ binary = gz.read(4)
+ binary.unpack('L>')[0] if binary
+ end
+
+ def read_string(gz)
+ string_size = read_string_size(gz)
+ yield string_size if block_given?
+ return false unless string_size
+ gz.read(string_size).chomp
+ end
+
+ def gzip
open do |file|
gzip = Zlib::GzipReader.new(file)
- gzip.each_line { |line| yield line }
+ result = yield gzip
gzip.close
+ result
end
end