Class: VCLog::Repo
- Inherits:
-
Object
- Object
- VCLog::Repo
- Defined in:
- lib/vclog/repo.rb
Overview
Encapsulate representaiton of the repository.
Constant Summary collapse
- ROOT_GLOB =
File glob used to find project root directory.
'{.ruby,.map/,.git/,.hg/,_darcs/,.svn/}'
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Options hash.
-
#root ⇒ Object
readonly
Project 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.
-
#config ⇒ Object
Configuration.
-
#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.
-
#method_missing(s, *a, &b) ⇒ Object
Delegate missing methods to SCM adapter.
-
#new_tag_message(label, tag) ⇒ Object
private
Returns a String.
-
#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 45 46 |
# File 'lib/vclog/repo.rb', line 35 def initialize(root, ={}) [:root] = root if root @config = Config.new() @options = vcs_type = @config.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.
267 268 269 270 271 272 273 |
# File 'lib/vclog/repo.rb', line 267 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 @options end |
#root ⇒ Object (readonly)
Project 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.
51 52 53 |
# File 'lib/vclog/repo.rb', line 51 def adapter @adapter end |
#apply_heuristics(changes) ⇒ Object
Apply heuristics to changes.
128 129 130 131 132 |
# File 'lib/vclog/repo.rb', line 128 def apply_heuristics(changes) changes.each do |change| change.apply_heuristics(heuristics) end end |
#ask_yn(message) ⇒ Object (private)
Ask yes/no question.
280 281 282 283 284 285 286 287 |
# File 'lib/vclog/repo.rb', line 280 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.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/vclog/repo.rb', line 95 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.
214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/vclog/repo.rb', line 214 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.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/vclog/repo.rb', line 229 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.
121 122 123 |
# File 'lib/vclog/repo.rb', line 121 def change_points @change_points ||= apply_heuristics(adapter.change_points) end |
#changes ⇒ Object
List of all changes.
114 115 116 |
# File 'lib/vclog/repo.rb', line 114 def changes @changes ||= apply_heuristics(adapter.changes) end |
#config ⇒ Object
Configuration.
58 59 60 |
# File 'lib/vclog/repo.rb', line 58 def config @config end |
#force? ⇒ Boolean
Check force option.
79 80 81 |
# File 'lib/vclog/repo.rb', line 79 def force? config.force? end |
#heuristics ⇒ Object
Load heuristics script.
72 73 74 |
# File 'lib/vclog/repo.rb', line 72 def heuristics config.heuristics end |
#history_file ⇒ Object
Access to Repo’s HISTORY file.
86 87 88 |
# File 'lib/vclog/repo.rb', line 86 def history_file @history_file ||= HistoryFile.new([:history_file] || root) end |
#new_tag_message(label, tag) ⇒ Object (private)
Returns a String.
292 293 294 |
# File 'lib/vclog/repo.rb', line 292 def (label, tag) "#{label} / #{tag.date.strftime('%Y-%m-%d')}\n#{tag.}" 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.
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 |
# File 'lib/vclog/repo.rb', line 146 def releases(changes) rel = [] = self..dup #ver = repo.bump(version) name = config.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 |