Class: Mtree::FileSpecification

Inherits:
Object
  • Object
show all
Defined in:
lib/mtree/file_specification.rb

Overview

rubocop:disable Metrics/ClassLength

Constant Summary collapse

VALID_ATTRIBUTES =

VALID_ATTRIBUTES = %i[cksum device flags gid gname link md5 mode nlink nochange optional rmd160 sha1 sha256 sha384 sha512 size tags time type uid uname].freeze

%i[gid gname link mode nochange optional type uid uname].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, attributes = {}) ⇒ FileSpecification

Returns a new instance of FileSpecification.



22
23
24
25
26
27
28
29
30
31
# File 'lib/mtree/file_specification.rb', line 22

def initialize(filename, attributes = {})
  @filename = filename
  @relative_path = filename
  if (invalid_keys = attributes.keys - VALID_ATTRIBUTES) != []
    raise "Unsupported attribute: #{invalid_keys.first}"
  end

  @attributes = attributes
  @children = []
end

Instance Attribute Details

#childrenObject

Returns the value of attribute children.



20
21
22
# File 'lib/mtree/file_specification.rb', line 20

def children
  @children
end

#filenameObject

Returns the value of attribute filename.



20
21
22
# File 'lib/mtree/file_specification.rb', line 20

def filename
  @filename
end

#relative_pathObject

Returns the value of attribute relative_path.



20
21
22
# File 'lib/mtree/file_specification.rb', line 20

def relative_path
  @relative_path
end

Instance Method Details

#<<(child) ⇒ Object



101
102
103
104
105
# File 'lib/mtree/file_specification.rb', line 101

def <<(child)
  children << child

  child.relative_path = File.join(relative_path, child.filename)
end

#attributesObject

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/mtree/file_specification.rb', line 140

def attributes # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
  parts = []

  parts << format('gid=%d', gid)     if gid
  parts << format('gname=%s', gname) if gname
  parts << format('link=%s', link)   if link
  parts << format('mode=0%o', mode)  if mode
  parts << 'nochange'                if nochange
  parts << 'optional'                if optional
  parts << format('type=%s', type)   if type
  parts << format('uid=%d', uid)     if uid
  parts << format('uname=%s', uname) if uname

  parts.join(' ')
end

#create(root) ⇒ Object



85
86
87
88
89
90
91
92
93
94
# File 'lib/mtree/file_specification.rb', line 85

def create(root)
  case type
  when 'dir'  then FileUtils.mkdir_p(full_filename(root))
  when 'file' then FileUtils.touch(full_filename(root))
  when 'link'
    FileUtils.rm_rf(full_filename(root))
    FileUtils.ln_s(link, full_filename(root))
  end
  update(root)
end

#each {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:



61
62
63
64
65
66
67
# File 'lib/mtree/file_specification.rb', line 61

def each(&block)
  yield(self)

  children.each do |child|
    child.each(&block)
  end
end

#enforce(root) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/mtree/file_specification.rb', line 69

def enforce(root)
  if exist?(root)
    update(root) unless nochange
  else
    create(root)
  end

  children.each do |child|
    child.enforce(root)
  end
end

#exist?(root) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/mtree/file_specification.rb', line 81

def exist?(root)
  current_type(root) == type
end

#leaves!Object



107
108
109
110
111
112
113
# File 'lib/mtree/file_specification.rb', line 107

def leaves!
  if children.any?
    self.nochange = true
    children.each(&:leaves!)
  end
  self
end

#match?(root) ⇒ Boolean

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength

Returns:

  • (Boolean)


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mtree/file_specification.rb', line 33

def match?(root) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
  res = true
  problems = []

  begin
    @attributes.each do |attr, expected|
      actual = send("current_#{attr}", root)

      problems << { attr: attr, expected: expected, actual: actual } if expected != actual
    end
  rescue Errno::ENOENT
    puts "#{relative_path} missing"
    res = false
  end

  if problems.any? && !nochange
    puts("#{relative_path}:")
    puts(problems.map { |problem| format("\t%<attr>s (%<expected>s, %<actual>s)", problem) })
    res = false
  end

  children.each do |child|
    res &= child.match?(root)
  end

  res
end


115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/mtree/file_specification.rb', line 115

def symlink_to!(destination)
  unless nochange
    @attributes = {
      type: 'link',
      link: File.join(destination, relative_path).sub(%r{/\.$}, '').sub(%r{/\./}, '/'),
    }
  end
  children.each do |child|
    child.symlink_to!(destination)
  end
  self
end

#to_s(options = {}) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/mtree/file_specification.rb', line 128

def to_s(options = {})
  descendent = ''
  if children.any?
    descendent = children.map do |child|
      child.to_s(options)
    end.join
    descendent.gsub!(/^/, '    ') if options[:indent]
  end

  "#{filename} #{attributes}\n#{descendent}..\n"
end

#update(root) ⇒ Object



96
97
98
99
# File 'lib/mtree/file_specification.rb', line 96

def update(root)
  FileUtils.chown(uname, gname, full_filename(root)) if uname || gname
  FileUtils.chmod(mode, full_filename(root)) if mode
end