manifoldcf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kwri...@apache.org
Subject svn commit: r1561575 - in /manifoldcf/release-scripts: create_release_branch.py update_release_branch.py
Date Mon, 27 Jan 2014 00:53:33 GMT
Author: kwright
Date: Mon Jan 27 00:53:33 2014
New Revision: 1561575

URL: http://svn.apache.org/r1561575
Log:
Add release branch update script.

Added:
    manifoldcf/release-scripts/update_release_branch.py   (with props)
Modified:
    manifoldcf/release-scripts/create_release_branch.py

Modified: manifoldcf/release-scripts/create_release_branch.py
URL: http://svn.apache.org/viewvc/manifoldcf/release-scripts/create_release_branch.py?rev=1561575&r1=1561574&r2=1561575&view=diff
==============================================================================
--- manifoldcf/release-scripts/create_release_branch.py (original)
+++ manifoldcf/release-scripts/create_release_branch.py Mon Jan 27 00:53:33 2014
@@ -21,7 +21,7 @@ def remove_dir(directory_path):
 
 def get_line_end(line):
     """ Get the line end characters for the line """
-    if len(line) > 2 and line[len(line)-2] == '\r':
+    if len(line) >= 2 and line[len(line)-2] == '\r':
         return "\r\n"
     return "\n"
 

Added: manifoldcf/release-scripts/update_release_branch.py
URL: http://svn.apache.org/viewvc/manifoldcf/release-scripts/update_release_branch.py?rev=1561575&view=auto
==============================================================================
--- manifoldcf/release-scripts/update_release_branch.py (added)
+++ manifoldcf/release-scripts/update_release_branch.py Mon Jan 27 00:53:33 2014
@@ -0,0 +1,494 @@
+import sys
+import os
+import shutil
+import subprocess
+import codecs
+
+def svn_command(command_array):
+    """ Invoke svn command """
+    popen = subprocess.Popen(["svn"] + command_array,
+        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    out,err = popen.communicate()
+    rcode = popen.returncode
+    if rcode != 0:
+        raise Exception("svn invocation errored with code %d: %s" % (rcode,err))
+    return out
+
+def remove_dir(directory_path):
+    """ Remove a directory and all of its contents """
+    shutil.rmtree(directory_path)
+    #print "Pretend cleanup '%s'..." % directory_path
+
+def get_line_end(line):
+    """ Get the line end characters for the line """
+    if len(line) >= 2 and line[len(line)-2] == '\r':
+        return "\r\n"
+    return "\n"
+
+def match_change_txt_dev_line(line):
+    """ Find a line looking like this:
+        ===== nnn-dev =====
+    """
+    index = line.find("=== ")
+    if index == -1:
+        return False
+    end_index = line.find("-dev ===", index + 4)
+    return end_index != -1
+
+def make_change_txt_release_line(build_version, line_end):
+    return "======================= Release %s =====================%s" % (build_version,
line_end)
+
+def set_change_file_release_row(change_file_path, release_version):
+    """ Convert the -dev row in a change file to a release row """
+    converted = False
+    temp_file = "%s.tmp" % change_file_path
+    fd = codecs.open(change_file_path, "r", "utf-8")
+    try:
+        out_fd = codecs.open(temp_file, "w", "utf-8")
+        try:
+            for line in fd:
+                if converted:
+                    out_fd.write(line)
+                else:
+                    if match_change_txt_dev_line(line):
+                        out_fd.write(make_change_txt_release_line(release_version, get_line_end(line)))
+                        converted = True
+                    else:
+                        out_fd.write(line)
+        finally:
+            out_fd.close()
+    finally:
+        fd.close()
+        
+    # Remove old file and rename temp file
+    os.unlink(change_file_path)
+    os.rename(temp_file, change_file_path)
+
+def match_change_txt_add_line(line):
+    """ Look for a line with === in it """
+    return line.find("===") >= 0
+
+def make_change_txt_dev_line(dev_version, line_end):
+    return "======================= %s-dev =====================%s" % (dev_version, line_end);
+
+def add_change_file_new_dev_row(change_file_path, dev_version):
+    """ Add a new -dev row to the start of a change file """
+    added_row = False
+    temp_file = "%s.tmp" % change_file_path
+    fd = codecs.open(change_file_path, "r", "utf-8")
+    try:
+        out_fd = codecs.open(temp_file, "w", "utf-8")
+        try:
+            for line in fd:
+                if added_row:
+                    out_fd.write(line)
+                else:
+                    if match_change_txt_add_line(line):
+                        line_end = get_line_end(line)
+                        out_fd.write(make_change_txt_dev_line(dev_version, line_end))
+                        out_fd.write(line_end)
+                        out_fd.write(line_end)
+                        out_fd.write(line)
+                        added_row = True
+                    else:
+                        out_fd.write(line)
+        finally:
+            out_fd.close()
+    finally:
+        fd.close()
+        
+    # Remove old file and rename temp file
+    os.unlink(change_file_path)
+    os.rename(temp_file, change_file_path)
+
+IN_BODY = 0
+IN_PREAMBLE = 1
+IN_COMMENT = 2
+IN_TAG_NAME = 3
+IN_TAG_BODY = 4
+IN_END_TAG_NAME = 5
+IN_BODY_SEEN_LEFTANGLE = 6
+IN_BODY_SEEN_LEFTANGLE_BANG = 7
+IN_BODY_SEEN_LEFTANGLE_BANG_DASH = 9
+IN_COMMENT_SEEN_DASH = 11
+IN_COMMENT_SEEN_DASH_DASH = 12
+IN_PREAMBLE_SEEN_QUESTION = 13
+IN_TAG_BODY_SEEN_SLASH = 14
+IN_TAG_SEEN_SLASH = 15
+
+class TagScanner:
+    
+    def __init__( self, action_object ):
+        self.state = IN_BODY
+        self.tag_name = None
+        self.action_object = action_object
+        self.body_accumulator = u''
+    
+    def end( self ):
+        if self.state != IN_BODY:
+            raise Exception("At end, in unknown state %d" % self.state)
+        self.action_object.write(self.action_object.map_body(self.body_accumulator))
+
+    def accept_character( self, char ):
+        uchar = unicode(char)
+        if self.state == IN_BODY:
+            if uchar == u'<':
+                self.state = IN_BODY_SEEN_LEFTANGLE
+            else:
+                self.body_accumulator += uchar
+                
+        elif self.state == IN_PREAMBLE:
+            if uchar == u'?':
+                self.state = IN_PREAMBLE_SEEN_QUESTION
+                self.action_object.write(uchar)
+            else:
+                self.action_object.write(uchar)
+                
+        elif self.state == IN_COMMENT:
+            if uchar == u'-':
+                self.state = IN_COMMENT_SEEN_DASH
+                self.action_object.write(uchar)
+            else:
+                self.action_object.write(uchar)
+                
+        elif self.state == IN_TAG_NAME:
+            if uchar <= u' ':
+                self.action_object.found_tag(self.tag_name)
+                self.action_object.write(uchar)
+                self.state = IN_TAG_BODY
+            elif uchar == u'>':
+                self.action_object.found_tag(self.tag_name)
+                self.action_object.write(uchar)
+                self.state = IN_BODY
+            elif uchar == u'/':
+                self.action_object.found_tag(self.tag_name)
+                self.action_object.write(uchar)
+                self.state = IN_TAG_SEEN_SLASH
+            else:
+                self.tag_name += uchar
+                self.action_object.write(uchar)
+
+        elif self.state == IN_TAG_SEEN_SLASH:
+            if uchar == u'>':
+                self.action_object.found_end_tag(self.tag_name)
+                self.action_object.write(uchar)
+                self.state = IN_BODY
+                self.tag_name = None
+            elif uchar == u'/':
+                self.action_object.write(uchar)
+            else:
+                self.action_object.write(uchar)
+                self.state = IN_TAG_BODY
+
+        elif self.state == IN_TAG_BODY:
+            if uchar == u'/':
+                self.state = IN_TAG_BODY_SEEN_SLASH
+                self.action_object.write(uchar)
+            elif uchar == u'>':
+                self.state = IN_BODY
+                self.action_object.write(uchar)
+            else:
+                self.action_object.write(uchar)
+
+        elif self.state == IN_TAG_BODY_SEEN_SLASH:
+            if uchar == u'>':
+                self.action_object.found_end_tag(self.tag_name)
+                self.action_object.write(uchar)
+                self.state = IN_BODY
+                self.tag_name = None
+            elif uchar == u'/':
+                self.action_object.write(uchar)
+            else:
+                self.action_object.write(uchar)
+                self.state = IN_TAG_BODY
+
+        elif self.state == IN_END_TAG_NAME:
+            if uchar == u'>':
+                self.state = IN_BODY
+                self.action_object.found_end_tag(self.tag_name)
+                self.action_object.write(uchar)
+                self.tag_name = None
+            else:
+                self.action_object.write(uchar)
+                self.tag_name += uchar
+
+        elif self.state == IN_BODY_SEEN_LEFTANGLE:
+            if uchar == u'!':
+                self.state = IN_BODY_SEEN_LEFTANGLE_BANG
+            elif uchar == u'?':
+                self.action_object.write(self.action_object.map_body(self.body_accumulator))
+                self.body_accumulator = u""
+                self.action_object.write(u'<')
+                self.action_object.write(u'?')
+                self.body_accumulator = u""
+                self.state = IN_PREAMBLE
+            elif uchar == u'/':
+                self.state = IN_END_TAG_NAME
+                self.action_object.write(self.action_object.map_body(self.body_accumulator))
+                self.body_accumulator = u""
+                self.action_object.write(u'<')
+                self.action_object.write(u'/')
+                self.tag_name = u""
+            elif uchar == u'<':
+                self.body_accumulator += u'<'
+            else:
+                self.action_object.write(self.action_object.map_body(self.body_accumulator))
+                self.body_accumulator = u""
+                self.action_object.write(u'<')
+                self.action_object.write(uchar)
+                self.tag_name = u"" + uchar
+                self.state = IN_TAG_NAME
+
+        elif self.state == IN_BODY_SEEN_LEFTANGLE_BANG:
+            if uchar == u'-':
+                self.state = IN_BODY_SEEN_LEFTANGLE_BANG_DASH
+            else:
+                self.body_accumulator += u'<'
+                self.body_accumulator += u'!'
+                self.body_accumulator += uchar
+            
+        elif self.state == IN_BODY_SEEN_LEFTANGLE_BANG_DASH:
+            if uchar == u'-':
+                self.state = IN_COMMENT
+                self.action_object.write(self.action_object.map_body(self.body_accumulator))
+                self.body_accumulator = u""
+                self.action_object.write(u"<!--")
+            else:
+                self.state = IN_BODY
+                self.body_accumulator += u"<!-"
+                self.body_accumulator += uchar
+            
+        elif self.state == IN_COMMENT_SEEN_DASH:
+            if uchar == u'-':
+                self.state = IN_COMMENT_SEEN_DASH_DASH
+                self.action_object.write(uchar)
+            else:
+                self.action_object.write(uchar)
+                self.state = IN_COMMENT
+
+        elif self.state == IN_COMMENT_SEEN_DASH_DASH:
+            if uchar == u'>':
+                self.state = IN_BODY
+                self.action_object.write(uchar)
+            elif uchar == u'-':
+                self.action_object.write(uchar)
+            else:
+                self.state = IN_COMMENT
+                self.action_object.write(uchar)
+
+        elif self.state == IN_PREAMBLE_SEEN_QUESTION:
+            if uchar == u'>':
+                self.state = IN_BODY
+                self.action_object.write(uchar)
+            elif uchar == u'?':
+                self.action_object.write(uchar)
+            else:
+                self.action_object.write(uchar)
+                self.state = IN_PREAMBLE
+
+        else:
+            raise Exception("Unknown state %d" % self.state)
+        
+
+class ActionBase:
+    def __init__( self, output_stream ):
+        self.output_stream = output_stream
+        
+    def write( self, chars ):
+        self.output_stream.write( chars )
+
+    def map_body( self, body_text ):
+        return body_text
+    
+    def found_end_tag( self, tag_name ):
+        pass
+        
+    def found_tag( self, tag_name ):
+        pass
+
+
+class HierarchicalAction(ActionBase):
+    def __init__( self, output_stream ):
+        ActionBase.__init__( self, output_stream )
+        self.tag_hierarchy = [ ]
+        
+    def found_tag( self, tag_name ):
+        self.tag_hierarchy += [ tag_name ]
+        self.enter_tag( self.make_tag_string( ) )
+    
+    def found_end_tag( self, tag_name ):
+        if len(self.tag_hierarchy) == 0 or self.tag_hierarchy[len(self.tag_hierarchy)-1]
!= tag_name:
+            raise Exception("Unmatched end tag '%s'" % tag_name)
+        self.exit_tag( self.make_tag_string( ) )
+        del self.tag_hierarchy[len(self.tag_hierarchy)-1]
+    
+    def make_tag_string( self ):
+        tag_string = u""
+        for tag in self.tag_hierarchy:
+            tag_string += u"/" + tag
+        return tag_string
+
+    def enter_tag( self, hierarchy_string ):
+        pass
+        
+    def exit_tag( self, hierarchy_string ):
+        pass
+
+class PomAction(HierarchicalAction):
+    def __init__( self, output_stream, new_version, root_parent ):
+        HierarchicalAction.__init__( self, output_stream )
+        self.accumulator = None
+        self.modules = [ ]
+        self.new_version = new_version
+        self.replace = False
+        self.root_parent = root_parent
+
+    def enter_tag( self, hierarchy_string ):
+        if hierarchy_string == u"/project/modules/module":
+            self.accumulator = u""
+        elif hierarchy_string == u"/project/version":
+            self.replace = True
+        elif hierarchy_string == u"/project/parent/version" and not self.root_parent:
+            self.replace = True
+            
+    def exit_tag( self, hierarchy_string ):
+        if hierarchy_string == u"/project/modules/module":
+            self.modules += [ self.accumulator ]
+            self.accumulator = None
+        elif hierarchy_string == u"/project/version":
+            self.replace = False
+        elif hierarchy_string == u"/project/parent/version" and not self.root_parent:
+            self.replace = False
+
+    def map_body( self, body_text ):
+        if self.accumulator != None:
+            self.accumulator += body_text
+        if self.replace:
+            return self.new_version
+        return body_text
+
+def fix_pom_xml(pom_file_path, pom_version, root_parent):
+    """
+        Fix primary versions in a pom file to become the specified pom_version.
+        Returns an array of child project names (NOT paths).
+    """
+    rval = None
+    temp_file = "%s.tmp" % pom_file_path
+    fd = codecs.open(pom_file_path, "r", "utf-8")
+    try:
+        out_fd = codecs.open(temp_file, "w", "utf-8")
+        try:
+            action_object = PomAction(out_fd, pom_version, root_parent)
+            ts = TagScanner(action_object)
+            for line in fd:
+                for char in line:
+                    ts.accept_character(char)
+            ts.end()
+            rval = action_object.modules
+        finally:
+            out_fd.close()
+    finally:
+        fd.close()
+
+    os.unlink(pom_file_path)
+    os.rename(temp_file, pom_file_path)
+    return rval
+
+def update_poms(root_directory, pom_version, root_parent=True):
+    """ Update all poms in a project """
+    dirs = fix_pom_xml( "%s/pom.xml" % root_directory, pom_version, root_parent )
+    for dir in dirs:
+        update_poms( "%s/%s" % (root_directory, dir), pom_version, root_parent=False )
+
+def convert_build_xml_line(line, build_version):
+    """
+        Fills value in where property name is "release-version", e.g. <property name="release-version"
value="1.6-dev"/>
+    """
+    string_to_match = "<property name=\"release-version\" value=\""
+    index = line.find(string_to_match)
+    if index == -1:
+        return line
+    end_index = line.find("\"", index + len(string_to_match))
+    if end_index == -1:
+        raise Exception("Can't substitute line '%s'" % line)
+    return line[0:index] + string_to_match + build_version + line[end_index:len(line)]
+
+def fix_build_xml(build_file_path, build_version):
+    """ Update version number in build.xml to be the specified one. """
+    temp_file = "%s.tmp" % build_file_path
+    fd = codecs.open(build_file_path, "r", "utf-8")
+    try:
+        out_fd = codecs.open(temp_file, "w", "utf-8")
+        try:
+            for line in fd:
+                out_fd.write(convert_build_xml_line(line, build_version))
+        finally:
+            out_fd.close()
+    finally:
+        fd.close()
+        
+    # Remove old file and rename temp file
+    os.unlink(build_file_path)
+    os.rename(temp_file, build_file_path)
+
+def checkout_tree(tree_directory_path, svn_url):
+    """ Check out the specified svn tree to the specified place """
+    svn_command(["co", svn_url, tree_directory_path])
+
+def commit_tree(tree_directory_path, commit_message):
+    """ Commit the svn tree using the specified commit message """
+    svn_command([ "-m", commit_message, "commit", tree_directory_path])
+    #print "Pretend commit..."
+
+def update_release_branch(release_branch_version_name, new_release_version, working_directory):
+    """ Modify specified release branch to update versions -- e.g. go from 1.5 to 1.5.1 on
release branch 1.5 """
+    # Basic checks
+    if not os.path.exists(working_directory):
+        raise Exception("Working directory '%s' does not appear to exist" % working_directory)
+    if release_branch_version_name.find("release") >= 0 or release_branch_version_name.find("branches")
>= 0:
+        raise Exception("Release major version name should consist only of major version
name, i.e. '1.5'")
+    if release_branch_version_name.find("-SNAPSHOT") >= 0 or release_branch_version_name.find("-dev")
>= 0:
+        raise Exception("Release major version '%s' cannot contain SNAPSHOT or dev" % release_version)
+    if new_release_version.find("-SNAPSNOT") >= 0 or new_release_version.find("-dev")
>= 0:
+        raise Exception("New release version '%s' cannot contain SNAPSHOT or dev" % new_trunk_version)
+
+    # Point to all the right places
+    branch_url = "https://svn.apache.org/repos/asf/manifoldcf/branches/release-%s-branch"
% release_branch_version_name
+    branch_dir = "%s/branch" % working_directory
+    
+    branch_changes_file = "%s/CHANGES.txt" % branch_dir
+    branch_build_xml_file = "%s/build.xml" % branch_dir
+    
+    # Check out branch.
+    checkout_tree(branch_dir, branch_url)
+
+    # Add change file release row.
+    add_change_file_new_dev_row(branch_changes_file, new_release_version)
+    set_change_file_release_row(branch_changes_file, new_release_version)
+    # Update build.xml
+    fix_build_xml(branch_build_xml_file, new_release_version)
+    # Update poms
+    update_poms(branch_dir, new_release_version)
+    
+    # Commit trunk
+    commit_tree(branch_dir, "Prepare for release %s" % new_release_version)
+    
+    # Finally, delete branch checkout (we're done with it)
+    remove_dir(branch_dir)
+
+if __name__ == '__main__':
+    if len(sys.argv) != 3 and len(sys.argv) != 4:
+        print >> sys.stderr, "Usage: %s <release_branch_major_version> <new_branch_version>
[<working_directory>]" % sys.argv[0]
+        sys.exit(1)
+    
+    release_branch_version_name = sys.argv[1]
+    new_branch_version = sys.argv[2]
+    if len(sys.argv) > 3:
+        working_dir = sys.argv[3]
+    else:
+        working_dir = "."
+    
+    update_release_branch(release_branch_version_name, new_branch_version, working_dir)
+    
+    print >> sys.stderr, "Release branch updated!"
+    
\ No newline at end of file

Propchange: manifoldcf/release-scripts/update_release_branch.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/release-scripts/update_release_branch.py
------------------------------------------------------------------------------
    svn:keywords = Id



Mime
View raw message