File: Rakefile

package info (click to toggle)
ruby-archive-zip 0.11.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 772 kB
  • sloc: ruby: 5,052; makefile: 3
file content (247 lines) | stat: -rw-r--r-- 8,120 bytes parent folder | download | duplicates (2)
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# encoding: UTF-8
# -*- ruby -*-

require 'rubygems'

require 'erb'
require 'rake/testtask'
require 'rubygems/package_task'
require 'rake/clean'
require 'yard'

# Load the gemspec file for this project.
GEMSPEC = Dir['*.gemspec'].first
SPEC = eval(File.read(GEMSPEC), nil, GEMSPEC)

# The path to the version.rb file and a string to eval to find the version.
VERSION_RB = "lib/#{SPEC.name.gsub('-', '/')}/version.rb"
VERSION_REF =
  SPEC.name.split('-').map do |subname|
    subname.split('_').map(&:capitalize).join
  end.join('::') + "::VERSION"

# A dynamically generated list of files that should match the manifest (the
# combined contents of SPEC.files and SPEC.test_files).  The idea is for this
# list to contain all project files except for those that have been explicitly
# excluded.  This list will be compared with the manifest from the SPEC in order
# to help catch the addition or removal of files to or from the project that
# have not been accounted for either by an exclusion here or an inclusion in the
# SPEC manifest.
#
# NOTE:
# It is critical that the manifest is *not* automatically generated via globbing
# and the like; otherwise, this will yield a simple comparison between
# redundantly generated lists of files that probably will not protect the
# project from the unintentional inclusion or exclusion of files in the
# distribution.
PKG_FILES = FileList.new(Dir.glob('**/*', File::FNM_DOTMATCH)) do |files|
  # Exclude anything that doesn't exist as well as directories.
  files.exclude {|file| ! File.exist?(file) || File.directory?(file)}
  # Exclude Git administrative files.
  files.exclude(%r{(^|[/\\])\.git(ignore|modules|keep)?([/\\]|$)})
  # Exclude editor swap/temporary files.
  files.exclude('**/.*.sw?')
  # Exclude gemspec files.
  files.exclude('*.gemspec')
  # Exclude the README template file.
  files.exclude('README.md.erb')
  # Exclude resources for bundler.
  files.exclude('Gemfile', 'Gemfile.lock')
  files.exclude(%r{^.bundle([/\\]|$)})
  files.exclude(%r{^vendor/bundle([/\\]|$)})
  # Exclude generated content, except for the README file.
  files.exclude(%r{^(pkg|doc|.yardoc)([/\\]|$)})
  # Exclude Rubinius compiled Ruby files.
  files.exclude('**/*.rbc')
  files.exclude('.rbx/**/*')
end

# Make sure that :clean and :clobber will not whack the repository files.
CLEAN.exclude('.git/**')
# Vim swap files are fair game for clean up.
CLEAN.include('**/.*.sw?')

# Returns the value of the VERSION environment variable as a Gem::Version object
# assuming it is set and a valid Gem version string.  Otherwise, raises an
# exception.
def get_version_argument
  version = ENV['VERSION']
  if version.to_s.empty?
    raise "No version specified: Add VERSION=X.Y.Z to the command line"
  end
  begin
    Gem::Version.create(version.dup)
  rescue ArgumentError
    raise "Invalid version specified in `VERSION=#{version}'"
  end
end

# Performs an in place, per line edit of the file indicated by _path_ by calling
# the sub method on each line and passing _pattern_, _replacement_, and _b_ as
# arguments.
def file_sub(path, pattern, replacement = nil, &b)
  tmp_path = "#{path}.tmp"
  File.open(path) do |infile|
    File.open(tmp_path, 'w') do |outfile|
      infile.each do |line|
        outfile.write(line.sub(pattern, replacement, &b))
      end
    end
  end
  File.rename(tmp_path, path)
end

# Updates the version string in the gemspec file and a version.rb file it to the
# string in _version_.
def set_version(version)
  file_sub(GEMSPEC, /(\.version\s*=\s*).*/, "\\1'#{version}'")
  file_sub(VERSION_RB, /^(\s*VERSION\s*=\s*).*/, "\\1'#{version}'")
end

# Returns a string that is line wrapped at word boundaries, where each line is
# no longer than _line_width_ characters.
#
# This is mostly lifted directly from ActionView::Helpers::TextHelper.
def word_wrap(text, line_width = 80)
  text.split("\n").collect do |line|
    line.length > line_width ?
      line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip :
      line
  end * "\n"
end

desc 'Alias for build:gem'
task :build => 'build:gem'

# Build related tasks.
namespace :build do
  # Ensure that the manifest is consulted when building the gem.  Any
  # generated/compiled files should be available at that time.
  task :gem => :check_manifest

  # Create the gem and package tasks.
  Gem::PackageTask.new(SPEC).define

  desc 'Verify the manifest'
  task :check_manifest do
    manifest_files = (SPEC.files + SPEC.test_files).sort.uniq
    pkg_files = PKG_FILES.sort.uniq
    if manifest_files != pkg_files then
      common_files = manifest_files & pkg_files
      manifest_files -= common_files
      pkg_files -= common_files
      message = ["The manifest does not match the automatic file list."]
      unless manifest_files.empty? then
        message << "  Extraneous files:\n    " + manifest_files.join("\n    ")
      end
      unless pkg_files.empty?
        message << "  Missing files:\n    " + pkg_files.join("\n    ")
      end
      raise message.join("\n")
    end
  end

  # Creates the README.md file from a template, the license file and the gemspec
  # contents.
  file 'README.md' => ['README.md.erb', 'LICENSE', GEMSPEC] do
    spec = SPEC
    File.open('README.md', 'w') do |readme|
      readme.write(
        ERB.new(File.read('README.md.erb'), nil, '-').result(binding)
      )
    end
  end
end

# Ensure that the clobber task also clobbers package files.
task :clobber => 'build:clobber_package'

# Create the documentation task.
YARD::Rake::YardocTask.new
# Ensure that the README file is (re)generated first.
task :yard => 'README.md'

# Gem related tasks.
namespace :gem do
  desc 'Alias for build:gem'
  task :build => 'build:gem'

  desc 'Publish the gemfile'
  task :publish => ['version:check', :test, 'repo:tag', :build] do
    sh "gem push pkg/#{SPEC.name}-#{SPEC.version}*.gem"
  end
end

Rake::TestTask.new do |t|
  t.pattern = 'spec/**/*_spec.rb'
end

# Version string management tasks.
namespace :version do
  desc 'Set the version for the project to a specified version'
  task :set do
    set_version(get_version_argument)
  end

  desc 'Set the version for the project back to 0.0.0'
  task :reset do
    set_version('0.0.0')
  end

  desc 'Check that all version strings are correctly set'
  task :check => ['version:check:spec', 'version:check:version_rb', 'version:check:news']

  namespace :check do
    desc 'Check that the version in the gemspec is correctly set'
    task :spec do
      version = get_version_argument
      if version != SPEC.version
        raise "The given version `#{version}' does not match the gemspec version `#{SPEC.version}'"
      end
    end

    desc 'Check that the version in the version.rb file is correctly set'
    task :version_rb do
      version = get_version_argument
      begin
        load VERSION_RB
        internal_version = Gem::Version.create(eval(VERSION_REF))
        if version != internal_version
          raise "The given version `#{version}' does not match the version.rb version `#{internal_version}'"
        end
      rescue ArgumentError
        raise "Invalid version specified in `#{VERSION_RB}'"
      end
    end

    desc 'Check that the NEWS.md file mentions the version'
    task :news do
      version = get_version_argument
      begin
        File.open('NEWS.md') do |news|
          unless news.each_line.any? {|l| l =~ /^## v#{Regexp.escape(version.to_s)} /}
            raise "The NEWS.md file does not mention version `#{version}'"
          end
        end
      rescue Errno::ENOENT
        raise 'No NEWS.md file found'
      end
    end
  end
end

# Repository and workspace management tasks.
namespace :repo do
  desc 'Tag the current HEAD with the version string'
  task :tag => :check_workspace do
    version = get_version_argument
    sh "git tag -s -m 'Release v#{version}' v#{version}"
  end

  desc 'Ensure the workspace is fully committed and clean'
  task :check_workspace => ['README.md'] do
    unless `git status --untracked-files=all --porcelain`.empty?
      raise 'Workspace has been modified.  Commit pending changes and try again.'
    end
  end
end