Class: Pkg::Tar

Inherits:
Object
  • Object
show all
Includes:
FileUtils
Defined in:
lib/packaging/tar.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Tar

Returns a new instance of Tar.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/packaging/tar.rb', line 10

def initialize
  @tar      = Pkg::Util::Tool.find_tool('tar', :required => true)
  @project  = Pkg::Config.project
  @version  = Pkg::Config.version
  @files    = Pkg::Config.files
  @target   = File.join(Pkg::Config.project_root, "pkg", "#{@project}-#{@version}.tar.gz")

  # We require that the excludes list be a string (which is space
  # separated, we hope)(deprecated) or an array.
  #
  if Pkg::Config.tar_excludes
    if Pkg::Config.tar_excludes.is_a?(String)
      warn "warning: `tar_excludes` should be an array, not a string"
      @excludes = Pkg::Config.tar_excludes.split(' ')
    elsif Pkg::Config.tar_excludes.is_a?(Array)
      @excludes = Pkg::Config.tar_excludes
    else
      fail "Tarball excludes must either be an array or a string, not #{@excludes.class}"
    end
  else
    @excludes = []
  end

  # On the other hand, support for explicit templates started with Arrays,
  # so that's all we support.
  #
  if Pkg::Config.templates
    @templates = Pkg::Config.templates.dup
    fail "templates must be an array" unless @templates.is_a?(Array)
    expand_templates
  end
end

Instance Attribute Details

#excludes ⇒ Object

Returns the value of attribute excludes.



7
8
9
# File 'lib/packaging/tar.rb', line 7

def excludes
  @excludes
end

#files ⇒ Object

Returns the value of attribute files.



7
8
9
# File 'lib/packaging/tar.rb', line 7

def files
  @files
end

#project ⇒ Object

Returns the value of attribute project.



7
8
9
# File 'lib/packaging/tar.rb', line 7

def project
  @project
end

#tar(target, source) ⇒ Object (readonly)

Returns the value of attribute tar.



8
9
10
# File 'lib/packaging/tar.rb', line 8

def tar
  @tar
end

#target ⇒ Object

Returns the value of attribute target.



7
8
9
# File 'lib/packaging/tar.rb', line 7

def target
  @target
end

#templates ⇒ Object

Returns the value of attribute templates.



7
8
9
# File 'lib/packaging/tar.rb', line 7

def templates
  @templates
end

#version ⇒ Object

Returns the value of attribute version.



7
8
9
# File 'lib/packaging/tar.rb', line 7

def version
  @version
end

Instance Method Details

#clean_up(workdir) ⇒ Object



139
140
141
# File 'lib/packaging/tar.rb', line 139

def clean_up(workdir)
  rm_rf workdir
end

#expand_templates ⇒ Object

The templates of a project can include globs, which may expand to an arbitrary number of files. This method expands all of the templates using Dir.glob and then filters out any templates that live in the packaging tools themselves. If the template is a source/target combination, it is returned to the array untouched.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/packaging/tar.rb', line 66

def expand_templates
  @templates.map! do |tempfile|
    if tempfile.is_a?(String)
      # Expand possible globs to all matching entries
      Dir.glob(File.join(Pkg::Config::project_root, tempfile))
    elsif tempfile.is_a?(Hash)
      tempfile
    end
  end
  @templates.flatten!

  # Reject matches that are templates from packaging itself. These will contain the packaging root.
  # These tend to come from the current tar.rake implementation.
  @templates.reject! { |temp| temp.is_a?(String) && temp.match(/#{Pkg::Config::packaging_root}/) }
end

#install_files_to(workdir) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/packaging/tar.rb', line 43

def install_files_to(workdir)
  # It is nice to use arrays in YAML to represent array content, but we used
  # to support a mode where a space-separated string was used.  Support both
  # to allow a gentle migration to a modern style...
  patterns =
    case @files
    when String
      $stderr.puts "warning: `files` should be an array, not a string"
      @files.split(' ')
    when Array
      @files
    else
      raise "`files` must be a string or an array!"
    end

  Pkg::Util::File.install_files_into_dir(patterns, workdir)
end

#pkg! ⇒ Object



143
144
145
146
147
148
149
150
# File 'lib/packaging/tar.rb', line 143

def pkg!
  workdir = File.join(Pkg::Util::File.mktemp, "#{@project}-#{@version}")
  mkpath workdir
  self.install_files_to workdir
  self.template(workdir)
  self.tar(@target, workdir)
  self.clean_up workdir
end

#template(workdir = nil) ⇒ Object

Given the tar object's template files (assumed to be in Pkg::Config.project_root), transform them, removing the originals. If workdir is passed, assume Pkg::Config.project_root exists in workdir



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/packaging/tar.rb', line 85

def template(workdir = nil)
  workdir ||= Pkg::Config.project_root
  root = Pathname.new(Pkg::Config.project_root)

  # Templates can be either a string or a hash of source and target. If it
  # is a string, the target is assumed to be the same path as the
  # source,with the extension removed. If it is a hash, we assume nothing
  # and use the provided source and target.
  @templates.each do |cur_template|
    if cur_template.is_a?(String)
      template_file = File.expand_path(cur_template)
      target_file = template_file.sub(File.extname(template_file), "")
    elsif cur_template.is_a?(Hash)
      template_file = File.expand_path(cur_template["source"])
      target_file = File.expand_path(cur_template["target"])
    end

    #   We construct paths to the erb template and its proposed target file
    #   relative to the project root, *not* fully qualified. This allows us
    #   to, given a temporary workdir containing a copy of the project,
    #   construct the full path to the erb and target file inside the
    #   temporary workdir.
    #
    rel_path_to_template = Pathname.new(template_file).relative_path_from(root).to_s
    rel_path_to_target = Pathname.new(target_file).relative_path_from(root).to_s

    #   What we pass to Pkg::util::File.erb_file are the paths to the erb
    #   and target inside of a temporary project directory. We are, in
    #   essence, templating "in place." This is why we remove the original
    #   files - they're not the originals in the authoritative project
    #   directory, but the originals in the temporary working copy.
    if File.exist?(File.join(workdir, rel_path_to_template))
      mkpath(File.dirname(File.join(workdir, rel_path_to_target)), :verbose => false)
      Pkg::Util::File.erb_file(File.join(workdir, rel_path_to_template), File.join(workdir, rel_path_to_target), true, :binding => Pkg::Config.get_binding)
    elsif File.exist?(File.join(root, rel_path_to_template))
      mkpath(File.dirname(File.join(workdir, rel_path_to_target)), :verbose => false)
      Pkg::Util::File.erb_file(File.join(root, rel_path_to_template), File.join(workdir, rel_path_to_target), false, :binding => Pkg::Config.get_binding)
    else
      fail "Expected to find #{template_file} in #{root} for templating. But it was not there. Maybe you deleted it?"
    end
  end
end