Class: Gitlab::Ci::Build::Artifacts::Metadata::Entry

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/ci/build/artifacts/metadata/entry.rb

Overview

Class that represents an entry (path and metadata) to a file or directory in GitLab CI Build Artifacts binary file / archive

This is IO-operations safe class, that does similar job to Ruby's Pathname but without the risk of accessing filesystem.

This class is working only with UTF-8 encoded paths.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, entries) ⇒ Entry


17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 17

def initialize(path, entries)
  @path = path.dup.force_encoding('UTF-8')
  @entries = entries

  if path.include?("\0")
    raise ArgumentError, 'Path contains zero byte character!'
  end

  unless path.valid_encoding?
    raise ArgumentError, 'Path contains non-UTF-8 byte sequence!'
  end
end

Instance Attribute Details

#entriesObject (readonly)

Returns the value of attribute entries


14
15
16
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 14

def entries
  @entries
end

#nameObject

Returns the value of attribute name


15
16
17
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 15

def name
  @name
end

#pathObject (readonly)

Returns the value of attribute path


14
15
16
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 14

def path
  @path
end

Instance Method Details

#==(other) ⇒ Object


109
110
111
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 109

def ==(other)
  @path == other.path && @entries == other.entries
end

#basenameObject


47
48
49
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 47

def basename
  (directory? && !blank_node?) ? name + '/' : name
end

#blank_node?Boolean


86
87
88
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 86

def blank_node?
  @path.empty? # "" is considered to be './'
end

#childrenObject


55
56
57
58
59
60
61
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 55

def children
  return [] unless directory?
  return @children if @children

  child_pattern = %r{^#{Regexp.escape(@path)}[^/]+/?$}
  @children = select_entries { |path| path =~ child_pattern }
end

#directories(opts = {}) ⇒ Object


63
64
65
66
67
68
69
70
71
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 63

def directories(opts = {})
  return [] unless directory?
  dirs = children.select(&:directory?)
  return dirs unless has_parent? && opts[:parent]

  dotted_parent = parent
  dotted_parent.name = '..'
  dirs.prepend(dotted_parent)
end

#directory?Boolean


30
31
32
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 30

def directory?
  blank_node? || @path.end_with?('/')
end

#empty?Boolean


94
95
96
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 94

def empty?
  children.empty?
end

#exists?Boolean


90
91
92
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 90

def exists?
  blank_node? || @entries.include?(@path)
end

#file?Boolean


34
35
36
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 34

def file?
  !directory?
end

#filesObject


73
74
75
76
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 73

def files
  return [] unless directory?
  children.select(&:file?)
end

#has_parent?Boolean


38
39
40
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 38

def has_parent?
  nodes > 0
end

#inspectObject


113
114
115
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 113

def inspect
  "#{self.class.name}: #{@path}"
end

#metadataObject


78
79
80
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 78

def 
  @entries[@path] || {}
end

#nodesObject


82
83
84
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 82

def nodes
  @path.count('/') + (file? ? 1 : 0)
end

#parentObject


42
43
44
45
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 42

def parent
  return nil unless has_parent?
  self.class.new(@path.chomp(basename), @entries)
end

#to_sObject


105
106
107
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 105

def to_s
  @path
end

#total_sizeObject


98
99
100
101
102
103
# File 'lib/gitlab/ci/build/artifacts/metadata/entry.rb', line 98

def total_size
  descendant_pattern = %r{^#{Regexp.escape(@path)}}
  entries.sum do |path, entry|
    (entry[:size] if path =~ descendant_pattern).to_i
  end
end