<p>Benjamin Keith Ford has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10941">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">build: Improve handling of CHANGES and UPGRADE.txt for releases.<br><br>The release script now handles the merging of the CHANGES and<br>UPGRADE.txt files for us! When a release is being done, the script will<br>go through the staging changes in the Asterisk working directory<br>(<asterisk-home>/doc/<file>-staging) and add each change to the<br>corresponding file. A separate script (process-staging-changes) has also<br>been added that can be used when creating a new version from master. It<br>takes 3 arguments: -l/--local-root, which is optional,<br>-s/--start-version, and -e/--end-version. You can use -h for more<br>information on each option.<br><br>This means that there's a new way to document our major changes. All<br>changes for CHANGES will go into doc/CHANGES-staging and all changes for<br>UPGRADE.txt will go into doc/UPGRADE-staging. Each of these files should<br>have a meaningful name related to what the change is. For example, if<br>you made a change to something in pjsip, your file might be called<br>"res_pjsip_relative_title", where "relative_title" will be something a<br>little more descriptive than that. Inside of each file, you will have a<br>subject line followed by a blank line, with the description of the<br>change following that. You can have multiple subject lines in one file.<br>For example, it may look something like this:<br><br>   Subject: res_pjsip<br><br>   This is a detailed description of what I changed.<br><br>   You can have new lines in between as well, spacing is handled by the<br>   release script!<br><br>   Subject: res_pjsip<br><br>   You can have another subject as well!<br><br>   Subject: Core<br><br>   The subjects don't have to be the same either!<br><br>The header lines (Subject:) are case sensative.<br><br>Fore more information, check out the wiki page:<br>https://wiki.asterisk.org/wiki/display/AST/CHANGES+and+UPGRADE.txt<br><br>Change-Id: I6dc084afedaeecaf36aaec66c3cf6a5a8ed4ef3c<br>---<br>M mkrelease.py<br>A process-staging-changes<br>A staging_changes.py<br>3 files changed, 227 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/repotools refs/changes/41/10941/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/mkrelease.py b/mkrelease.py</span><br><span>index 10e1a7e..fd9a272 100755</span><br><span>--- a/mkrelease.py</span><br><span>+++ b/mkrelease.py</span><br><span>@@ -23,6 +23,7 @@</span><br><span> from release_summary import ReleaseSummary, ReleaseSummaryOptions</span><br><span> from alembic_creator import create_db_script</span><br><span> from testsuite import update_testsuite</span><br><span style="color: hsl(120, 100%, 40%);">+from staging_changes import StagingChangesExtractor</span><br><span> </span><br><span> LOGGER = logging.getLogger(__name__)</span><br><span> </span><br><span>@@ -692,6 +693,16 @@</span><br><span>                                                                prev_version))</span><br><span>         create_tag(options, repo)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    # At this point, we should be on the correct branch with everything ready except</span><br><span style="color: hsl(120, 100%, 40%);">+    # for the staging changes for CHANGES and UPGRADE.txt. Get those changes now</span><br><span style="color: hsl(120, 100%, 40%);">+    # before we push everything upstream.</span><br><span style="color: hsl(120, 100%, 40%);">+    extractor = StagingChangesExtractor(path=options.local_root, start_version=prev_version,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        end_version=version)</span><br><span style="color: hsl(120, 100%, 40%);">+    ret = extractor.run()</span><br><span style="color: hsl(120, 100%, 40%);">+    if ret != 0:</span><br><span style="color: hsl(120, 100%, 40%);">+        print "Error while trying to get staging changes!"</span><br><span style="color: hsl(120, 100%, 40%);">+        sys.exit(1)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     prompt_to_continue("Tag created, pushing changes to remote.")</span><br><span>     repo.push_changes()</span><br><span> </span><br><span>diff --git a/process-staging-changes b/process-staging-changes</span><br><span>new file mode 100755</span><br><span>index 0000000..79e33f8</span><br><span>--- /dev/null</span><br><span>+++ b/process-staging-changes</span><br><span>@@ -0,0 +1,26 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#!/usr/bin/env python</span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+Manually get the staging changes from <asterisk_home>/doc/<file>-staging</span><br><span style="color: hsl(120, 100%, 40%);">+and add them to <file>.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Ben Ford <bford@digium.com></span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from staging_changes import StagingChangesExtractor</span><br><span style="color: hsl(120, 100%, 40%);">+from argparse import ArgumentParser</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+    parser = ArgumentParser(description="Processes changes in working tree and updates files")</span><br><span style="color: hsl(120, 100%, 40%);">+    parser.add_argument("-l", "--local-root", dest="path", help="The local root to work from", default="/tmp")</span><br><span style="color: hsl(120, 100%, 40%);">+    parser.add_argument("-s", "--start-version", dest="start", help="The version to start from", required=True)</span><br><span style="color: hsl(120, 100%, 40%);">+    parser.add_argument("-e", "--end-version", dest="end", help="The version to end on", required=True)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    args = parser.parse_args()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    sce = StagingChangesExtractor(ast_path=args.path, start_version=args.start, end_version=args.end)</span><br><span style="color: hsl(120, 100%, 40%);">+    ret = sce.run()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if ret == 0:</span><br><span style="color: hsl(120, 100%, 40%);">+        print "Done!"</span><br><span style="color: hsl(120, 100%, 40%);">+    else:</span><br><span style="color: hsl(120, 100%, 40%);">+        print "Uh oh - omething went wrong!"</span><br><span>diff --git a/staging_changes.py b/staging_changes.py</span><br><span>new file mode 100644</span><br><span>index 0000000..876bc2f</span><br><span>--- /dev/null</span><br><span>+++ b/staging_changes.py</span><br><span>@@ -0,0 +1,190 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#!/usr/bin/env python</span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+Used to extract information from <asterisk_home>/doc/<file>-staging/</span><br><span style="color: hsl(120, 100%, 40%);">+and add that information to <asterisk_home>/<file></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Ben Ford <bford@digium.com></span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import logging</span><br><span style="color: hsl(120, 100%, 40%);">+import os</span><br><span style="color: hsl(120, 100%, 40%);">+import fileinput</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+LOGGER = logging.getLogger(__name__)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+MODES = ["CHANGES", "UPGRADE"]</span><br><span style="color: hsl(120, 100%, 40%);">+FUNCTIONALITY_SEPARATOR_DASH_COUNT = 78</span><br><span style="color: hsl(120, 100%, 40%);">+CATEGORY_SEPARATOR_DASH_COUNT = 18</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class StagingChangesExtractor:</span><br><span style="color: hsl(120, 100%, 40%);">+    '''</span><br><span style="color: hsl(120, 100%, 40%);">+    Holds all the information needed to update the target files.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Currently there is support for CHANGES and UPGRADE.txt</span><br><span style="color: hsl(120, 100%, 40%);">+    '''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self, ast_path, start_version, end_version):</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        Initializer</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_path        The location of the Asterisk directory we are working with</span><br><span style="color: hsl(120, 100%, 40%);">+        start_version   The version we are starting from</span><br><span style="color: hsl(120, 100%, 40%);">+        end_version     The version we are ending on</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        if ast_path is None:</span><br><span style="color: hsl(120, 100%, 40%);">+            raise Exception("ast_path cannot be NULL")</span><br><span style="color: hsl(120, 100%, 40%);">+        if start_version is None:</span><br><span style="color: hsl(120, 100%, 40%);">+            raise Exception("start_version cannot be NULL")</span><br><span style="color: hsl(120, 100%, 40%);">+        if end_version is None:</span><br><span style="color: hsl(120, 100%, 40%);">+            raise Exception("end_version cannot be NULL")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        self.data = dict()</span><br><span style="color: hsl(120, 100%, 40%);">+        # If the path doesn't end with '/', go ahead and add one for get_staging_changes</span><br><span style="color: hsl(120, 100%, 40%);">+        if ast_path.endswith('/') == False:</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_path += '/'</span><br><span style="color: hsl(120, 100%, 40%);">+        self.ast_path = ast_path</span><br><span style="color: hsl(120, 100%, 40%);">+        self.start_version = start_version</span><br><span style="color: hsl(120, 100%, 40%);">+        self.end_version = end_version</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def gen_separator(self, count):</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        Generate a number of dashes to be used as a separator</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        count       The number of dashes to generate</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        returns     A string with <count> dash(es)</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        ret = ""</span><br><span style="color: hsl(120, 100%, 40%);">+        for num in range(count):</span><br><span style="color: hsl(120, 100%, 40%);">+            ret += "-"</span><br><span style="color: hsl(120, 100%, 40%);">+        return ret</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def gen_header(self, mode):</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        Generate the header that will precede data in the target file</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        if mode is "CHANGES":</span><br><span style="color: hsl(120, 100%, 40%);">+            header = "--- Functionality changes from Asterisk {0} to Asterisk {1} ".format(self.start_version, self.end_version)</span><br><span style="color: hsl(120, 100%, 40%);">+            remaining = FUNCTIONALITY_SEPARATOR_DASH_COUNT - len(header)</span><br><span style="color: hsl(120, 100%, 40%);">+            header += self.gen_separator(remaining)</span><br><span style="color: hsl(120, 100%, 40%);">+            separator = self.gen_separator(FUNCTIONALITY_SEPARATOR_DASH_COUNT)</span><br><span style="color: hsl(120, 100%, 40%);">+            header = separator + "\n" + header + "\n" + separator + "\n\n"</span><br><span style="color: hsl(120, 100%, 40%);">+        elif mode is "UPGRADE":</span><br><span style="color: hsl(120, 100%, 40%);">+            header = "From {0} to {1}:\n\n".format(self.start_version, self.end_version)</span><br><span style="color: hsl(120, 100%, 40%);">+        else:</span><br><span style="color: hsl(120, 100%, 40%);">+            return None</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return header</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def get_staging_changes(self, mode):</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        Retrieve changes from <self.ast_path>/doc/<mode>-staging/</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+        returns     0 on success</span><br><span style="color: hsl(120, 100%, 40%);">+        returns     -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        if mode is not "CHANGES" and mode is not "UPGRADE":</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        staging_path = "{0}/doc/{1}-staging".format(self.ast_path, mode)</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            for filename in os.listdir(staging_path):</span><br><span style="color: hsl(120, 100%, 40%);">+                if not os.path.isfile(staging_path + "/" + filename) or filename == "README":</span><br><span style="color: hsl(120, 100%, 40%);">+                    continue</span><br><span style="color: hsl(120, 100%, 40%);">+                with open(staging_path + "/" + filename, 'r') as f:</span><br><span style="color: hsl(120, 100%, 40%);">+                    subject = ""</span><br><span style="color: hsl(120, 100%, 40%);">+                    line = f.readline()</span><br><span style="color: hsl(120, 100%, 40%);">+                    while line != "":</span><br><span style="color: hsl(120, 100%, 40%);">+                        # Get the subject</span><br><span style="color: hsl(120, 100%, 40%);">+                        if line.startswith("Subject:"):</span><br><span style="color: hsl(120, 100%, 40%);">+                            if subject != "":</span><br><span style="color: hsl(120, 100%, 40%);">+                                # In the case of trailing space of any kind, remove it. For example,</span><br><span style="color: hsl(120, 100%, 40%);">+                                # double new line characters make the format mess up.</span><br><span style="color: hsl(120, 100%, 40%);">+                                self.data.update({subject: self.data[subject].rstrip() + "\n"})</span><br><span style="color: hsl(120, 100%, 40%);">+                            subject = line.split("Subject:")[1].lstrip()</span><br><span style="color: hsl(120, 100%, 40%);">+                            if subject not in self.data:</span><br><span style="color: hsl(120, 100%, 40%);">+                                self.data.update({subject: "{0}{1}\n".format(subject, self.gen_separator(CATEGORY_SEPARATOR_DASH_COUNT))})</span><br><span style="color: hsl(120, 100%, 40%);">+                            else:</span><br><span style="color: hsl(120, 100%, 40%);">+                                self.data.update({subject: self.data[subject] + "\n"})</span><br><span style="color: hsl(120, 100%, 40%);">+                            f.readline()</span><br><span style="color: hsl(120, 100%, 40%);">+                            line = f.readline()</span><br><span style="color: hsl(120, 100%, 40%);">+                            self.data.update({subject: self.data[subject] + " * " + line})</span><br><span style="color: hsl(120, 100%, 40%);">+                        elif line == "\n":</span><br><span style="color: hsl(120, 100%, 40%);">+                            # This is a special case because if there is an empty line separating some</span><br><span style="color: hsl(120, 100%, 40%);">+                            # text, we don't want to add 3 spaces and then a new line.</span><br><span style="color: hsl(120, 100%, 40%);">+                            self.data.update({subject: self.data[subject] + "\n"})</span><br><span style="color: hsl(120, 100%, 40%);">+                        else:</span><br><span style="color: hsl(120, 100%, 40%);">+                            self.data.update({subject: self.data[subject] + "   " + line})</span><br><span style="color: hsl(120, 100%, 40%);">+                        line = f.readline()</span><br><span style="color: hsl(120, 100%, 40%);">+                # Clean up the staging directory as we cycle through the files</span><br><span style="color: hsl(120, 100%, 40%);">+                os.remove(os.path.join(staging_path, filename))</span><br><span style="color: hsl(120, 100%, 40%);">+        except:</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGGER.debug("Could not extract data from {0}".format(staging_path))</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def add_staging_changes(self, mode):</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        Add the changes retrieved to <self.ast_path/<mode>(.txt)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        returns     0 on success</span><br><span style="color: hsl(120, 100%, 40%);">+        returns     -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        if mode is not "CHANGES" and mode is not "UPGRADE":</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if bool(self.data) is False:</span><br><span style="color: hsl(120, 100%, 40%);">+            # There was no data to retrieve during get_staging_changes</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        header = self.gen_header(mode)</span><br><span style="color: hsl(120, 100%, 40%);">+        if header is None:</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        file_path = "{0}/{1}".format(self.ast_path, mode)</span><br><span style="color: hsl(120, 100%, 40%);">+        if mode is "UPGRADE":</span><br><span style="color: hsl(120, 100%, 40%);">+            file_path += ".txt"</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            insert = 0</span><br><span style="color: hsl(120, 100%, 40%);">+            for line in fileinput.FileInput(file_path, inplace = 1):</span><br><span style="color: hsl(120, 100%, 40%);">+                if insert is 0 and line in ["\n", "\r\n"]:</span><br><span style="color: hsl(120, 100%, 40%);">+                    insert = 1</span><br><span style="color: hsl(120, 100%, 40%);">+                    continue</span><br><span style="color: hsl(120, 100%, 40%);">+                if insert is 1:</span><br><span style="color: hsl(120, 100%, 40%);">+                    for entry in self.data:</span><br><span style="color: hsl(120, 100%, 40%);">+                        line = line.replace(line, self.data[entry] + "\n" + line)</span><br><span style="color: hsl(120, 100%, 40%);">+                    line = line.replace(line, "\n" + header + line)</span><br><span style="color: hsl(120, 100%, 40%);">+                    insert = 2</span><br><span style="color: hsl(120, 100%, 40%);">+                print line,</span><br><span style="color: hsl(120, 100%, 40%);">+        except:</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGGER.debug("Could not add data to {0}".format(file_path))</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def run(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+        Put everything together and run it</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        returns     0 on success</span><br><span style="color: hsl(120, 100%, 40%);">+        returns     -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+        '''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        for mode in MODES:</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGGER.debug("Extracting changes for {0}".format(mode))</span><br><span style="color: hsl(120, 100%, 40%);">+            self.data.clear()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            ret = self.get_staging_changes(mode)</span><br><span style="color: hsl(120, 100%, 40%);">+            if ret is not 0:</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGGER.debug("Failed during {0} get_staging_changes step - aborting "</span><br><span style="color: hsl(120, 100%, 40%);">+                             "(working directory probably needs to be reset!!!)".format(mode))</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            ret = self.add_staging_changes(mode)</span><br><span style="color: hsl(120, 100%, 40%);">+            if ret is not 0:</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGGER.debug("Failed during {0} add_staging_changes step - aborting "</span><br><span style="color: hsl(120, 100%, 40%);">+                             "(working directory probably needs to be reset!!!)".format(mode))</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10941">change 10941</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10941"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: repotools </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I6dc084afedaeecaf36aaec66c3cf6a5a8ed4ef3c </div>
<div style="display:none"> Gerrit-Change-Number: 10941 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Benjamin Keith Ford <bford@digium.com> </div>