Class: VCLog::Repo
- Inherits:
-
Object
- Object
- VCLog::Repo
- Defined in:
- lib/vclog/repo.rb
Constant Summary collapse
- ROOT_GLOB =
File glob used to find project root directory.
'{.git/,.hg/,_darcs/,.svn/}'
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Options hash.
-
#root ⇒ Object
readonly
Project’s root directory.
Instance Method Summary collapse
-
#adapter ⇒ Object
Returns instance of an Adapter subclass.
-
#apply_heuristics(changes) ⇒ Object
Apply heuristics to changes.
-
#ask_yn(message) ⇒ Object
private
Ask yes/no question.
-
#autotag(prefix = nil) ⇒ Object
Read history file and make a commit tag for any release not already tagged.
-
#bump ⇒ String
Make an educated guess as to the next version number based on changes made since previous release.
-
#bump_part(part = nil) ⇒ Object
Provides a bumped version number.
-
#change_points ⇒ Object
List of all change points.
-
#changes ⇒ Object
List of all changes.
-
#force? ⇒ Boolean
Check force option.
-
#heuristics ⇒ Object
Load heuristics script.
-
#history_file ⇒ Object
Access to Repo’s HISTORY file.
-
#initialize(root, options = {}) ⇒ Repo
constructor
Setup new Repo instance.
-
#lookup_root ⇒ Object
Find project root.
-
#method_missing(s, *a, &b) ⇒ Object
Delegate missing methods to SCM adapter.
-
#new_tag_message(label, tag) ⇒ Object
private
Returns a String.
- #read_vcs_type ⇒ Object
-
#releases(changes) ⇒ Array<Release>
Collect releases for the given set of
changes. -
#report(options) ⇒ Object
Print a report with given options.
Constructor Details
#initialize(root, options = {}) ⇒ Repo
Setup new Repo instance.
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/vclog/repo.rb', line 35 def initialize(root, ={}) @root = root || lookup_root = vcs_type = read_vcs_type raise ArgumentError, "Not a recognized version control system." unless vcs_type @adapter = Adapters.const_get(vcs_type.capitalize).new(self) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(s, *a, &b) ⇒ Object
Delegate missing methods to SCM adapter.
287 288 289 290 291 292 293 |
# File 'lib/vclog/repo.rb', line 287 def method_missing(s, *a, &b) if adapter.respond_to?(s) adapter.send(s, *a, &b) else super(s,*a,&b) end end |
Instance Attribute Details
#options ⇒ Object (readonly)
Options hash.
30 31 32 |
# File 'lib/vclog/repo.rb', line 30 def end |
#root ⇒ Object (readonly)
Project’s root directory.
25 26 27 |
# File 'lib/vclog/repo.rb', line 25 def root @root end |
Instance Method Details
#adapter ⇒ Object
Returns instance of an Adapter subclass.
49 50 51 |
# File 'lib/vclog/repo.rb', line 49 def adapter @adapter end |
#apply_heuristics(changes) ⇒ Object
Apply heuristics to changes.
148 149 150 151 152 |
# File 'lib/vclog/repo.rb', line 148 def apply_heuristics(changes) changes.each do |change| change.apply_heuristics(heuristics) end end |
#ask_yn(message) ⇒ Object (private)
Ask yes/no question.
300 301 302 303 304 305 306 307 |
# File 'lib/vclog/repo.rb', line 300 def ask_yn() case ask() when 'y', 'Y', 'yes' true else false end end |
#autotag(prefix = nil) ⇒ Object
Read history file and make a commit tag for any release not already tagged. Unless the force option is set the user will be prompted for each new tag.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/vclog/repo.rb', line 115 def autotag(prefix=nil) history_file..each do |tag| label = "#{prefix}#{tag.name}" if not adapter.tag?(label) chg = adapter.change_by_date(tag.date) if chg if force? or ask_yn((label, tag) + "\nCreate tag? [yN] ") adapter.tag(chg.rev, label, tag.date, tag.) end else puts "No commit found for #{label} #{tag.date.strftime('%Y-%m-%d')}." end end end end |
#bump ⇒ String
Allow configuration of version bump thresholds
Make an educated guess as to the next version number based on changes made since previous release.
234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/vclog/repo.rb', line 234 def bump last_release = releases(changes).first max = last_release.changes.map{ |c| c.level }.max if max > 1 bump_part('major') elsif max >= 0 bump_part('minor') else bump_part('patch') end end |
#bump_part(part = nil) ⇒ Object
Provides a bumped version number.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/vclog/repo.rb', line 249 def bump_part(part=nil) raise "bad version part - #{part}" unless ['major', 'minor', 'patch', 'build', ''].include?(part.to_s) if .last v = [-1].name # TODO: ensure the latest version v = [-2].name if v == 'HEAD' else v = '0.0.0' end v = v.split(/\W/) # TODO: preserve split chars case part.to_s when 'major' v[0] = v[0].succ (1..(v.size-1)).each{ |i| v[i] = '0' } v.join('.') when 'minor' v[1] = '0' unless v[1] v[1] = v[1].succ (2..(v.size-1)).each{ |i| v[i] = '0' } v.join('.') when 'patch' v[1] = '0' unless v[1] v[2] = '0' unless v[2] v[2] = v[2].succ (3..(v.size-1)).each{ |i| v[i] = '0' } v.join('.') else v[-1] = '0' unless v[-1] v[-1] = v[-1].succ v.join('.') end end |
#change_points ⇒ Object
List of all change points.
141 142 143 |
# File 'lib/vclog/repo.rb', line 141 def change_points @change_points ||= apply_heuristics(adapter.change_points) end |
#changes ⇒ Object
List of all changes.
134 135 136 |
# File 'lib/vclog/repo.rb', line 134 def changes @changes ||= apply_heuristics(adapter.changes) end |
#force? ⇒ Boolean
Check force option.
56 57 58 |
# File 'lib/vclog/repo.rb', line 56 def force? [:force] end |
#heuristics ⇒ Object
Load heuristics script.
99 100 101 |
# File 'lib/vclog/repo.rb', line 99 def heuristics @heuristics ||= Heuristics.new(&Confection[:vclog]) end |
#history_file ⇒ Object
Access to Repo’s HISTORY file.
106 107 108 |
# File 'lib/vclog/repo.rb', line 106 def history_file @history_file ||= HistoryFile.new([:history_file] || root) end |
#lookup_root ⇒ Object
Find project root. This searches up from the current working directory for a Confection configuration file or source control manager directory.
.co
.git/
.hg/
.svn/
_darcs/
If all else fails the current directory is returned.
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/vclog/repo.rb', line 84 def lookup_root root = nil Dir.ascend(Dir.pwd) do |path| check = Dir[ROOT_GLOB].first if check root = path break end end root || Dir.pwd end |
#new_tag_message(label, tag) ⇒ Object (private)
Returns a String.
312 313 314 |
# File 'lib/vclog/repo.rb', line 312 def (label, tag) "#{label} / #{tag.date.strftime('%Y-%m-%d')}\n#{tag.message}" end |
#read_vcs_type ⇒ Object
63 64 65 66 67 68 69 |
# File 'lib/vclog/repo.rb', line 63 def read_vcs_type dir = nil Dir.chdir(root) do dir = Dir.glob("{.git,.hg,.svn,_darcs}").first end dir[1..-1] if dir end |
#releases(changes) ⇒ Array<Release>
Collect releases for the given set of changes.
Releases are groups of changes segregated by tags. The release version, release date and release note are defined by hard tag commits.
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 |
# File 'lib/vclog/repo.rb', line 166 def releases(changes) rel = [] = self..dup #ver = repo.bump(version) name = [:version] || 'HEAD' user = adapter.user date = ::Time.now + (3600 * 24) # one day ahead change = Change.new(:id=>'HEAD', :date=>date, :who=>user) << Tag.new(:name=>name, :date=>date, :who=>user, :msg=>"Current Development", :commit=>change) # TODO: Do we need to add a Time.now tag? # add current verion to release list (if given) #previous_version = tags[0].name #if current_version < previous_version # TODO: need to use natural comparision # raise ArgumentError, "Release version is less than previous version (#{previous_version})." #end # sort by release date = .sort{ |a,b| a.date <=> b.date } # organize into deltas delta = [] last = nil .each do |tag| delta << [tag, [last, tag.commit.date]] last = tag.commit.date end # gather changes for each delta delta.each do |tag, (started, ended)| if started set = changes.select{ |c| c.date >= started && c.date < ended } #gt_vers, gt_date = gt.name, gt.date #lt_vers, lt_date = lt.name, lt.date #gt_date = Time.parse(gt_date) unless Time===gt_date #lt_date = Time.parse(lt_date) unless Time===lt_date #log = changelog.after(gt).before(lt) else #lt_vers, lt_date = lt.name, lt.date #lt_date = Time.parse(lt_date) unless Time===lt_date #log = changelog.before(lt_date) set = changes.select{ |c| c.date < ended } end rel << Release.new(tag, set) end rel.sort end |
#report(options) ⇒ Object
Print a report with given options.
221 222 223 224 |
# File 'lib/vclog/repo.rb', line 221 def report() report = Report.new(self, ) report.print end |