script to retroactively add commitids to past openbsd commits
at master 166 lines 5.0 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 28require "date" 29 30class RCSRevision 31 attr_accessor :rcsfile, :version, :date, :author, :state, :lines, :commitid, 32 :log, :branch, :vendor_branches 33 34 def self.previous_of(ver) 35 nums = ver.split(".").map{|z| z.to_i } 36 37 if nums.last == 1 38 # 1.3.2.1 -> 1.3 39 2.times { nums.pop } 40 else 41 # 1.3.2.2 -> 1.3.2.1 42 nums[nums.count - 1] -= 1 43 end 44 45 outnum = nums.join(".") 46 if outnum == "" 47 return "0" 48 else 49 return outnum 50 end 51 end 52 53 # 1.1.0.2 -> 1.1.2.1 54 def self.first_branch_version_of(ver) 55 nums = ver.split(".").map{|z| z.to_i } 56 57 if nums[nums.length - 2] != 0 58 return ver 59 end 60 61 last = nums.pop 62 nums.pop 63 nums.push last 64 nums.push 1 65 66 return nums.join(".") 67 end 68 69 def self.is_vendor_branch?(ver) 70 !!ver.match(/^1\.1\.1\..*/) 71 end 72 73 def self.is_trunk?(ver) 74 ver.split(".").count == 2 75 end 76 77 # str: "revision 1.7\ndate: 1996/12/14 12:17:33; author: mickey; state: Exp; lines: +3 -3;\n-Wall'ing." 78 def initialize(rcsfile, str) 79 @rcsfile = rcsfile 80 @version = nil 81 @date = 0 82 @author = nil 83 @state = nil 84 @lines = nil 85 @commitid = nil 86 @log = nil 87 @branch = nil 88 @vendor_branches = [] 89 90 lines = str.gsub(/^\s*/, "").split("\n") 91 # -> [ 92 # "revision 1.7", 93 # "date: 1996/12/14 12:17:33; author: mickey; state: Exp; lines: +3 -3;", 94 # "-Wall'ing." 95 # ] 96 97 # strip out possible branches line in log 98 if lines[2].to_s.match(/^branches:\s+([\d\.]+)/) 99 lines.delete_at(2) 100 end 101 102 @version = lines.first.scan(/^revision ([\d\.]+)($|\tlocked by)/).first. 103 first.encode("UTF-8") 104 # -> "1.7" 105 106 # date/author/state/lines/commitid line 107 lines[1].split(/;[ \t]*/).each do |piece| 108 kv = piece.split(": ") 109 self.send(kv[0] + "=", kv[1].encode("UTF-8")) 110 end 111 # -> @date = "1996/12/14 12:17:33", @author = "mickey", ... 112 113 if m = @date.match(/^\d\d\d\d\/\d\d\/\d\d \d\d:\d\d:\d\d$/) 114 @date = DateTime.parse(@date).strftime("%s").to_i 115 else 116 raise "invalid date #{@date}" 117 end 118 # -> @date = 850565853 119 120 @log = lines[2, lines.count].join("\n").encode("UTF-8", 121 :invalid => :replace, :undef => :replace, :replace => "?") 122 123 if @version.match(/^\d+\.\d+$/) 124 # no branch 125 elsif @version.match(/^1\.1\.1\./) || 126 (@version == "1.1.2.1" && @branch == nil) 127 # vendor 128 @rcsfile.symbols.each do |k,v| 129 if v == "1.1.1" 130 @vendor_branches.push k 131 end 132 end 133 elsif m = @version.match(/^(\d+)\.(\d+)\.(\d+)\.\d+$/) 134 # 1.2.2.3 -> 1.2.0.2 135 sym = [ m[1], m[2], "0", m[3] ].join(".") 136 @rcsfile.symbols.each do |s,v| 137 if v == sym 138 if @branch 139 raise "version #{@version} matched two symbols (#{@branch}, #{s})" 140 end 141 142 @branch = s 143 end 144 end 145 146 if !@branch && @rcsfile.symbols.values.include?(@version) 147 # if there's an exact match, this was probably just an import done with 148 # a vendor branch id (import -b) 149 elsif !@branch 150 # branch was deleted, but we don't want this appearing on HEAD, so call 151 # it something 152 @branch = "_branchless_#{@version.gsub(".", "_")}" 153 end 154 155 if @branch && @rcsfile.symbols[@branch] && 156 @rcsfile.symbols[@branch].match(/^1\.1\.0\.\d+$/) 157 # this is also a vendor branch 158 if !@vendor_branches.include?(@branch) 159 @vendor_branches.push @branch 160 end 161 end 162 else 163 raise "TODO: handle version #{@version}" 164 end 165 end 166end