script to retroactively add commitids to past openbsd commits
at master 219 lines 6.5 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 "shellwords" 29 30class Outputter 31 def initialize(scanner) 32 @scanner = scanner 33 end 34 35 def changelog(domain, fh) 36 puts "writing changelog to #{fh.path}" 37 38 last = {} 39 files = [] 40 41 printlog = Proc.new { 42 fh.puts "Changes by: #{last["author"]}@#{domain} " << 43 Time.at(last["date"].to_i).strftime("%Y/%m/%d %H:%M:%S") 44 if last["commitid"].to_s != "" 45 fh.puts "Commitid: #{last["commitid"]}" 46 end 47 if last["branch"].to_s != "" 48 fh.puts "Branch: #{last["branch"]}" 49 end 50 fh.puts "" 51 fh.puts "Modified files:" 52 53 # group files by directory 54 dirs = {} 55 files.each do |f| 56 dir = f.split("/") 57 file = dir.pop.gsub(/,v$/, "") 58 59 if dir.length == 0 60 dir = "." 61 else 62 dir = dir.join("/") 63 end 64 65 dirs[dir] ||= [] 66 if !dirs[dir].include?(file) 67 dirs[dir].push file 68 end 69 end 70 71 # print padded and wrapped directory and file lines 72 dirs.each do |dir,fs| 73 dl = " #{dir}" 74 if dir.length < 15 75 (15 - dir.length).times do 76 dl += " " 77 end 78 end 79 dl += ":" 80 fl = (72 - dl.length) 81 cl = dl 82 (fs.count + 1).times do 83 if (f = fs.shift) 84 if cl.length + f.length > 72 85 fh.puts cl.gsub(/[ ]{8}/, "\t") 86 cl = " " * dl.length 87 end 88 89 cl += " " + f 90 else 91 fh.puts cl.gsub(/[ ]{8}/, "\t") 92 break 93 end 94 end 95 end 96 97 fh.puts "" 98 fh.puts "Log message:" 99 fh.puts last["log"] 100 fh.puts "" 101 fh.puts "" 102 } 103 104 @scanner.db.execute("SELECT 105 changesets.csorder, changesets.date, changesets.author, 106 changesets.commitid, changesets.log, files.file, revisions.branch 107 FROM changesets 108 LEFT OUTER JOIN revisions ON revisions.changeset_id = changesets.id 109 LEFT OUTER JOIN files ON revisions.file_id = files.id 110 ORDER BY changesets.csorder, files.file") do |csfile| 111 if csfile["csorder"] == last["csorder"] 112 files.push csfile["file"] 113 else 114 if files.any? 115 printlog.call 116 end 117 files = [ csfile["file"] ] 118 last = csfile 119 end 120 end 121 122 if last.any? 123 printlog.call 124 end 125 end 126 127 def history(fh) 128 puts "writing history to #{fh.path}" 129 130 last = {} 131 files = [] 132 133 printlog = Proc.new { 134 fh.puts [ 135 Time.at(last["date"].to_i).strftime("%Y/%m/%d %H:%M:%S"), 136 last["author"], 137 last["commitid"], 138 last["log"].to_s.split("\n").first, 139 files.map{|f| f.gsub(/,v$/, "") }.join(", "), 140 ].join("\t") 141 } 142 143 @scanner.db.execute("SELECT 144 changesets.date, changesets.author, changesets.commitid, changesets.log, 145 files.file 146 FROM changesets 147 LEFT OUTER JOIN revisions ON revisions.changeset_id = changesets.id 148 LEFT OUTER JOIN files ON revisions.file_id = files.id 149 ORDER BY changesets.date, files.file") do |csfile| 150 if csfile["commitid"] == last["commitid"] 151 files.push csfile["file"] 152 else 153 if files.any? 154 printlog.call 155 end 156 files = [ csfile["file"] ] 157 last = csfile 158 end 159 end 160 161 if last.any? 162 printlog.call 163 end 164 end 165 166 def dup_script(script, tree) 167 puts "writing update script to #{script.path}" 168 169 script.puts "#!/bin/sh -x" 170 script.puts "if [ \"$TMPCVSDIR\" = \"\" ]; then echo 'set $TMPCVSDIR'; " + 171 "exit 1; fi" 172 script.puts "if [ \"$CVSROOT\" = \"\" ]; then echo 'set $CVSROOT'; " + 173 "exit 1; fi" 174 script.puts "" 175 script.puts "set -e" 176 script.puts "" 177 script.puts "cd $TMPCVSDIR" 178 script.puts "cvs -Q -d $CVSROOT co -r1.1 #{tree}" 179 script.puts "" 180 181 dead11s = {} 182 @scanner.db.execute("SELECT 183 file, first_undead_version 184 FROM files 185 WHERE first_undead_version NOT LIKE '1.1'") do |rev| 186 dead11s[rev["file"]] = rev["first_undead_version"] 187 end 188 189 dead11s.each do |file,rev| 190 confile = file.gsub(/,v$/, "") 191 192 script.puts "cvs -Q -d $CVSROOT co -r#{rev} " + 193 "#{tree}/#{Shellwords.escape(confile)}" 194 end 195 196 script.puts "" 197 script.puts "cd $TMPCVSDIR/#{tree}" 198 199 csid = nil 200 @scanner.db.execute("SELECT 201 files.file, changesets.commitid, changesets.author, changesets.date, 202 revisions.version, changesets.branch 203 FROM revisions 204 LEFT OUTER JOIN files ON files.id = file_id 205 LEFT OUTER JOIN changesets ON revisions.changeset_id = changesets.id 206 ORDER BY changesets.csorder ASC, files.file ASC") do |rev| 207 if csid == nil || rev["commitid"] != csid 208 script.puts "# #{Time.at(rev["date"])} by " + rev["author"] + 209 (rev["branch"].to_s == "" ? "" : " (branch #{rev["branch"]})") 210 csid = rev["commitid"] 211 script.puts "COMMITID=\"#{Shellwords.escape(rev["commitid"])}\"" 212 end 213 214 fi = rev["file"].gsub(/,v$/, "") 215 script.puts "cvs admin -C #{rev["version"]}:${COMMITID} " + 216 "#{Shellwords.escape(fi)}" 217 end 218 end 219end