Class: Qrpm::Rpm

Inherits:
Object
  • Object
show all
Defined in:
lib/qrpm/rpm.rb

Overview

Knows the following RPM fields:

name        Package name (mandatory)
version     Version (mandatory)
release     Release
summary     Short one-line description of package (mandatory)
description Description
packager    Name of the packager (defaults to the name of the user or 
            $USER@$HOSTNAME if not found)
license     License (defaults to GPL)
require     Array of required packages
make        Controls the build process:
              null    Search the top-level directory for configure or
                      make files and runs them. Skip building if not 
                      found. This is the default
              true    Expect the top-level directory to contain 
                      configure or make files and runs them. It is an 
                      error if the Makefile is missing
              (array of commands)
                      Runs the commands to build the project

Each field has a dynamically generated accessor method that can be referenced in the template file

Constant Summary collapse

MANDATORY_FIELDS =
%w(name version summary)
FIELDS =

Maps from field name to array of allowed types for that field

MANDATORY_FIELDS.map { |f| [f, [String]] }.to_h.merge({
  "release" => [String],
  "description" => [String],
  "packager" => [String],
  "license" => [String],
  "group" => [String],
  "include" => [Array, String],
  "require" => [Array, String],
  "make" => [Array, String]
})
RPM_DIRS =
%w(SOURCES BUILD RPMS SPECS SRPMS tmp)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(srcdir, fields, nodes, template: QRPM_ERB_FILE) ⇒ Rpm

Returns a new instance of Rpm.



81
82
83
84
85
86
87
88
# File 'lib/qrpm/rpm.rb', line 81

def initialize(srcdir, fields, nodes, template: QRPM_ERB_FILE)
  constrain srcdir, String
  constrain fields, { String => Node }
  constrain nodes, [FileNode]
  @fields, @nodes = fields, nodes
  @srcdir = srcdir
  @template = template
end

Instance Attribute Details

#fieldsObject (readonly)

Returns the value of attribute fields.



67
68
69
# File 'lib/qrpm/rpm.rb', line 67

def fields
  @fields
end

#nodesObject (readonly)

Returns the value of attribute nodes.



68
69
70
# File 'lib/qrpm/rpm.rb', line 68

def nodes
  @nodes
end

#specObject (readonly)

The content of the SPEC file



74
75
76
# File 'lib/qrpm/rpm.rb', line 74

def spec
  @spec
end

#srcdirObject (readonly)

The source directory



71
72
73
# File 'lib/qrpm/rpm.rb', line 71

def srcdir
  @srcdir
end

Instance Method Details

#build(target: :rpm, file: nil, verbose: false, destdir: ".", builddir: nil) ⇒ Object



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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/qrpm/rpm.rb', line 93

def build(target: :rpm, file: nil, verbose: false, destdir: ".", builddir: nil)
  verb = verbose ? "" : "&>/dev/null"
  begin
    if builddir
      rootdir = builddir
      FileUtils.rm_rf(rootdir)
      FileUtils.mkdir_p(rootdir)
    else
      rootdir = Dir.mktmpdir
    end

    spec_file = file || "#{name}.spec"
    tar_file = "#{name}.tar.gz"
    spec_path = "#{rootdir}/SPECS/#{spec_file}"
    tar_path = "#{rootdir}/SOURCES/#{tar_file}"

    # Create directories
    RPM_DIRS.each { |dir| FileUtils.mkdir_p "#{rootdir}/#{dir}" }

    # Roll tarball
    #
    # It is a bad idea to use git-archive to roll a tarball because we may
    # have configuration files/scripts that are not included in the git
    # repository. If needed then see
    # https://gist.github.com/arteymix/03702e3eb05c2c161a86b49d4626d21f
    #
    # Alternatively use the --add-file option? Then we need to know if
    # files are in the git repo or not
    system "tar zcf #{tar_path} --transform=s%^\./%#{name}/% ." # FIXME FIXME

    # Create spec file. Initial blanks are removed from each line in the file
    renderer = ERB.new(IO.read(@template).sub(/^__END__\n.*/m, ""), trim_mode: "-")
    @spec = renderer.result(binding).gsub(/^[[:blank:]]*/, "")

    # Emit spec or build RPM
    if target == :spec
      destfiles = ["#{destdir}/#{spec_file}"]
      IO.write(destfiles.first, @spec)
    else
      IO.write(spec_path, @spec)
      rpm_build_options = [
          "-v -ba",
          "-D 'debug_package %{nil}'",
          "--define \"_topdir #{rootdir}\"",
      ].join(" ")
      system "rpmbuild #{rpm_build_options} #{rootdir}/SPECS/#{name}.spec #{verb}" or
          raise "Failed building RPM file. Re-run with -v option to see errors"
      if target == :srpm
        destfiles = Dir["#{rootdir}/SRPMS/*"]
        !destfiles.empty? or raise Error, "No SRPM file found"
      elsif target == :rpm
        destfiles = Dir["#{rootdir}/RPMS/*/#{name}-[0-9]*"]
        !destfiles.empty? or raise Error, "No RPM file found"
      else
        raise ArgumentError, "Not a valid value for :target - #{target.inspect}"
      end
      system "cp #{destfiles.join " "} #{destdir}" or raise "Failed copying SRPM file"
    end
    return destfiles
  ensure
    FileUtils.remove_entry_secure rootdir if !builddir
  end
end

#dumpObject



157
158
159
160
161
162
163
164
165
# File 'lib/qrpm/rpm.rb', line 157

def dump
  puts self.class
  indent {
    puts "fields"
    indent { fields.sort_by(&:first).each { |k,v| puts "#{k}: #{v.value}" } }
    puts "nodes"
    indent { nodes.map(&:dump) }
  }
end

#filesObject



76
# File 'lib/qrpm/rpm.rb', line 76

def files() @files ||= nodes.select(&:file?) end

#has_configure?Boolean

Returns:

  • (Boolean)


90
# File 'lib/qrpm/rpm.rb', line 90

def has_configure?() ::File.exist? "#{srcdir}/configure" end

#has_make?Boolean

Returns:

  • (Boolean)


91
# File 'lib/qrpm/rpm.rb', line 91

def has_make?() ::File.exist? "#{srcdir}/Makefile" end


77
# File 'lib/qrpm/rpm.rb', line 77

def links() @links ||= nodes.select(&:link?) end


78
# File 'lib/qrpm/rpm.rb', line 78

def reflinks() @reflinks ||= nodes.select(&:reflink?) end


79
# File 'lib/qrpm/rpm.rb', line 79

def symlinks() @symlinks ||= nodes.select(&:symlink?) end