script to retroactively add commitids to past openbsd commits
at master 78 lines 2.9 kB view raw
1# 2# Copyright (c) 2014, 2016 joshua stein <jcs@jcs.org> 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions 6# are met: 7# 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. The name of the author may not be used to endorse or promote products 14# derived from this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26# 27 28class RCSFile 29 attr_accessor :file, :revisions, :symbols, :first_undead_version 30 31 RCSEND = "==================OPENBSD_COMMITID_RCS_END==================" 32 REVSEP = "------------------OPENBSD_COMMITID_REV_SEP------------------" 33 34 def initialize(file) 35 @file = file 36 @revisions = {} 37 @symbols = {} 38 39 blocks = [] 40 IO.popen([ "rlog", "-E#{RCSEND}", "-S#{REVSEP}", file ]) do |rlog| 41 blocks = rlog.read.force_encoding("iso-8859-1"). 42 split(/^(#{REVSEP}|#{RCSEND})\n?$/). 43 reject{|b| b == RCSEND || b == REVSEP } 44 end 45 46 if !blocks.first.match(/^RCS file/) 47 raise "file #{file} didn't come out of rlog properly" 48 end 49 50 insymbols = false 51 blocks.shift.split("\n").each do |l| 52 if l.match(/^symbolic names:/) 53 insymbols = true 54 elsif insymbols && (m = l.match(/^\t(.+): ([\d\.]+)$/)) 55 @symbols[m[1].encode("UTF-8")] = m[2].encode("UTF-8") 56 else 57 insymbols = false 58 end 59 end 60 61 blocks.each do |block| 62 rev = RCSRevision.new(self, block) 63 if @revisions[rev.version] 64 raise "duplicate revision #{rev.version} in #{file}" 65 end 66 @revisions[rev.version] = rev 67 end 68 69 @first_undead_version = @revisions.values. 70 # this has nothing to do with Gem, but it has a version comparator 71 sort{|a,b| Gem::Version.new(a.version) <=> Gem::Version.new(b.version) }. 72 select{|r| r.state != "dead" }.first.version 73 end 74 75 def to_s 76 "RCSFile: #{@file}" 77 end 78end