summaryrefslogtreecommitdiff
path: root/lib/rake/packagetask.rb
blob: e77345c19862c184249824378c9bfba8f19ec26d (plain)
1
2
3
4
5
6
7
8
9
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# Define a package task library to aid in the definition of
# redistributable package files.

require 'rake'
require 'rake/tasklib'

module Rake

  # Create a packaging task that will package the project into
  # distributable files (e.g zip archive or tar files).
  #
  # The PackageTask will create the following targets:
  #
  # [<b>:package</b>]
  #   Create all the requested package files.
  #
  # [<b>:clobber_package</b>]
  #   Delete all the package files.  This target is automatically
  #   added to the main clobber target.
  #
  # [<b>:repackage</b>]
  #   Rebuild the package files from scratch, even if they are not out
  #   of date.
  #
  # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tgz"</b>]
  #   Create a gzipped tar package (if <em>need_tar</em> is true).
  #
  # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tar.gz"</b>]
  #   Create a gzipped tar package (if <em>need_tar_gz</em> is true).
  #
  # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.tar.bz2"</b>]
  #   Create a bzip2'd tar package (if <em>need_tar_bz2</em> is true).
  #
  # [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.zip"</b>]
  #   Create a zip package archive (if <em>need_zip</em> is true).
  #
  # Example:
  #
  #   Rake::PackageTask.new("rake", "1.2.3") do |p|
  #     p.need_tar = true
  #     p.package_files.include("lib/**/*.rb")
  #   end
  #
  class PackageTask < TaskLib
    # Name of the package (from the GEM Spec).
    attr_accessor :name

    # Version of the package (e.g. '1.3.2').
    attr_accessor :version

    # Directory used to store the package files (default is 'pkg').
    attr_accessor :package_dir

    # True if a gzipped tar file (tgz) should be produced (default is false).
    attr_accessor :need_tar

    # True if a gzipped tar file (tar.gz) should be produced (default is false).
    attr_accessor :need_tar_gz

    # True if a bzip2'd tar file (tar.bz2) should be produced (default is false).
    attr_accessor :need_tar_bz2

    # True if a zip file should be produced (default is false)
    attr_accessor :need_zip

    # List of files to be included in the package.
    attr_accessor :package_files

    # Tar command for gzipped or bzip2ed archives.  The default is 'tar'.
    attr_accessor :tar_command

    # Zip command for zipped archives.  The default is 'zip'.
    attr_accessor :zip_command

    # Create a Package Task with the given name and version.
    def initialize(name=nil, version=nil)
      init(name, version)
      yield self if block_given?
      define unless name.nil?
    end

    # Initialization that bypasses the "yield self" and "define" step.
    def init(name, version)
      @name = name
      @version = version
      @package_files = Rake::FileList.new
      @package_dir = 'pkg'
      @need_tar = false
      @need_tar_gz = false
      @need_tar_bz2 = false
      @need_zip = false
      @tar_command = 'tar'
      @zip_command = 'zip'
    end

    # Create the tasks defined by this task library.
    def define
      fail "Version required (or :noversion)" if @version.nil?
      @version = nil if :noversion == @version

      desc "Build all the packages"
      task :package

      desc "Force a rebuild of the package files"
      task :repackage => [:clobber_package, :package]

      desc "Remove package products"
      task :clobber_package do
        rm_r package_dir rescue nil
      end

      task :clobber => [:clobber_package]

      [
        [need_tar, tgz_file, "z"],
        [need_tar_gz, tar_gz_file, "z"],
        [need_tar_bz2, tar_bz2_file, "j"]
      ].each do |(need, file, flag)|
        if need
          task :package => ["#{package_dir}/#{file}"]
          file "#{package_dir}/#{file}" => [package_dir_path] + package_files do
            chdir(package_dir) do
              sh %{#{@tar_command} #{flag}cvf #{file} #{package_name}}
            end
          end
        end
      end

      if need_zip
        task :package => ["#{package_dir}/#{zip_file}"]
        file "#{package_dir}/#{zip_file}" => [package_dir_path] + package_files do
          chdir(package_dir) do
            sh %{#{@zip_command} -r #{zip_file} #{package_name}}
          end
        end
      end

      directory package_dir

      file package_dir_path => @package_files do
        mkdir_p package_dir rescue nil
        @package_files.each do |fn|
          f = File.join(package_dir_path, fn)
          fdir = File.dirname(f)
          mkdir_p(fdir) if !File.exist?(fdir)
          if File.directory?(fn)
            mkdir_p(f)
          else
            rm_f f
            safe_ln(fn, f)
          end
        end
      end
      self
    end

    def package_name
      @version ? "#{@name}-#{@version}" : @name
    end

    def package_dir_path
      "#{package_dir}/#{package_name}"
    end

    def tgz_file
      "#{package_name}.tgz"
    end

    def tar_gz_file
      "#{package_name}.tar.gz"
    end

    def tar_bz2_file
      "#{package_name}.tar.bz2"
    end

    def zip_file
      "#{package_name}.zip"
    end
  end

end