Class: Buildar

Inherits:
Rake::TaskLib
  • Object
show all
Defined in:
lib/buildar.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBuildar

Returns a new instance of Buildar.



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/buildar.rb', line 35

def initialize
  @gemspec_file = nil
  @version_file = nil
  @use_git = false
  @pkg_dir = 'pkg'
  @ns = ''

  if block_given?
    yield self
    define
  end
end

Instance Attribute Details

#gemspec_fileObject

Returns the value of attribute gemspec_file.



33
34
35
# File 'lib/buildar.rb', line 33

def gemspec_file
  @gemspec_file
end

#nsObject

Returns the value of attribute ns.



33
34
35
# File 'lib/buildar.rb', line 33

def ns
  @ns
end

#pkg_dirObject

Returns the value of attribute pkg_dir.



33
34
35
# File 'lib/buildar.rb', line 33

def pkg_dir
  @pkg_dir
end

#use_gitObject

Returns the value of attribute use_git.



33
34
35
# File 'lib/buildar.rb', line 33

def use_git
  @use_git
end

#version_fileObject

Returns the value of attribute version_file.



33
34
35
# File 'lib/buildar.rb', line 33

def version_file
  @version_file
end

Class Method Details

.bump(position, version) ⇒ Object

e.g. bump(:minor, ‘1.2.3’) #=> ‘1.3.0’ only works for versions consisting of integers delimited by periods (dots)



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/buildar.rb', line 13

def self.bump(position, version)
  pos = [:major, :minor, :patch, :build].index(position) || position
  places = version.split('.')
  if places.length <= pos and pos <= places.length + 3
    # add zeroes to places up to pos
    # allows bump(:build, '0') #=> '0.0.0.1'
    places.length.upto(pos) { |i| places[i] = 0 }
  end
  raise "bad position: #{pos} (for version #{version})" unless places[pos]
  places.map.with_index { |place, i|
    if i < pos
      place
    elsif i == pos
      place.to_i + 1
    else
      0
    end
  }.join('.')
end

.versionObject



6
7
8
# File 'lib/buildar.rb', line 6

def self.version
  File.read(File.join(__dir__, '..', 'VERSION')).chomp
end

Instance Method Details

#defineObject



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
# File 'lib/buildar.rb', line 72

def define
  directory @pkg_dir
  CLOBBER.include @pkg_dir

  if @ns and !@ns.empty?
    namespace(@ns) { define_tasks }
  else
    define_tasks
  end

  #
  # tasks to be kept out of @ns namespace
  #

  desc "config check"
  task buildar: :valid_gemspec do
    spacer = " " * 14
    gemspec = self.gemspec
    puts
    puts "     Project: #{gemspec.name} #{gemspec.version}"
    puts "Gemspec file: #{@gemspec_file}" if @gemspec_file
    puts <<EOF
Version file: #{@version_file}
   Use git: #{@use_git}
 Package dir: #{@pkg_dir}
     Files: #{gemspec.files.join("\n#{spacer}")}
Built gems: #{Dir[@pkg_dir +  '/*.gem'].join("\n#{spacer}")}
# using Buildar #{Buildar.version}
EOF
    puts
  end

  if @version_file
    namespace :bump do
      # tasks :bump_major, :bump_minor, :bump_patch, :bump_build
      # commit the version file if @use_git
      #
      [:major, :minor, :patch, :build].each { |v|
        desc "increment the #{v} number in #{@version_file}"
        task v do
          old_version = self.read_version
          new_version = self.class.bump(v, old_version)

          puts "bumping #{old_version} to #{new_version}"
          self.write_version new_version

          if @use_git and v != :build
            msg = "Buildar version:bump_#{v} to #{new_version}"
            sh "git commit #{@version_file} -m #{msg.inspect}"
          end
        end
      }
    end
  end
end

#define_tasksObject



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
# File 'lib/buildar.rb', line 128

def define_tasks
  desc "invoke :test and :bump_build conditionally"
  task pre_build: @pkg_dir do
    Rake::Task[:test].invoke if Rake::Task.task_defined? :test
    Rake::Task['bump:build'].invoke if @version_file
  end

  # can't make this a file task, because the version could be bumped
  # as a dependency, changing the target file
  #
  desc "build a .gem in #{@pkg_dir}/ using `gem build`"
  task build: :pre_build do
    if @gemspec_file
      sh "gem build #{@gemspec_file}"
      mv File.basename(self.gem_file), self.gem_file
    else
      Rake::Task[:gem_package].invoke
    end
  end

  # roughly equivalent to `gem build self.gemspec`
  # operates with a hard or soft gemspec
  #
  desc "build a .gem in #{@pkg_dir}/ using Gem::PackageTask"
  task gem_package: :pre_build do
    # definine the task at runtime, rather than requiretime
    # so that the gemspec will reflect any version bumping since requiretime
    require 'rubygems/package_task'
    Gem::PackageTask.new(self.gemspec).define
    Rake::Task["package"].invoke
  end

  # desc "used internally; make sure we have .gem for the current version"
  task :built do
    Rake::Task[:build].invoke unless File.exist? self.gem_file
  end

  desc "publish the current version to rubygems.org"
  task publish: :built do
    sh "gem push #{self.gem_file}"
  end

  desc "build, publish" + (@use_git ? ", tag " : '')
  task release: [:build, :publish] do
    Rake::Task[:tag].invoke if @use_git
  end

  desc "install the current version"
  task install: :built do
    sh "gem install #{self.gem_file}"
  end

  desc "build a new version and install"
  task install_new: [:build, :install]

  desc "display current version"
  task version: :valid_gemspec do
    puts self.gemspec.version
  end

  task :valid_gemspec do
    unless self.gemspec
      msg = "gemspec required"
      msg += "; checked #{self.gemspec_file}" if self.gemspec_file
      raise msg
    end
  end

  #
  # Optional tasks
  #

  if @version_file
    namespace :release do
      [:major, :minor, :patch].each { |v|
        desc "increment the #{v} number and release"
        task v => ["bump:#{v}", :release]
      }
    end
  end

  if @use_git
    desc "annotated git tag with version and message"
    task tag: :message do
      Rake::Task[:test].invoke if Rake::Task.task_defined? :test
      tagname = "v#{self.gemspec.version}"
      message = ENV['message'] || "auto-tagged #{tagname} by Buildar"
      sh "git tag -a #{tagname.inspect} -m #{message.inspect}"
      sh "git push origin --tags"
    end

    # right now only :tag depends on this, but maybe others in the future?
    # desc "used internally; make sure ENV['message'] is populated"
    task :message do
      if !ENV['message'] or ENV['message'].empty?
        print "This task requires a message:\n> "
        ENV['message'] = $stdin.gets.chomp
      end
    end
  end
end

#gem_fileObject



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

def gem_file
  File.join(@pkg_dir, "#{gemspec.name}-#{gemspec.version}.gem")
end

#gemspecObject



48
49
50
51
52
53
54
55
56
# File 'lib/buildar.rb', line 48

def gemspec
  if @gemspec_file
    Gem::Specification.load @gemspec_file
  else
    @gemspec ||= Gem::Specification.new
    @gemspec.version = self.read_version if @version_file
    @gemspec
  end
end

#read_versionObject



58
59
60
61
# File 'lib/buildar.rb', line 58

def read_version
  raise "no @version_file" unless @version_file
  File.read(@version_file).chomp
end

#write_version(new_version) ⇒ Object



63
64
65
66
# File 'lib/buildar.rb', line 63

def write_version(new_version)
  raise "no @version_file" unless @version_file
  File.open(@version_file, 'w') { |f| f.write(new_version) }
end