[Asterisk-code-review] build: Improve handling of CHANGES and UPGRADE.txt for relea... (repotools[master])

Benjamin Keith Ford asteriskteam at digium.com
Fri Feb 1 11:46:23 CST 2019


Benjamin Keith Ford has uploaded this change for review. ( https://gerrit.asterisk.org/10941


Change subject: build: Improve handling of CHANGES and UPGRADE.txt for releases.
......................................................................

build: Improve handling of CHANGES and UPGRADE.txt for releases.

The release script now handles the merging of the CHANGES and
UPGRADE.txt files for us! When a release is being done, the script will
go through the staging changes in the Asterisk working directory
(<asterisk-home>/doc/<file>-staging) and add each change to the
corresponding file. A separate script (process-staging-changes) has also
been added that can be used when creating a new version from master. It
takes 3 arguments: -l/--local-root, which is optional,
-s/--start-version, and -e/--end-version. You can use -h for more
information on each option.

This means that there's a new way to document our major changes. All
changes for CHANGES will go into doc/CHANGES-staging and all changes for
UPGRADE.txt will go into doc/UPGRADE-staging. Each of these files should
have a meaningful name related to what the change is. For example, if
you made a change to something in pjsip, your file might be called
"res_pjsip_relative_title", where "relative_title" will be something a
little more descriptive than that. Inside of each file, you will have a
subject line followed by a blank line, with the description of the
change following that. You can have multiple subject lines in one file.
For example, it may look something like this:

   Subject: res_pjsip

   This is a detailed description of what I changed.

   You can have new lines in between as well, spacing is handled by the
   release script!

   Subject: res_pjsip

   You can have another subject as well!

   Subject: Core

   The subjects don't have to be the same either!

The header lines (Subject:) are case sensative.

Fore more information, check out the wiki page:
https://wiki.asterisk.org/wiki/display/AST/CHANGES+and+UPGRADE.txt

Change-Id: I6dc084afedaeecaf36aaec66c3cf6a5a8ed4ef3c
---
M mkrelease.py
A process-staging-changes
A staging_changes.py
3 files changed, 227 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/repotools refs/changes/41/10941/1

diff --git a/mkrelease.py b/mkrelease.py
index 10e1a7e..fd9a272 100755
--- a/mkrelease.py
+++ b/mkrelease.py
@@ -23,6 +23,7 @@
 from release_summary import ReleaseSummary, ReleaseSummaryOptions
 from alembic_creator import create_db_script
 from testsuite import update_testsuite
+from staging_changes import StagingChangesExtractor
 
 LOGGER = logging.getLogger(__name__)
 
@@ -692,6 +693,16 @@
                                                                prev_version))
         create_tag(options, repo)
 
+    # At this point, we should be on the correct branch with everything ready except
+    # for the staging changes for CHANGES and UPGRADE.txt. Get those changes now
+    # before we push everything upstream.
+    extractor = StagingChangesExtractor(path=options.local_root, start_version=prev_version,
+                                        end_version=version)
+    ret = extractor.run()
+    if ret != 0:
+        print "Error while trying to get staging changes!"
+        sys.exit(1)
+
     prompt_to_continue("Tag created, pushing changes to remote.")
     repo.push_changes()
 
diff --git a/process-staging-changes b/process-staging-changes
new file mode 100755
index 0000000..79e33f8
--- /dev/null
+++ b/process-staging-changes
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+'''
+Manually get the staging changes from <asterisk_home>/doc/<file>-staging
+and add them to <file>.
+
+Ben Ford <bford at digium.com>
+'''
+
+from staging_changes import StagingChangesExtractor
+from argparse import ArgumentParser
+
+if __name__ == "__main__":
+    parser = ArgumentParser(description="Processes changes in working tree and updates files")
+    parser.add_argument("-l", "--local-root", dest="path", help="The local root to work from", default="/tmp")
+    parser.add_argument("-s", "--start-version", dest="start", help="The version to start from", required=True)
+    parser.add_argument("-e", "--end-version", dest="end", help="The version to end on", required=True)
+
+    args = parser.parse_args()
+
+    sce = StagingChangesExtractor(ast_path=args.path, start_version=args.start, end_version=args.end)
+    ret = sce.run()
+
+    if ret == 0:
+        print "Done!"
+    else:
+        print "Uh oh - omething went wrong!"
diff --git a/staging_changes.py b/staging_changes.py
new file mode 100644
index 0000000..876bc2f
--- /dev/null
+++ b/staging_changes.py
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+'''
+Used to extract information from <asterisk_home>/doc/<file>-staging/
+and add that information to <asterisk_home>/<file>
+
+Ben Ford <bford at digium.com>
+'''
+
+import logging
+import os
+import fileinput
+
+LOGGER = logging.getLogger(__name__)
+
+MODES = ["CHANGES", "UPGRADE"]
+FUNCTIONALITY_SEPARATOR_DASH_COUNT = 78
+CATEGORY_SEPARATOR_DASH_COUNT = 18
+
+class StagingChangesExtractor:
+    '''
+    Holds all the information needed to update the target files.
+
+    Currently there is support for CHANGES and UPGRADE.txt
+    '''
+
+    def __init__(self, ast_path, start_version, end_version):
+        '''
+        Initializer
+
+        ast_path        The location of the Asterisk directory we are working with
+        start_version   The version we are starting from
+        end_version     The version we are ending on
+        '''
+        if ast_path is None:
+            raise Exception("ast_path cannot be NULL")
+        if start_version is None:
+            raise Exception("start_version cannot be NULL")
+        if end_version is None:
+            raise Exception("end_version cannot be NULL")
+
+        self.data = dict()
+        # If the path doesn't end with '/', go ahead and add one for get_staging_changes
+        if ast_path.endswith('/') == False:
+            ast_path += '/'
+        self.ast_path = ast_path
+        self.start_version = start_version
+        self.end_version = end_version
+
+    def gen_separator(self, count):
+        '''
+        Generate a number of dashes to be used as a separator
+
+        count       The number of dashes to generate
+
+        returns     A string with <count> dash(es)
+        '''
+        ret = ""
+        for num in range(count):
+            ret += "-"
+        return ret
+
+    def gen_header(self, mode):
+        '''
+        Generate the header that will precede data in the target file
+        '''
+        if mode is "CHANGES":
+            header = "--- Functionality changes from Asterisk {0} to Asterisk {1} ".format(self.start_version, self.end_version)
+            remaining = FUNCTIONALITY_SEPARATOR_DASH_COUNT - len(header)
+            header += self.gen_separator(remaining)
+            separator = self.gen_separator(FUNCTIONALITY_SEPARATOR_DASH_COUNT)
+            header = separator + "\n" + header + "\n" + separator + "\n\n"
+        elif mode is "UPGRADE":
+            header = "From {0} to {1}:\n\n".format(self.start_version, self.end_version)
+        else:
+            return None
+
+        return header
+
+    def get_staging_changes(self, mode):
+        '''
+        Retrieve changes from <self.ast_path>/doc/<mode>-staging/
+        
+        returns     0 on success
+        returns     -1 on failure
+        '''
+        if mode is not "CHANGES" and mode is not "UPGRADE":
+            return -1
+
+        staging_path = "{0}/doc/{1}-staging".format(self.ast_path, mode)
+        try:
+            for filename in os.listdir(staging_path):
+                if not os.path.isfile(staging_path + "/" + filename) or filename == "README":
+                    continue
+                with open(staging_path + "/" + filename, 'r') as f:
+                    subject = ""
+                    line = f.readline()
+                    while line != "":
+                        # Get the subject
+                        if line.startswith("Subject:"):
+                            if subject != "":
+                                # In the case of trailing space of any kind, remove it. For example,
+                                # double new line characters make the format mess up.
+                                self.data.update({subject: self.data[subject].rstrip() + "\n"})
+                            subject = line.split("Subject:")[1].lstrip()
+                            if subject not in self.data:
+                                self.data.update({subject: "{0}{1}\n".format(subject, self.gen_separator(CATEGORY_SEPARATOR_DASH_COUNT))})
+                            else:
+                                self.data.update({subject: self.data[subject] + "\n"})
+                            f.readline()
+                            line = f.readline()
+                            self.data.update({subject: self.data[subject] + " * " + line})
+                        elif line == "\n":
+                            # This is a special case because if there is an empty line separating some
+                            # text, we don't want to add 3 spaces and then a new line.
+                            self.data.update({subject: self.data[subject] + "\n"})
+                        else:
+                            self.data.update({subject: self.data[subject] + "   " + line})
+                        line = f.readline()
+                # Clean up the staging directory as we cycle through the files
+                os.remove(os.path.join(staging_path, filename))
+        except:
+            LOGGER.debug("Could not extract data from {0}".format(staging_path))
+            return -1
+
+        return 0
+
+    def add_staging_changes(self, mode):
+        '''
+        Add the changes retrieved to <self.ast_path/<mode>(.txt)
+
+        returns     0 on success
+        returns     -1 on failure
+        '''
+        if mode is not "CHANGES" and mode is not "UPGRADE":
+            return -1
+
+        if bool(self.data) is False:
+            # There was no data to retrieve during get_staging_changes
+            return 0
+
+        header = self.gen_header(mode)
+        if header is None:
+            return -1
+
+        file_path = "{0}/{1}".format(self.ast_path, mode)
+        if mode is "UPGRADE":
+            file_path += ".txt"
+        try:
+            insert = 0
+            for line in fileinput.FileInput(file_path, inplace = 1):
+                if insert is 0 and line in ["\n", "\r\n"]:
+                    insert = 1
+                    continue
+                if insert is 1:
+                    for entry in self.data:
+                        line = line.replace(line, self.data[entry] + "\n" + line)
+                    line = line.replace(line, "\n" + header + line)
+                    insert = 2
+                print line,
+        except:
+            LOGGER.debug("Could not add data to {0}".format(file_path))
+            return -1
+
+        return 0
+
+    def run(self):
+        '''
+        Put everything together and run it
+
+        returns     0 on success
+        returns     -1 on failure
+        '''
+
+        for mode in MODES:
+            LOGGER.debug("Extracting changes for {0}".format(mode))
+            self.data.clear()
+
+            ret = self.get_staging_changes(mode)
+            if ret is not 0:
+                LOGGER.debug("Failed during {0} get_staging_changes step - aborting "
+                             "(working directory probably needs to be reset!!!)".format(mode))
+                return -1
+
+            ret = self.add_staging_changes(mode)
+            if ret is not 0:
+                LOGGER.debug("Failed during {0} add_staging_changes step - aborting "
+                             "(working directory probably needs to be reset!!!)".format(mode))
+                return -1
+
+        return 0

-- 
To view, visit https://gerrit.asterisk.org/10941
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: repotools
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6dc084afedaeecaf36aaec66c3cf6a5a8ed4ef3c
Gerrit-Change-Number: 10941
Gerrit-PatchSet: 1
Gerrit-Owner: Benjamin Keith Ford <bford at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190201/b78b39e4/attachment-0001.html>


More information about the asterisk-code-review mailing list