113481Sgiacomo.travaglini@arm.com#!/usr/bin/env python 213481Sgiacomo.travaglini@arm.com# 313481Sgiacomo.travaglini@arm.com# Copyright 2013 Google Inc. All Rights Reserved. 413481Sgiacomo.travaglini@arm.com# 513481Sgiacomo.travaglini@arm.com# Redistribution and use in source and binary forms, with or without 613481Sgiacomo.travaglini@arm.com# modification, are permitted provided that the following conditions are 713481Sgiacomo.travaglini@arm.com# met: 813481Sgiacomo.travaglini@arm.com# 913481Sgiacomo.travaglini@arm.com# * Redistributions of source code must retain the above copyright 1013481Sgiacomo.travaglini@arm.com# notice, this list of conditions and the following disclaimer. 1113481Sgiacomo.travaglini@arm.com# * Redistributions in binary form must reproduce the above 1213481Sgiacomo.travaglini@arm.com# copyright notice, this list of conditions and the following disclaimer 1313481Sgiacomo.travaglini@arm.com# in the documentation and/or other materials provided with the 1413481Sgiacomo.travaglini@arm.com# distribution. 1513481Sgiacomo.travaglini@arm.com# * Neither the name of Google Inc. nor the names of its 1613481Sgiacomo.travaglini@arm.com# contributors may be used to endorse or promote products derived from 1713481Sgiacomo.travaglini@arm.com# this software without specific prior written permission. 1813481Sgiacomo.travaglini@arm.com# 1913481Sgiacomo.travaglini@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2013481Sgiacomo.travaglini@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2113481Sgiacomo.travaglini@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2213481Sgiacomo.travaglini@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2313481Sgiacomo.travaglini@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2413481Sgiacomo.travaglini@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2513481Sgiacomo.travaglini@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2613481Sgiacomo.travaglini@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2713481Sgiacomo.travaglini@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2813481Sgiacomo.travaglini@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2913481Sgiacomo.travaglini@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3013481Sgiacomo.travaglini@arm.com 3113481Sgiacomo.travaglini@arm.com"""Script for branching Google Test/Mock wiki pages for a new version. 3213481Sgiacomo.travaglini@arm.com 3313481Sgiacomo.travaglini@arm.comSYNOPSIS 3413481Sgiacomo.travaglini@arm.com release_docs.py NEW_RELEASE_VERSION 3513481Sgiacomo.travaglini@arm.com 3613481Sgiacomo.travaglini@arm.com Google Test and Google Mock's external user documentation is in 3713481Sgiacomo.travaglini@arm.com interlinked wiki files. When we release a new version of 3813481Sgiacomo.travaglini@arm.com Google Test or Google Mock, we need to branch the wiki files 3913481Sgiacomo.travaglini@arm.com such that users of a specific version of Google Test/Mock can 4013481Sgiacomo.travaglini@arm.com look up documenation relevant for that version. This script 4113481Sgiacomo.travaglini@arm.com automates that process by: 4213481Sgiacomo.travaglini@arm.com 4313481Sgiacomo.travaglini@arm.com - branching the current wiki pages (which document the 4413481Sgiacomo.travaglini@arm.com behavior of the SVN trunk head) to pages for the specified 4513481Sgiacomo.travaglini@arm.com version (e.g. branching FAQ.wiki to V2_6_FAQ.wiki when 4613481Sgiacomo.travaglini@arm.com NEW_RELEASE_VERSION is 2.6); 4713481Sgiacomo.travaglini@arm.com - updating the links in the branched files to point to the branched 4813481Sgiacomo.travaglini@arm.com version (e.g. a link in V2_6_FAQ.wiki that pointed to 4913481Sgiacomo.travaglini@arm.com Primer.wiki#Anchor will now point to V2_6_Primer.wiki#Anchor). 5013481Sgiacomo.travaglini@arm.com 5113481Sgiacomo.travaglini@arm.com NOTE: NEW_RELEASE_VERSION must be a NEW version number for 5213481Sgiacomo.travaglini@arm.com which the wiki pages don't yet exist; otherwise you'll get SVN 5313481Sgiacomo.travaglini@arm.com errors like "svn: Path 'V1_7_PumpManual.wiki' is not a 5413481Sgiacomo.travaglini@arm.com directory" when running the script. 5513481Sgiacomo.travaglini@arm.com 5613481Sgiacomo.travaglini@arm.comEXAMPLE 5713481Sgiacomo.travaglini@arm.com $ cd PATH/TO/GTEST_SVN_WORKSPACE/trunk 5813481Sgiacomo.travaglini@arm.com $ scripts/release_docs.py 2.6 # create wiki pages for v2.6 5913481Sgiacomo.travaglini@arm.com $ svn status # verify the file list 6013481Sgiacomo.travaglini@arm.com $ svn diff # verify the file contents 6113481Sgiacomo.travaglini@arm.com $ svn commit -m "release wiki pages for v2.6" 6213481Sgiacomo.travaglini@arm.com""" 6313481Sgiacomo.travaglini@arm.com 6413481Sgiacomo.travaglini@arm.com__author__ = 'wan@google.com (Zhanyong Wan)' 6513481Sgiacomo.travaglini@arm.com 6613481Sgiacomo.travaglini@arm.comimport os 6713481Sgiacomo.travaglini@arm.comimport re 6813481Sgiacomo.travaglini@arm.comimport sys 6913481Sgiacomo.travaglini@arm.com 7013481Sgiacomo.travaglini@arm.comimport common 7113481Sgiacomo.travaglini@arm.com 7213481Sgiacomo.travaglini@arm.com 7313481Sgiacomo.travaglini@arm.com# Wiki pages that shouldn't be branched for every gtest/gmock release. 7413481Sgiacomo.travaglini@arm.comGTEST_UNVERSIONED_WIKIS = ['DevGuide.wiki'] 7513481Sgiacomo.travaglini@arm.comGMOCK_UNVERSIONED_WIKIS = [ 7613481Sgiacomo.travaglini@arm.com 'DesignDoc.wiki', 7713481Sgiacomo.travaglini@arm.com 'DevGuide.wiki', 7813481Sgiacomo.travaglini@arm.com 'KnownIssues.wiki' 7913481Sgiacomo.travaglini@arm.com ] 8013481Sgiacomo.travaglini@arm.com 8113481Sgiacomo.travaglini@arm.com 8213481Sgiacomo.travaglini@arm.comdef DropWikiSuffix(wiki_filename): 8313481Sgiacomo.travaglini@arm.com """Removes the .wiki suffix (if any) from the given filename.""" 8413481Sgiacomo.travaglini@arm.com 8513481Sgiacomo.travaglini@arm.com return (wiki_filename[:-len('.wiki')] if wiki_filename.endswith('.wiki') 8613481Sgiacomo.travaglini@arm.com else wiki_filename) 8713481Sgiacomo.travaglini@arm.com 8813481Sgiacomo.travaglini@arm.com 8913481Sgiacomo.travaglini@arm.comclass WikiBrancher(object): 9013481Sgiacomo.travaglini@arm.com """Branches ...""" 9113481Sgiacomo.travaglini@arm.com 9213481Sgiacomo.travaglini@arm.com def __init__(self, dot_version): 9313481Sgiacomo.travaglini@arm.com self.project, svn_root_path = common.GetSvnInfo() 9413481Sgiacomo.travaglini@arm.com if self.project not in ('googletest', 'googlemock'): 9513481Sgiacomo.travaglini@arm.com sys.exit('This script must be run in a gtest or gmock SVN workspace.') 9613481Sgiacomo.travaglini@arm.com self.wiki_dir = svn_root_path + '/wiki' 9713481Sgiacomo.travaglini@arm.com # Turn '2.6' to 'V2_6_'. 9813481Sgiacomo.travaglini@arm.com self.version_prefix = 'V' + dot_version.replace('.', '_') + '_' 9913481Sgiacomo.travaglini@arm.com self.files_to_branch = self.GetFilesToBranch() 10013481Sgiacomo.travaglini@arm.com page_names = [DropWikiSuffix(f) for f in self.files_to_branch] 10113481Sgiacomo.travaglini@arm.com # A link to Foo.wiki is in one of the following forms: 10213481Sgiacomo.travaglini@arm.com # [Foo words] 10313481Sgiacomo.travaglini@arm.com # [Foo#Anchor words] 10413481Sgiacomo.travaglini@arm.com # [http://code.google.com/.../wiki/Foo words] 10513481Sgiacomo.travaglini@arm.com # [http://code.google.com/.../wiki/Foo#Anchor words] 10613481Sgiacomo.travaglini@arm.com # We want to replace 'Foo' with 'V2_6_Foo' in the above cases. 10713481Sgiacomo.travaglini@arm.com self.search_for_re = re.compile( 10813481Sgiacomo.travaglini@arm.com # This regex matches either 10913481Sgiacomo.travaglini@arm.com # [Foo 11013481Sgiacomo.travaglini@arm.com # or 11113481Sgiacomo.travaglini@arm.com # /wiki/Foo 11213481Sgiacomo.travaglini@arm.com # followed by a space or a #, where Foo is the name of an 11313481Sgiacomo.travaglini@arm.com # unversioned wiki page. 11413481Sgiacomo.travaglini@arm.com r'(\[|/wiki/)(%s)([ #])' % '|'.join(page_names)) 11513481Sgiacomo.travaglini@arm.com self.replace_with = r'\1%s\2\3' % (self.version_prefix,) 11613481Sgiacomo.travaglini@arm.com 11713481Sgiacomo.travaglini@arm.com def GetFilesToBranch(self): 11813481Sgiacomo.travaglini@arm.com """Returns a list of .wiki file names that need to be branched.""" 11913481Sgiacomo.travaglini@arm.com 12013481Sgiacomo.travaglini@arm.com unversioned_wikis = (GTEST_UNVERSIONED_WIKIS if self.project == 'googletest' 12113481Sgiacomo.travaglini@arm.com else GMOCK_UNVERSIONED_WIKIS) 12213481Sgiacomo.travaglini@arm.com return [f for f in os.listdir(self.wiki_dir) 12313481Sgiacomo.travaglini@arm.com if (f.endswith('.wiki') and 12413481Sgiacomo.travaglini@arm.com not re.match(r'^V\d', f) and # Excluded versioned .wiki files. 12513481Sgiacomo.travaglini@arm.com f not in unversioned_wikis)] 12613481Sgiacomo.travaglini@arm.com 12713481Sgiacomo.travaglini@arm.com def BranchFiles(self): 12813481Sgiacomo.travaglini@arm.com """Branches the .wiki files needed to be branched.""" 12913481Sgiacomo.travaglini@arm.com 13013481Sgiacomo.travaglini@arm.com print 'Branching %d .wiki files:' % (len(self.files_to_branch),) 13113481Sgiacomo.travaglini@arm.com os.chdir(self.wiki_dir) 13213481Sgiacomo.travaglini@arm.com for f in self.files_to_branch: 13313481Sgiacomo.travaglini@arm.com command = 'svn cp %s %s%s' % (f, self.version_prefix, f) 13413481Sgiacomo.travaglini@arm.com print command 13513481Sgiacomo.travaglini@arm.com os.system(command) 13613481Sgiacomo.travaglini@arm.com 13713481Sgiacomo.travaglini@arm.com def UpdateLinksInBranchedFiles(self): 13813481Sgiacomo.travaglini@arm.com 13913481Sgiacomo.travaglini@arm.com for f in self.files_to_branch: 14013481Sgiacomo.travaglini@arm.com source_file = os.path.join(self.wiki_dir, f) 14113481Sgiacomo.travaglini@arm.com versioned_file = os.path.join(self.wiki_dir, self.version_prefix + f) 14213481Sgiacomo.travaglini@arm.com print 'Updating links in %s.' % (versioned_file,) 14313481Sgiacomo.travaglini@arm.com text = file(source_file, 'r').read() 14413481Sgiacomo.travaglini@arm.com new_text = self.search_for_re.sub(self.replace_with, text) 14513481Sgiacomo.travaglini@arm.com file(versioned_file, 'w').write(new_text) 14613481Sgiacomo.travaglini@arm.com 14713481Sgiacomo.travaglini@arm.com 14813481Sgiacomo.travaglini@arm.comdef main(): 14913481Sgiacomo.travaglini@arm.com if len(sys.argv) != 2: 15013481Sgiacomo.travaglini@arm.com sys.exit(__doc__) 15113481Sgiacomo.travaglini@arm.com 15213481Sgiacomo.travaglini@arm.com brancher = WikiBrancher(sys.argv[1]) 15313481Sgiacomo.travaglini@arm.com brancher.BranchFiles() 15413481Sgiacomo.travaglini@arm.com brancher.UpdateLinksInBranchedFiles() 15513481Sgiacomo.travaglini@arm.com 15613481Sgiacomo.travaglini@arm.com 15713481Sgiacomo.travaglini@arm.comif __name__ == '__main__': 15813481Sgiacomo.travaglini@arm.com main() 159