From 3ec0deb880c9b0c61bc3b5196c9c1a47ae81d018 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Tue, 21 Mar 2017 11:37:03 +0100 Subject: Move to Python3 Most of the work was done by the 2to3 tool, with a few manual fixes on top. We now get a lot of resource warnings about /dev/null not being closed, but fixing those seems beyond the scope of this commit, since the same problem existed in python2 as well (it just didn't complain about it). Change-Id: Ie9f6cf7501a71aceb309e299b113f5bca7148474 --- linaropy/colors.py | 3 +- linaropy/git/clone.py | 10 +- linaropy/git/gitrepo.py | 38 +++---- linaropy/git/workdir.py | 20 +++- linaropy/git/worktree.py | 18 ++-- linaropy/proj.py | 27 +++-- linaropy/rn/linaroseries.py | 1 + linaropy/rn/rngen.py | 129 ++++++++++++++--------- linaropy/rn/rnseries.py | 47 +++++---- linaropy/rn/template.py | 13 ++- linaropy/rninput.py | 19 +++- linaropy/series.py | 242 ++++++++++++++++++++++---------------------- linaropy/vers.py | 43 ++++---- rn.py | 40 +++++--- 14 files changed, 364 insertions(+), 286 deletions(-) diff --git a/linaropy/colors.py b/linaropy/colors.py index 33d8d16..abca0f4 100644 --- a/linaropy/colors.py +++ b/linaropy/colors.py @@ -5,9 +5,10 @@ GREEN = "\033[32m" BOLD = "\033[1m" ITALIC = "\033[3m" + def print_info(pstr): """ This precedes pstr with two blue asterisks and a space. The input string parameter, pstr, may also contain color codes from linaropy/colors.py embedded in the string. This function always returns the terminal to no-color text after printing pstr. """ - print BLUE + "** " + NC + pstr + NC + print(BLUE + "** " + NC + pstr + NC) diff --git a/linaropy/git/clone.py b/linaropy/git/clone.py index c821df0..ef5842f 100644 --- a/linaropy/git/clone.py +++ b/linaropy/git/clone.py @@ -13,7 +13,7 @@ from stat import * from ..proj import Proj from ..cd import cd -from gitrepo import GitRepo +from linaropy.git.gitrepo import GitRepo import time @@ -29,7 +29,7 @@ class Clone(GitRepo): # Clone a new repo from the remote if clonedir is None or (isinstance( - clonedir, basestring) and clonedir == ""): + clonedir, str) and clonedir == ""): if remote == "" or remote is None: raise TypeError( 'Clone input parameter \'remote\' can not be empty') @@ -55,7 +55,7 @@ class Clone(GitRepo): # Reuse an existing git clone directory else: - if not isinstance(clonedir, basestring): + if not isinstance(clonedir, str): raise TypeError('clonedir must be of type basestring') elif not os.path.isdir(clonedir): raise EnvironmentError( @@ -124,12 +124,12 @@ class TestClone(unittest.TestCase): cls.rnclone = Clone( cls.proj, - remote=u'http://git.linaro.org/toolchain/release-notes.git') + remote='http://git.linaro.org/toolchain/release-notes.git') # OFFLINE: # cls.rnclone=Clone(cls.proj,remote=u'/var/run/media/ryanarn/sidecar/reldir/release-notes') cls.startbranch = cls.rnclone.getbranch() - cls.rtremote = u'http://git.linaro.org/toolchain/tcwg-release-tools.git' + cls.rtremote = 'http://git.linaro.org/toolchain/tcwg-release-tools.git' # OFFLINE: # cls.rtremote=u'/var/run/media/ryanarn/sidecar/releases/tcwg-release-tools' diff --git a/linaropy/git/gitrepo.py b/linaropy/git/gitrepo.py index 5c72f83..78fcefb 100644 --- a/linaropy/git/gitrepo.py +++ b/linaropy/git/gitrepo.py @@ -26,7 +26,7 @@ from contextlib import contextmanager class GitRepo(object): def __init__(self, proj): - self.repodir = u"" + self.repodir = "" if isinstance(proj, Proj): self.proj = proj else: @@ -72,7 +72,7 @@ class GitRepo(object): "HEAD").stdout.rstrip() except ErrorReturnCode: raise EnvironmentError("Unable to get the current branch") - return branch + return str(branch, 'utf-8') # TODO make this a bit more sophisticated because the user might not be # using 'origin' as their remote name. @@ -87,7 +87,7 @@ class GitRepo(object): with cd(self.repodir): # The stashid will remain empty if there were no changes in the # directory to stash. - stashid = u"" + stashid = "" try: self.prevbranch = git( @@ -99,7 +99,7 @@ class GitRepo(object): # TODO: do we want to do a blanket git add *? stashid = git("stash", "create").stdout.rstrip() # If there's no stash then there's no reason to save. - if stashid != "": + if stashid: git("stash", "save") except ErrorReturnCode: raise EnvironmentError("Unable to get the current branch") @@ -125,7 +125,7 @@ class GitRepo(object): git("checkout", self.prevbranch) # If there's no stashid then there were no files stashed, # so don't stash apply. - if stashid != "": + if stashid: git("stash", "apply", stashid) except ErrorReturnCode as exc: raise EnvironmentError( @@ -183,13 +183,13 @@ class GitRepo(object): return True # TODO: Write unit tests for this. - def print_log(self, numcommits,oneline=False): + def print_log(self, numcommits, oneline=False): try: with cd(self.repodir): if oneline: - print git("log", "--oneline", "-n %d" % numcommits) + print(git("log", "--oneline", "-n %d" % numcommits)) else: - print git("log", "-n %d" % numcommits) + print(git("log", "-n %d" % numcommits)) except ErrorReturnCode: raise EnvironmentError("Unable to git log -n %d" % numcommits) @@ -200,13 +200,13 @@ class GitRepo(object): with cd(self.repodir): if versus is not None: return git("rev-list", "%s..%s" % (versus, - branch)).stdout.rstrip() + branch)).stdout.rstrip() else: return git("rev-list", branch, "--max-count=%d" % - numcommits).stdout.rstrip() + numcommits).stdout.rstrip() except ErrorReturnCode as exc: raise EnvironmentError("Unable to git rev-list because: %s" % - (numcommits, str(exc))) + (numcommits, str(exc))) # TODO: Does this need to 'cd' first? def edit(self, toedit): @@ -275,7 +275,7 @@ class TestGitRepo(unittest.TestCase): def __init__(self, proj): super(TestGitRepo.DerivedGitRepo, self).__init__(proj) - self.remote = u'http://git.linaro.org/toolchain/release-notes.git' + self.remote = 'http://git.linaro.org/toolchain/release-notes.git' dgr_dirname = "release-notes" self.repodir = self.proj.projdir + "/" + dgr_dirname try: @@ -326,7 +326,7 @@ class TestGitRepo(unittest.TestCase): except ErrorReturnCode as exc: raise EnvironmentError( "Unable to checkout -b %s %s" % (branch, track)) - self.assertEquals(self.dgr.getbranch(), "master_test") + self.assertEqual(self.dgr.getbranch(), "master_test") # TODO: Test checkoutbranch with various combinations of polluted # directories. @@ -377,8 +377,8 @@ class TestGitRepo(unittest.TestCase): with self.assertRaises(EnvironmentError) as context: self.dgr.delete_branch(branchToDelete, False) - self.assertRegexpMatches(str(context.exception), - "Unable to delete branch:") + self.assertRegex(str(context.exception), + "Unable to delete branch:") # Make sure the branch still exists (i.e. this doesn't throw an # exception) @@ -417,8 +417,8 @@ class TestGitRepo(unittest.TestCase): with self.assertRaises(EnvironmentError) as context: self.dgr.delete_branch(currentBranch, False) - self.assertRegexpMatches(str(context.exception), - "Unable to delete branch:") + self.assertRegex(str(context.exception), + "Unable to delete branch:") # Make sure the branch still exists (i.e. this doesn't throw an # exception) @@ -437,8 +437,8 @@ class TestGitRepo(unittest.TestCase): with self.assertRaises(EnvironmentError) as context: self.dgr.delete_branch(nonexistentBranch, False) - self.assertRegexpMatches(str(context.exception), - "Unable to delete branch:") + self.assertRegex(str(context.exception), + "Unable to delete branch:") if __name__ == '__main__': # logging.basicConfig(level="INFO") diff --git a/linaropy/git/workdir.py b/linaropy/git/workdir.py index 8de4a81..7b769f9 100644 --- a/linaropy/git/workdir.py +++ b/linaropy/git/workdir.py @@ -7,9 +7,9 @@ import uuid from ..proj import Proj from ..cd import cd -from gitrepo import GitRepo +from .gitrepo import GitRepo -from clone import Clone +from .clone import Clone from sh import git from sh import git_new_workdir @@ -60,13 +60,23 @@ class Workdir(GitRepo): (workdir, track)) # TODO: Do we want to prevalidate that 'track' is a valid branch or tag? # If we don't this will just throw an exception. - git_new_workdir(clone.clonedir(), workdir, track, _err_to_out=True, _out="/dev/null") + git_new_workdir( + clone.clonedir(), + workdir, + track, + _err_to_out=True, + _out="/dev/null") else: logging.info( "Workdir(): Calling git new-workdir for workdir %s, tracking %s" % (workdir, "origin/HEAD")) # Always just checkout HEAD if the track is not specified. - git_new_workdir(clone.clonedir(), workdir, "origin/HEAD", _err_to_out=True, _out="/dev/null") + git_new_workdir( + clone.clonedir(), + workdir, + "origin/HEAD", + _err_to_out=True, + _out="/dev/null") except ErrorReturnCode as exc: # if 'workdir' is None @@ -110,7 +120,7 @@ class TestWorkdir(unittest.TestCase): # be nice to the git server. cls.rnclone = Clone( cls.proj, - remote=u'http://git.linaro.org/toolchain/release-notes.git') + remote='http://git.linaro.org/toolchain/release-notes.git') # OFFLINE: # cls.rnclone=Clone(cls.proj,remote=u'/var/run/media/ryanarn/sidecar/reldir/release-notes') diff --git a/linaropy/git/worktree.py b/linaropy/git/worktree.py index 7da0cf8..70c9623 100644 --- a/linaropy/git/worktree.py +++ b/linaropy/git/worktree.py @@ -7,9 +7,9 @@ import uuid from ..proj import Proj from ..cd import cd -from gitrepo import GitRepo +from .gitrepo import GitRepo -from clone import Clone +from .clone import Clone from sh import git, ErrorReturnCode, rm @@ -657,10 +657,10 @@ class TestWorktree(unittest.TestCase): with self.assertRaises(EnvironmentError) as context: self.worktree.clean(True) - self.assertRegexpMatches(str(context.exception), - "branch deletion failed:") - self.assertRegexpMatches(str(context.exception), - "not fully merged") + self.assertRegex(str(context.exception), + "branch deletion failed:") + self.assertRegex(str(context.exception), + "not fully merged") self.assertFalse(os.path.isdir(worktreePath)) @@ -726,9 +726,9 @@ class TestWorktree(unittest.TestCase): with self.assertRaises(EnvironmentError) as context: self.worktree.clean(False) - self.assertRegexpMatches(str(context.exception), - 'Worktree directory not found: %s' % - worktreePath) + self.assertRegex(str(context.exception), + 'Worktree directory not found: %s' % + worktreePath) if __name__ == '__main__': # logging.basicConfig(level="INFO") diff --git a/linaropy/proj.py b/linaropy/proj.py index b20d96b..aeff057 100644 --- a/linaropy/proj.py +++ b/linaropy/proj.py @@ -40,19 +40,24 @@ class Proj(object): """ if existing_projdir: - if not isinstance (existing_projdir,basestring): + if not isinstance(existing_projdir, str): raise TypeError("The 'existing_projdir' must be a string.") if prefix: - logging.warning("'existing_proj' specified so 'prefix'=%s ignored" % prefix) + logging.warning( + "'existing_proj' specified so 'prefix'=%s ignored" % + prefix) if not persist: - logging.warning("'existing_proj' specified, 'persist' forced to True.") + logging.warning( + "'existing_proj' specified, 'persist' forced to True.") if not os.path.isdir(existing_projdir): - raise IOError('existing_projdir %s not found.' % existing_projdir) + raise IOError( + 'existing_projdir %s not found.' % + existing_projdir) else: - self.persist= True - self.longevity= "persistent" + self.persist = True + self.longevity = "persistent" self.projdir = os.path.abspath(existing_projdir) else: # This allows string or bool inputs. @@ -63,10 +68,10 @@ class Proj(object): self.persist = False self.longevity = "temporary" - self.projdir = unicode(tempfile.mkdtemp(prefix=prefix), "utf-8") + self.projdir = str(tempfile.mkdtemp(prefix=prefix)) logging.info("Using %s as %s project directory." % - (self.projdir, self.longevity)) + (self.projdir, self.longevity)) def cleanup(self): """Perform cleanup (removal) of the proj directory if Proj persist==False.""" @@ -79,6 +84,7 @@ class Proj(object): else: logging.info("Project dir %s will persist" % self.projdir) + class TestProj(unittest.TestCase): """Test the Proj class.""" @@ -152,6 +158,7 @@ class TestProj(unittest.TestCase): if self.persistdir != "/" and self.persistdir != "/home": rm("-rf", "--preserve-root", self.persistdir) + class TestExisting_Projdir(unittest.TestCase): """Test the Proj class when existing_projdir is set.""" @@ -177,7 +184,9 @@ class TestExisting_Projdir(unittest.TestCase): # Verify that prefix is properly ignored when reusing a proj dir. def test_existing_projdir(self): - self.proj = Proj(prefix="shouldntmatch", existing_projdir=self.reuse_proj.projdir) + self.proj = Proj( + prefix="shouldntmatch", + existing_projdir=self.reuse_proj.projdir) self.assertFalse(self.proj.projdir.startswith("shouldntmatch")) self.proj.cleanup() diff --git a/linaropy/rn/linaroseries.py b/linaropy/rn/linaroseries.py index 5c7f2ab..97027ac 100644 --- a/linaropy/rn/linaroseries.py +++ b/linaropy/rn/linaroseries.py @@ -182,6 +182,7 @@ class LinaroSeries(Series): return prev_release + def linaro_series_from_tag(tag=None): series = series_from_tag(tag) linaroseries = LinaroSeries( diff --git a/linaropy/rn/rngen.py b/linaropy/rn/rngen.py index 47d63f8..7daae9e 100644 --- a/linaropy/rn/rngen.py +++ b/linaropy/rn/rngen.py @@ -4,8 +4,6 @@ import csv import sys import getopt -reload(sys) -sys.setdefaultencoding('utf8') # For fileIO import os.path @@ -20,27 +18,30 @@ from bs4 import BeautifulSoup # Jinja2 is the templating engine. from jinja2 import Template, FileSystemLoader, Environment -from custom_wordwrap import do_customwordwrap +from .custom_wordwrap import do_customwordwrap -from cStringIO import StringIO +from io import StringIO from datetime import datetime from shutil import copyfile # To test if a remote file exists. -import urllib2 +import urllib.request +import urllib.error +import urllib.parse from ..series import Series -from linaroseries import LinaroSeries -from rnseries import RNSeries -from gccclone import GCCClone +from .linaroseries import LinaroSeries +from .rnseries import RNSeries +from .gccclone import GCCClone from ..rninput import finput # Terminal color codes. from linaropy.colors import * + def get_gcc_version(gccclone): dct = {} (dct["major"], dct["minor"], dct["revision"] @@ -52,15 +53,15 @@ def rngen(rn_series, gccclone, history): trackseries = rn_series.track_series nextseries = rn_series.next_series - print "toNext: " + nextseries.branchname() - print "toNext: " + format(nextseries, '%N/%d') + print("toNext: " + nextseries.branchname()) + print("toNext: " + format(nextseries, '%N/%d')) # TODO: What if 'track' is not a snapshot branch? To do this right we'd # probably have to preserve basedon information in the release notes # repository as a yaml file. basedon = 'http://snapshots.linaro.org/components/toolchain/gcc-linaro/' basedon = basedon + trackseries.get_dir() - print "basedon: " + basedon + print("basedon: " + basedon) basis_url = basedon # print 'gccbaseversion is ' + gccclone.get_base_version() @@ -68,8 +69,8 @@ def rngen(rn_series, gccclone, history): # (dct["major"],dct["minor"],dct["revision"]) = gccclone.get_base_version().split(".") # print 'fsf revision is ' + gccclone.get_fsf_revision() ver = get_gcc_version(gccclone) - print 'gcc major ' + ver['major'] - print 'gcc minor ' + ver['minor'] + print('gcc major ' + ver['major']) + print('gcc minor ' + ver['minor']) fsf = gccclone.get_fsf_revision() @@ -78,22 +79,22 @@ def rngen(rn_series, gccclone, history): # incremented per-release. # TODO: read stable and maintenance information from a config file. if int(ver['major']) <= 4: - gcc_version_path = u'' + ver['major'] + '.' + ver['minor'] + gcc_version_path = '' + ver['major'] + '.' + ver['minor'] stab_maint = 'Maintenance' else: gcc_version_path = ver['major'] stab_maint = 'Stable' - print "This is a %s RNSeries for GCC version %s" % (stab_maint, - gcc_version_path) + print("This is a %s RNSeries for GCC version %s" % (stab_maint, + gcc_version_path)) - print "Using the following .csv file: " + history + print("Using the following .csv file: " + history) #month_year=format(nextseries, '%D') month_year = nextseries.date - outfile = u'GCC-' + ver['major'] + u'.' + \ - ver['minor'] + u'-' + month_year.strftime("%Y.%m") + outfile = 'GCC-' + ver['major'] + '.' + \ + ver['minor'] + '-' + month_year.strftime("%Y.%m") # if spin != "": # outfile=outfile + u'-' + spin @@ -101,7 +102,7 @@ def rngen(rn_series, gccclone, history): # if rc != "": # outfile=outfile + u'-rc' + rc outfile = outfile + str(nextseries.spin) + str(nextseries.rc) - print "outfile: " + outfile + print("outfile: " + outfile) with open(history, mode='r') as backports: backports.seek(0) @@ -136,13 +137,13 @@ def rngen(rn_series, gccclone, history): # will contain erroneous information. url = urllib2 try: - ret = urllib2.urlopen(basis_url) + ret = urllib.request.urlopen(basis_url) except url.URLError as e: - print "%s does not exist!" % basis_url + print("%s does not exist!" % basis_url) exit(1) # TODO verify that the basis_url is a valid url and warn if not. - basis = u'' + basis = '' basis_ver = basis_url.strip("/") basis_ver = basis_ver.rsplit("/", 1)[1] if basis_url.find("releases") == 1: @@ -155,14 +156,16 @@ def rngen(rn_series, gccclone, history): release_string = "Linaro GCC %s.%s-%s.%s %s" % (ver['major'], ver[ 'minor'], month_year.strftime("%Y"), month_year.strftime("%m"), release_type) - print "The release notes for this %s will be generated based on: %s" % (release_string, basis) + print( + "The release notes for this %s will be generated based on: %s" % + (release_string, basis)) # Get ready to do the rendering of the jinja2 templates into .textile # format. # relative path to the README.textile templates. - src_readme_path = u'/components/toolchain/gcc-linaro/%s/README.textile' % gcc_version_path - bin_readme_path = u'/components/toolchain/binaries/README.textile' + src_readme_path = '/components/toolchain/gcc-linaro/%s/README.textile' % gcc_version_path + bin_readme_path = '/components/toolchain/binaries/README.textile' # absolute path to README.textile templates. template_src_readme = template_dir + src_readme_path @@ -170,8 +173,8 @@ def rngen(rn_series, gccclone, history): # relative path to the README.textile.series templates. # Note, the src templates don't have an extends (.series) file. - src_extends_path = u'/components/toolchain/gcc-linaro/%s/README.textile' % gcc_version_path - bin_extends_path = u'/components/toolchain/binaries/README.textile.series' + src_extends_path = '/components/toolchain/gcc-linaro/%s/README.textile' % gcc_version_path + bin_extends_path = '/components/toolchain/binaries/README.textile.series' # absolute path to README.textile.series template overrides. These are # what are passed to the jinja2 rendering engine because they might @@ -208,8 +211,8 @@ def rngen(rn_series, gccclone, history): # Generate the toolchain GCC source archive release notes. source_textile_rendering = source_archive_template.render( backports=backportsDict, - GCC_base_version=ver['major'] + u'.' + - ver['minor'] + u'.' + ver['revision'], + GCC_base_version=ver['major'] + '.' + + ver['minor'] + '.' + ver['revision'], FSF_rev=fsf, basis=basis, basis_url=basis_url, @@ -225,22 +228,32 @@ def rngen(rn_series, gccclone, history): source_textile_rendering = source_textile_rendering.encode('utf-8') - out_source = u'' + outfile - out_binary = u'Linaro-' + outfile + out_source = '' + outfile + out_binary = 'Linaro-' + outfile try: - with open(out_source + u'.textile', 'w') as f: + with open(out_source + '.textile', 'w') as f: f.write(source_textile_rendering) - print 'Wrote textile rendering to file %s' % os.getcwd() + u'/' + out_source + u'.textile' + print( + 'Wrote textile rendering to file %s' % + os.getcwd() + + '/' + + out_source + + '.textile') except IOError as e: sys.exit('Error rendering textile source archive release notes.') source_html_rendering = textile.textile(source_textile_rendering) try: - with open(out_source + u'.html', 'w') as f: + with open(out_source + '.html', 'w') as f: f.write(source_html_rendering) - print 'Wrote html rendering to file %s' % os.getcwd() + u'/' + out_source + u'.html' + print( + 'Wrote html rendering to file %s' % + os.getcwd() + + '/' + + out_source + + '.html') except IOError as e: sys.exit('Error rendering html release notes.') @@ -258,18 +271,28 @@ def rngen(rn_series, gccclone, history): binary_textile_rendering = binary_textile_rendering.encode('utf-8') try: - with open(out_binary + u'.textile', 'w') as f: + with open(out_binary + '.textile', 'w') as f: f.write(binary_textile_rendering) - print 'Wrote textile rendering to file %s' % os.getcwd() + u'/' + out_binary + u'.textile' + print( + 'Wrote textile rendering to file %s' % + os.getcwd() + + '/' + + out_binary + + '.textile') except IOError as e: sys.exit('Error rendering textile binary archive release notes.') binary_html_rendering = textile.textile(binary_textile_rendering) try: - with open(out_binary + u'.html', 'w') as f: + with open(out_binary + '.html', 'w') as f: f.write(binary_html_rendering) - print 'Wrote html rendering to file %s' % os.getcwd() + u'/' + out_binary + u'.html' + print( + 'Wrote html rendering to file %s' % + os.getcwd() + + '/' + + out_binary + + '.html') except IOError as e: sys.exit('Error rendering html release notes.') @@ -286,11 +309,13 @@ def rngen(rn_series, gccclone, history): snap_rc_release=release_type) announce_rendering = announce_rendering.encode('utf-8') - announce_file = u'announce-' + out_binary + u'.txt' + announce_file = 'announce-' + out_binary + '.txt' try: with open(announce_file, 'w') as f: f.write(announce_rendering) - print 'Wrote text rendering to file %s' % os.getcwd() + u'/' + announce_file + print( + 'Wrote text rendering to file %s' % + os.getcwd() + '/' + announce_file) except IOError as e: sys.exit('Error rendering text announce message.') @@ -299,18 +324,28 @@ def rngen(rn_series, gccclone, history): # WARNING: This must be done AFTER you generate the announce message # because it uses the same README.textile template as the textile rendered # release notes. - copyfile(out_binary + u'.textile', bin_readme) - print 'Wrote generated file ' + out_binary + u'.textile' + " to " + bin_readme + copyfile(out_binary + '.textile', bin_readme) + print( + 'Wrote generated file ' + + out_binary + + '.textile' + + " to " + + bin_readme) # Copy the generated .textile file over the # readme_series_dir/README.textile template file. - copyfile(out_source + u'.textile', src_readme) - print 'Wrote generated file ' + out_source + u'.textile' + " to " + src_readme + copyfile(out_source + '.textile', src_readme) + print( + 'Wrote generated file ' + + out_source + + '.textile' + + " to " + + src_readme) rn_series.rn_series.add(bin_readme) rn_series.rn_series.add(src_readme) print_info("Generated release notes for %s. Please add a commit message." - % nextseries.label()) + % nextseries.label()) rn_series.rn_series.commit( "Generated Release Notes for %s." % nextseries.label()) rn_series.rn_series.print_log(1) diff --git a/linaropy/rn/rnseries.py b/linaropy/rn/rnseries.py index 6528ff8..c590eb1 100644 --- a/linaropy/rn/rnseries.py +++ b/linaropy/rn/rnseries.py @@ -2,7 +2,6 @@ import unittest import logging import os -from sh import ls from shutil import copyfile from ..proj import Proj @@ -10,9 +9,9 @@ from ..cd import cd from ..git.clone import Clone from ..git.workdir import Workdir from ..series import Series -from linaroseries import LinaroSeries -from linaroseries import linaroSeriesFromBranchname -from template import RNTemplate +from .linaroseries import LinaroSeries +from .linaroseries import linaroSeriesFromBranchname +from .template import RNTemplate from ..rninput import yninput from ..colors import * @@ -25,7 +24,7 @@ from ..colors import * class RNSeries(object): # rnremote=u'http://git.linaro.org/toolchain/release-notes.git' # use ssh:// so that we can push to the remote. - rnremote = u'ssh://git@git.linaro.org/toolchain/release-notes.git' + rnremote = 'ssh://git@git.linaro.org/toolchain/release-notes.git' _series = 'components/toolchain/binaries/README.textile.series' # @rnrepo - path to the existing releases notes repository if there is one. # If there isn't one a new one will be cloned. @@ -140,7 +139,9 @@ class RNSeries(object): remote_track = self.rn_clone.remote_branchname( self.track_series.branchname()) if not self.rn_series: - logging.info("Looking for branch %s" % self.track_series.branchname()) + logging.info( + "Looking for branch %s" % + self.track_series.branchname()) # The -rc1 candidate in an RNSeries will always track a snapshot # (per the rules in toNextCandidate()) and snapshots don't have @@ -161,28 +162,30 @@ class RNSeries(object): # We look to see if there is a previous release in the series # and if we don't find one we derive from the template. - found_previous=None + found_previous = None prev_release = self.next_series # Look two years back because that's the length of a supported # release. next_minor = self.next_series.package.version.minor - for x in xrange(1,25): + for x in range(1, 25): # Search for the nearest previous release. We need to # iterate through the minor variations blindly # (unfortunately) because the release process doesn't follow # a strict schedule with regard to date and minor number. - prev_release=prev_release.toPreviousMonthsRelease() + prev_release = prev_release.toPreviousMonthsRelease() while True: try: logging.info("looking for previous release branch " - "'%s'" % prev_release.branchname()) + "'%s'" % prev_release.branchname()) if self.rn_clone.remote_branch_exists( prev_release.branchname()): - logging.info ("previous release branch " - "'%s' exists." % prev_release.branchname()) - found_previous=prev_release + logging.info( + "previous release branch " + "'%s' exists." % + prev_release.branchname()) + found_previous = prev_release break prev_release.package.version.decrement_minor() @@ -194,10 +197,10 @@ class RNSeries(object): break # Restore the starting 'minor' for the next month. - prev_release.package.version.minor=next_minor + prev_release.package.version.minor = next_minor if not found_previous: - track=self.rn_template.getbranch() + track = self.rn_template.getbranch() print_info( "Deriving your release-notes from template branch " "%s%s%s%s" @@ -209,9 +212,10 @@ class RNSeries(object): # was a release respin. Keep incrementing until we discover # no new spins and then we can select the previously # identified spin. - logging.warning("Fixme: If the previous release had a spin " + logging.warning( + "Fixme: If the previous release had a spin " "we aren't yet able to detect it yet.") - track=found_previous.branchname() + track = found_previous.branchname() print_info( "Deriving your release-notes from release branch " "%s%s%s%s" @@ -224,7 +228,6 @@ class RNSeries(object): track=track, branchname=self.next_series.branchname()) - else: print_info( "Deriving your release-notes from branch %s%s%s%s" @@ -237,8 +240,8 @@ class RNSeries(object): track=remote_track, branchname=self.next_series.branchname()) - self.starting_commit=self.rn_series.rev_list( - self.rn_series.getbranch(),1) + self.starting_commit = self.rn_series.rev_list( + self.rn_series.getbranch(), 1) # TODO: Detect if the user changed the template README.textile or # template README.textile.series and ask if they want to merge the @@ -253,8 +256,8 @@ class RNSeries(object): # TODO: If there are multiple commits, the subsequent calls should use # commit --amend. Add an 'amend' parameter to GitRepo::commit(). - commits=self.rn_series.rev_list(self.rn_series.getbranch(), - versus=self.starting_commit) + commits = self.rn_series.rev_list(self.rn_series.getbranch(), + versus=self.starting_commit) return self.rn_series.commit( "Added NEWS items for %s." % self.next_series.branchname()) diff --git a/linaropy/rn/template.py b/linaropy/rn/template.py index 41cacb0..bfaaeb0 100644 --- a/linaropy/rn/template.py +++ b/linaropy/rn/template.py @@ -4,7 +4,6 @@ import os import sys import uuid -from sh import ls from ..proj import Proj from ..git.clone import Clone from ..git.workdir import Workdir @@ -41,13 +40,13 @@ class RNTemplate(Workdir): answer = yninput( "Would you like to update the Template README.textile file?", "N") if answer != "y": - print "The Template README.textile file has not been updated." + print("The Template README.textile file has not been updated.") return False editor = os.getenv('EDITOR') if not editor: editor = '/usr/bin/vim' - print "Edit the README.textile template fragment if changes are needed." + print("Edit the README.textile template fragment if changes are needed.") os.system(editor + ' ' + self.repodir + '/' + RNTemplate._readme) self.add(RNTemplate._readme) @@ -62,13 +61,13 @@ class RNTemplate(Workdir): answer = yninput( "Would you like to update the Template README.textile.series file?", "N") if answer != "y": - print "The Template README.textile.series file has not been updated." + print("The Template README.textile.series file has not been updated.") return False editor = os.getenv('EDITOR') if not editor: editor = '/usr/bin/vim' - print "Edit the README.textile.series template fragment if changes are needed." + print("Edit the README.textile.series template fragment if changes are needed.") os.system(editor + ' ' + self.repodir + '/' + RNTemplate._series) self.add(RNTemplate._series) @@ -96,7 +95,7 @@ class TestRNTemplate(unittest.TestCase): def test_getREADME(self): self.rnrepo = Clone( self.proj, - remote=u'http://git.linaro.org/toolchain/release-notes.git') + remote='http://git.linaro.org/toolchain/release-notes.git') self.rn_template = RNTemplate(self.proj, self.rnrepo) compare = self.proj.projdir + '/template/' + RNTemplate._readme self.assertEqual(self.rn_template.get_readme(), compare) @@ -105,7 +104,7 @@ class TestRNTemplate(unittest.TestCase): def test_getSERIES(self): self.rnrepo = Clone( self.proj, - remote=u'http://git.linaro.org/toolchain/release-notes.git') + remote='http://git.linaro.org/toolchain/release-notes.git') self.rn_template = RNTemplate(self.proj, self.rnrepo) compare = self.proj.projdir + '/template/' + RNTemplate._series self.assertEqual(self.rn_template.get_series(), compare) diff --git a/linaropy/rninput.py b/linaropy/rninput.py index 6f4e346..59dc974 100644 --- a/linaropy/rninput.py +++ b/linaropy/rninput.py @@ -1,7 +1,7 @@ # For fileIO import os.path -from colors import * +from .colors import * # @message - The question to display to the user. # @default - The default if is hit. @@ -21,9 +21,18 @@ def yninput(message, default="n", accept=['yes', 'y', 'no', 'n'], retry=True): default_msg = " [Y/n]: " while(1): - answer = raw_input(BLUE + "** " + NC + BOLD + message + default_msg + NC) or default.lower() + answer = input( + BLUE + + "** " + + NC + + BOLD + + message + + default_msg + + NC) or default.lower() if answer.lower() not in accept and retry: - print "'%s' is an invalid response. Please try again." % answer.lower() + print( + "'%s' is an invalid response. Please try again." % + answer.lower()) continue else: if answer.lower() == "yes" or answer.lower() == "y": @@ -35,8 +44,8 @@ def yninput(message, default="n", accept=['yes', 'y', 'no', 'n'], retry=True): def finput(message, orval): while(1): - answer = raw_input(BLUE + "** " + NC + BOLD + message + NC) or orval + answer = input(BLUE + "** " + NC + BOLD + message + NC) or orval if os.path.exists(answer) and os.path.isfile(answer): return answer - print "%s doesn't exist or isn't a regular file. Try again." % answer + print("%s doesn't exist or isn't a regular file. Try again." % answer) diff --git a/linaropy/series.py b/linaropy/series.py index 6c16a9f..e1d435d 100644 --- a/linaropy/series.py +++ b/linaropy/series.py @@ -6,11 +6,7 @@ import string from collections import OrderedDict import copy -from vers import Spin -from vers import Rc -from vers import Vendor -from vers import Package -from vers import packageFromStr +from linaropy.vers import Spin, Rc, Vendor, Package, packageFromStr from datetime import datetime from dateutil.relativedelta import relativedelta @@ -106,7 +102,7 @@ class Series(object): raise TypeError('Series requires an input package.') elif isinstance(package, Package): self.package = package - elif isinstance(package, basestring): + elif isinstance(package, str): self.package = packageFromStr(package) else: # There can't be a defaut package because it requires a version. @@ -171,7 +167,7 @@ class Series(object): self.fmt['%R'] = None # Fill in the values. - for key in self.fmt.iterkeys(): + for key in self.fmt.keys(): self.update_fmtdict(key) def update_fmtdict(self, key): @@ -183,7 +179,7 @@ class Series(object): elif key == '.%L': # Only prepend '.' if there's actually a series label. label = self.serieslabel() - self.fmt['.%L'] = string.replace(label, '-', '.') + self.fmt['.%L'] = str.replace(label, '-', '.') return elif key == '%L': self.fmt['%L'] = self.serieslabel().strip('-') @@ -217,7 +213,7 @@ class Series(object): self.fmt['-%S'] = str(self.spin) elif key == '.%S': spin = str(self.spin) - self.fmt['.%S'] = string.replace(spin, '-', '.') + self.fmt['.%S'] = str.replace(spin, '-', '.') elif key == '%S': self.fmt['%S'] = str(self.spin).strip('-') elif key == '-%R': @@ -225,7 +221,7 @@ class Series(object): self.fmt['-%R'] = str(self.rc) elif key == '.%R': rc = str(self.rc) - self.fmt['.%R'] = string.replace(rc, '-', '.') + self.fmt['.%R'] = str.replace(rc, '-', '.') elif key == '%R': self.fmt['%R'] = str(self.rc).strip('-') else: @@ -304,21 +300,21 @@ class Series(object): # Iterate across the dictionary and for each key found replace the key # with the contents of the fmt dictionary. ret = format_spec - for key in self.fmt.iterkeys(): + for key in self.fmt.keys(): if key in ret: # Update the relevant keys everytime through because the user # might have changed things. self.update_fmtdict(key) replac = self.fmt[key] - ret = string.replace(ret, key, replac) + ret = str.replace(ret, key, replac) return ret def serieslabel(self): # Only the 'snapshot-' is used in a label. if self.seriestype == Series.series.index("snapshot"): - return u'-' + Series.series[self.seriestype] + return '-' + Series.series[self.seriestype] else: - return u'' + return '' def shorttype(self): return Series.series[self.seriestype] @@ -334,8 +330,8 @@ class Series(object): def label(self): label = str(self.vendor) + self.serieslabel() + \ - u'-' + str(self.package) - label = label + u'-' + self.date.strftime("%Y.%m") + '-' + str(self.package) + label = label + '-' + self.date.strftime("%Y.%m") label = label + str(self.spin) + str(self.rc) return label @@ -344,21 +340,21 @@ class Series(object): def get_dir(self): dirstr = self.package.version.strfversion("%M%m") - dirstr = dirstr + u'-' + self.date.strftime("%Y.%m") + dirstr = dirstr + '-' + self.date.strftime("%Y.%m") dirstr = dirstr + str(self.spin) dirstr = dirstr + str(self.rc) return dirstr def get_server(self): - namespace = u'snapshots' + namespace = 'snapshots' if self.seriestype == Series.series.index("release"): - namespace = u'releases' + namespace = 'releases' return namespace def get_namespace(self): - namespace = u'releases' + namespace = 'releases' if self.seriestype == Series.series.index("snapshot"): - namespace = u'snapshots' + namespace = 'snapshots' return namespace # TODO: Document what a conformant branch name looks like. @@ -373,16 +369,16 @@ class Series(object): ------------ string represensting the branch name. """ - branchname = u'' + branchname = '' if self.seriestype == Series.series.index("snapshot"): - branchname = branchname + u'snapshots/' + branchname = branchname + 'snapshots/' else: - branchname = branchname + u'releases/' + branchname = branchname + 'releases/' branchname = branchname + self.vendor.lower() - branchname = branchname + u'-' + \ + branchname = branchname + '-' + \ self.package.version.strfversion("%M%m") - branchname = branchname + u'-' + self.date.strftime("%Y.%m") + branchname = branchname + '-' + self.date.strftime("%Y.%m") branchname = branchname + str(self.spin) branchname = branchname + str(self.rc) @@ -415,7 +411,7 @@ def series_from_branchname(branch=None): releases/[!-rcN] """ logging.info("Branch is %s." % branch) - if not isinstance(branch, basestring): + if not isinstance(branch, str): raise TypeError( 'series_from_branchname requires a basestring as input') @@ -443,7 +439,7 @@ def series_from_branchname(branch=None): # raise ValueError("Couldn't parse a namespace from input string") # This will catch where there's a namespace/ but no right hand value after # the /. - if seriesstr == u'': + if seriesstr == '': raise ValueError( "Couldn't parse a series from input string. Missing a branch name.") @@ -451,7 +447,7 @@ def series_from_branchname(branch=None): # This might generate key errors, depending on whether anything can be # parsed from the right-hand values. values = seriesstr.split('-') - dictionary = dict(zip(keys, values)) + dictionary = dict(list(zip(keys, values))) # if there is no spin but there is an 'rcX' in the spin key:value pair # it means that there's really no spin but should be in the rc key:value @@ -484,7 +480,7 @@ def series_from_branchname(branch=None): if dictionary["date"]: datekeys = ['year', 'month', 'day'] datevalues = dictionary["date"].split('.') - datefields = dict(zip(datekeys, datevalues)) + datefields = dict(list(zip(datekeys, datevalues))) if "day" not in datefields: datefields["day"] = "15" seriesdate = datetime(int(datefields["year"]), int( @@ -550,7 +546,7 @@ def series_from_tag(tag=None): raise ValueError('series_from_tag requires a tag') # TODO Test this. - if not isinstance(tag, basestring): + if not isinstance(tag, str): raise TypeError('series_from_tag requires a basestring as input') # This is default, we'll replace with 'snapshots' if we detect that the @@ -561,7 +557,7 @@ def series_from_tag(tag=None): # to force conformance, i.e., remove "-snapshot", but record the # namespace as snapshots while we're at it. if "snapshot" in tag: - tag = string.replace(tag, "-snapshot", '') + tag = str.replace(tag, "-snapshot", '') namespace = "snapshots" # Now we're going to cheat and fabricate a false branchname. @@ -570,7 +566,7 @@ def series_from_tag(tag=None): # ... in which case we can reuse this function. return series_from_branchname(branchname) -from vers import versionFromStr +from linaropy.vers import versionFromStr class TestSeries(unittest.TestCase): @@ -826,130 +822,130 @@ class TestSeries(unittest.TestCase): # and then the same branch name recreated. def test_series_from_branchname(self): - branch2 = u'snapshots/linaro-5.3-2016.05-6' + branch2 = 'snapshots/linaro-5.3-2016.05-6' series2 = series_from_branchname(branch=branch2) self.assertEqual(series2.branchname(), - u'snapshots/linaro-5.3-2016.05-6') + 'snapshots/linaro-5.3-2016.05-6') - branch3 = u'snapshots/linaro-5.3-2016.05' + branch3 = 'snapshots/linaro-5.3-2016.05' series3 = series_from_branchname(branch=branch3) - self.assertEqual(series3.branchname(), u'snapshots/linaro-5.3-2016.05') + self.assertEqual(series3.branchname(), 'snapshots/linaro-5.3-2016.05') - branch4 = u'releases/linaro-5.3-2016.05-6-rc1' + branch4 = 'releases/linaro-5.3-2016.05-6-rc1' series4 = series_from_branchname(branch=branch4) self.assertEqual(series4.branchname(), - u'releases/linaro-5.3-2016.05-6-rc1') + 'releases/linaro-5.3-2016.05-6-rc1') - branch5 = u'releases/linaro-5.3-2016.05-rc1' + branch5 = 'releases/linaro-5.3-2016.05-rc1' series5 = series_from_branchname(branch=branch5) self.assertEqual(series5.branchname(), - u'releases/linaro-5.3-2016.05-rc1') + 'releases/linaro-5.3-2016.05-rc1') - branch6 = u'releases/linaro-5.3-2016.05-6' + branch6 = 'releases/linaro-5.3-2016.05-6' series6 = series_from_branchname(branch=branch6) self.assertEqual(series6.branchname(), - u'releases/linaro-5.3-2016.05-6') + 'releases/linaro-5.3-2016.05-6') - branch7 = u'releases/linaro-5.3-2016.05' + branch7 = 'releases/linaro-5.3-2016.05' series7 = series_from_branchname(branch=branch7) - self.assertEqual(series7.branchname(), u'releases/linaro-5.3-2016.05') + self.assertEqual(series7.branchname(), 'releases/linaro-5.3-2016.05') # -rc1 is invalid with a snapshots namespace. - branch8 = u'snapshots/linaro-5.3-2016.05-6-rc1' + branch8 = 'snapshots/linaro-5.3-2016.05-6-rc1' with self.assertRaises(ValueError): series8 = series_from_branchname(branch=branch8) # Wrong branchname.. it should be 'snapshots' - branch9 = u'snapshot/linaro-5.3-2016.05-6-rc1' + branch9 = 'snapshot/linaro-5.3-2016.05-6-rc1' with self.assertRaises(ValueError): series9 = series_from_branchname(branch=branch9) # Wrong branchname.. it should be 'snapshots' - branch10 = u'snapshot/linaro-5.3-2016.05-6' + branch10 = 'snapshot/linaro-5.3-2016.05-6' with self.assertRaises(ValueError): series10 = series_from_branchname(branch=branch10) # namespace required. - branch11 = u'linaro-5.3-2016.05-6' + branch11 = 'linaro-5.3-2016.05-6' with self.assertRaises(ValueError): series11 = series_from_branchname(branch=branch11) # it should complain about missing the right-hand values. - branch12 = u'snapshots/' + branch12 = 'snapshots/' with self.assertRaises(ValueError): series12 = series_from_branchname(branch=branch12) # It won't parse because of a missing namespace / - branch13 = u'snapshots' + branch13 = 'snapshots' with self.assertRaises(ValueError): series13 = series_from_branchname(branch=branch13) - branch14 = u'snapshots/foo' + branch14 = 'snapshots/foo' with self.assertRaises(KeyError): series14 = series_from_branchname(branch=branch14) # unknown namespace. - branch15 = u'foobarnamespace/linaro-5.3-2016.05-6' + branch15 = 'foobarnamespace/linaro-5.3-2016.05-6' with self.assertRaises(ValueError): series15 = series_from_branchname(branch=branch15) # This will fail on a non-datetime input. - branch16 = u'snapshots/linaro-5.3-asdf' + branch16 = 'snapshots/linaro-5.3-asdf' with self.assertRaises(ValueError): series16 = series_from_branchname(branch=branch16) # This will fail with an invalid spin. - branch17 = u'snapshots/linaro-5.3-2016.05-a' + branch17 = 'snapshots/linaro-5.3-2016.05-a' with self.assertRaises(TypeError): series17 = series_from_branchname(branch=branch17) # This will fail with an invalid rc. - branch18 = u'snapshots/linaro-5.3-2016.05-rcasdfn' + branch18 = 'snapshots/linaro-5.3-2016.05-rcasdfn' with self.assertRaises(TypeError): series18 = series_from_branchname(branch=branch18) # This will fail with an invalid rc. - branch19 = u'snapshots/linaro-5.3-2016.05-9-rcasdfn' + branch19 = 'snapshots/linaro-5.3-2016.05-9-rcasdfn' with self.assertRaises(TypeError): series19 = series_from_branchname(branch=branch19) # TODO: Test series.label (as there was a runtime bug) def test_snapshot_series_from_tag(self): - tag = u'linaro-snapshot-5.3-2016.05-6' + tag = 'linaro-snapshot-5.3-2016.05-6' series = series_from_tag(tag=tag) self.assertEqual(series.branchname(), - u'snapshots/linaro-5.3-2016.05-6') + 'snapshots/linaro-5.3-2016.05-6') def test_invalid_snapshot_series_from_tag(self): # We can't have -rc1 on a snapshot. - tag = u'linaro-snapshot-5.3-2016.05-6-rc1' + tag = 'linaro-snapshot-5.3-2016.05-6-rc1' with self.assertRaises(ValueError): series = series_from_tag(tag=tag) def test_candidate_series_from_tag(self): - tag = u'linaro-5.3-2016.05-6-rc1' + tag = 'linaro-5.3-2016.05-6-rc1' series = series_from_tag(tag=tag) self.assertEqual(series.branchname(), - u'releases/linaro-5.3-2016.05-6-rc1') + 'releases/linaro-5.3-2016.05-6-rc1') def test_release_series_from_tag(self): - tag = u'linaro-5.3-2016.05-6' + tag = 'linaro-5.3-2016.05-6' series = series_from_tag(tag=tag) - self.assertEqual(series.branchname(), u'releases/linaro-5.3-2016.05-6') + self.assertEqual(series.branchname(), 'releases/linaro-5.3-2016.05-6') def test_series_from_tag_invalid_spin(self): - tag = u'linaro-5.3-2016.05-abc' + tag = 'linaro-5.3-2016.05-abc' with self.assertRaises(TypeError): series = series_from_tag(tag=tag) def test_series_from_tag_invalid_rc(self): - tag = u'linaro-5.3-2016.05-rcabf' + tag = 'linaro-5.3-2016.05-rcabf' with self.assertRaises(TypeError): series = series_from_tag(tag=tag) def test_series_from_tag_invalid_rc_with_valid_spin(self): - tag = u'linaro-5.3-2016.05-9-rcabf' + tag = 'linaro-5.3-2016.05-9-rcabf' with self.assertRaises(TypeError): series = series_from_tag(tag=tag) @@ -958,153 +954,153 @@ class TestSeriesFormat(unittest.TestCase): @classmethod def setUpClass(cls): - snaptag = u'linaro-snapshot-5.3-2016.05-6' - reltag = u'linaro-5.3-2016.05-6' - rctag = u'linaro-5.3-2016.05-6-rc1' + snaptag = 'linaro-snapshot-5.3-2016.05-6' + reltag = 'linaro-5.3-2016.05-6' + rctag = 'linaro-5.3-2016.05-6-rc1' cls.snapseries = series_from_tag(tag=snaptag) cls.relseries = series_from_tag(tag=reltag) cls.rcseries = series_from_tag(tag=rctag) def test_format_N_snap(self): f = format(self.snapseries, '%N') - self.assertEquals(f, 'snapshots') + self.assertEqual(f, 'snapshots') def test_format_N_rel(self): f = format(self.relseries, '%N') - self.assertEquals(f, 'releases') + self.assertEqual(f, 'releases') def test_format_N_rc(self): f = format(self.rcseries, '%N') - self.assertEquals(f, 'releases') + self.assertEqual(f, 'releases') def test_format_dashL_snap(self): f = format(self.snapseries, 'foo-%L-bar') - self.assertEquals(f, 'foo-snapshot-bar') + self.assertEqual(f, 'foo-snapshot-bar') def test_format_dashL_rel(self): f = format(self.relseries, 'foo-%L-bar') - self.assertEquals(f, 'foo-bar') + self.assertEqual(f, 'foo-bar') def test_format_dashL_rc(self): f = format(self.rcseries, 'foo-%L-bar') - self.assertEquals(f, 'foo-bar') + self.assertEqual(f, 'foo-bar') def test_format_dotL_snap(self): f = format(self.snapseries, 'foo.%L.bar') - self.assertEquals(f, 'foo.snapshot.bar') + self.assertEqual(f, 'foo.snapshot.bar') def test_format_dotL_rel(self): f = format(self.relseries, 'foo.%L.bar') - self.assertEquals(f, 'foo.bar') + self.assertEqual(f, 'foo.bar') def test_format_dotL_rc(self): f = format(self.rcseries, 'foo.%L.bar') - self.assertEquals(f, 'foo.bar') + self.assertEqual(f, 'foo.bar') def test_format_L_snap(self): f = format(self.snapseries, 'foo%Lbar') - self.assertEquals(f, 'foosnapshotbar') + self.assertEqual(f, 'foosnapshotbar') def test_format_L_rel(self): f = format(self.relseries, 'foo%Lbar') - self.assertEquals(f, 'foobar') + self.assertEqual(f, 'foobar') def test_format_L_rc(self): f = format(self.rcseries, 'foo%Lbar') - self.assertEquals(f, 'foobar') + self.assertEqual(f, 'foobar') def test_format_dashP(self): f = format(self.snapseries, 'foo-%P-bar') - self.assertEquals(f, 'foo-GCC-bar') + self.assertEqual(f, 'foo-GCC-bar') def test_format_dotP(self): f = format(self.snapseries, 'foo.%P.bar') - self.assertEquals(f, 'foo.GCC.bar') + self.assertEqual(f, 'foo.GCC.bar') def test_format_P(self): f = format(self.snapseries, 'foo%Pbar') - self.assertEquals(f, 'fooGCCbar') + self.assertEqual(f, 'fooGCCbar') def test_format_dashl(self): f = format(self.snapseries, 'foo-%l-bar') - self.assertEquals(f, 'foo-gcc-bar') + self.assertEqual(f, 'foo-gcc-bar') def test_format_dotl(self): f = format(self.snapseries, 'foo.%l.bar') - self.assertEquals(f, 'foo.gcc.bar') + self.assertEqual(f, 'foo.gcc.bar') def test_format_l(self): f = format(self.snapseries, 'foo%lbar') - self.assertEquals(f, 'foogccbar') + self.assertEqual(f, 'foogccbar') def test_format_V(self): f = format(self.snapseries, 'foo.%V.bar') - self.assertEquals(f, 'foo.Linaro.bar') + self.assertEqual(f, 'foo.Linaro.bar') def test_format_v(self): f = format(self.snapseries, 'foo.%v.bar') - self.assertEquals(f, 'foo.linaro.bar') + self.assertEqual(f, 'foo.linaro.bar') def test_format_E(self): f = format(self.snapseries, 'gcc-%E') - self.assertEquals(f, 'gcc-5.3') + self.assertEqual(f, 'gcc-5.3') # This shouldn't show a trailing - after the minor because of a point. def test_format_E_with_fabricated_minor(self): minorseries = copy.deepcopy(self.snapseries) minorseries.package.version.point = 9 f = format(minorseries, 'gcc-%E') - self.assertEquals(f, 'gcc-5.3') + self.assertEqual(f, 'gcc-5.3') def test_format_e(self): f = format(self.snapseries, 'gcc-%e') - self.assertEquals(f, 'gcc-5.3') + self.assertEqual(f, 'gcc-5.3') def test_format_e_fabricate_minor(self): minorseries = copy.deepcopy(self.snapseries) minorseries.package.version.point = 9 f = format(minorseries, 'gcc-%e') - self.assertEquals(f, 'gcc-5.3.9') + self.assertEqual(f, 'gcc-5.3.9') def test_format_M(self): f = format(self.snapseries, 'gcc-%M') - self.assertEquals(f, 'gcc-5') + self.assertEqual(f, 'gcc-5') def test_format_m(self): f = format(self.snapseries, 'gcc-X.%m') - self.assertEquals(f, 'gcc-X.3') + self.assertEqual(f, 'gcc-X.3') def test_format_p(self): f = format(self.snapseries, 'gcc-X.Y.%p') - self.assertEquals(f, 'gcc-X.Y.') + self.assertEqual(f, 'gcc-X.Y.') def test_format_p_fabricate_minor(self): minorseries = copy.deepcopy(self.snapseries) minorseries.package.version.point = 9 f = format(minorseries, 'gcc-X.Y.%p') - self.assertEquals(f, 'gcc-X.Y.9') + self.assertEqual(f, 'gcc-X.Y.9') def test_format_D(self): f = format(self.snapseries, 'foo-%D-bar') - self.assertEquals(f, 'foo-2016.05-bar') + self.assertEqual(f, 'foo-2016.05-bar') def test_format_snap_h(self): f = format(self.snapseries, 'http://%h.') - self.assertEquals(f, 'http://snapshots.') + self.assertEqual(f, 'http://snapshots.') def test_format_release_h(self): f = format(self.relseries, 'http://%h.') - self.assertEquals(f, 'http://releases.') + self.assertEqual(f, 'http://releases.') def test_format_snap_h(self): f = format(self.snapseries, 'http://%h.') - self.assertEquals(f, 'http://snapshots.') + self.assertEqual(f, 'http://snapshots.') def test_format_snap_d(self): f = format( self.snapseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://snapshots.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6') @@ -1113,7 +1109,7 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.relseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://releases.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6') @@ -1122,7 +1118,7 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.rcseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://snapshots.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6-rc1') @@ -1131,7 +1127,7 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.snapseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://snapshots.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6') @@ -1140,7 +1136,7 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.relseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://releases.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6') @@ -1149,7 +1145,7 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.rcseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://snapshots.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6-rc1') @@ -1158,7 +1154,7 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.snapseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://snapshots.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6') @@ -1167,7 +1163,7 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.relseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://releases.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6') @@ -1176,70 +1172,70 @@ class TestSeriesFormat(unittest.TestCase): f = format( self.rcseries, 'http://%h.linaro.org/components/toolchain/binaries/%d') - self.assertEquals( + self.assertEqual( f, 'http://snapshots.linaro.org/components/' 'toolchain/binaries/5.3-2016.05-6-rc1') def test_format_dashS(self): f = format(self.snapseries, 'foo-%S-bar') - self.assertEquals(f, 'foo-6-bar') + self.assertEqual(f, 'foo-6-bar') def test_format_dashS_no_spin(self): nospinseries = copy.deepcopy(self.snapseries) nospinseries.spin = Spin() f = format(nospinseries, 'foo-%S-bar') - self.assertEquals(f, 'foo-bar') + self.assertEqual(f, 'foo-bar') def test_format_dotS(self): f = format(self.snapseries, 'foo.%S.bar') - self.assertEquals(f, 'foo.6.bar') + self.assertEqual(f, 'foo.6.bar') def test_format_dotS_no_spin(self): nospinseries = copy.deepcopy(self.snapseries) nospinseries.spin = Spin() f = format(nospinseries, 'foo.%S.bar') - self.assertEquals(f, 'foo.bar') + self.assertEqual(f, 'foo.bar') def test_format_S(self): f = format(self.snapseries, 'foo%Sbar') - self.assertEquals(f, 'foo6bar') + self.assertEqual(f, 'foo6bar') def test_format_S_no_spin(self): nospinseries = copy.deepcopy(self.snapseries) nospinseries.spin = Spin() f = format(nospinseries, 'foo%Sbar') - self.assertEquals(f, 'foobar') + self.assertEqual(f, 'foobar') def test_format_dashR(self): f = format(self.rcseries, '2016.05-6-%R') - self.assertEquals(f, '2016.05-6-rc1') + self.assertEqual(f, '2016.05-6-rc1') def test_format_dashR_fabricate_norc(self): norcseries = copy.deepcopy(self.rcseries) norcseries.rc = Rc() f = format(norcseries, '2016.05-6-%R') - self.assertEquals(f, '2016.05-6') + self.assertEqual(f, '2016.05-6') def test_format_dotR(self): f = format(self.rcseries, '2016.05-6.%R') - self.assertEquals(f, '2016.05-6.rc1') + self.assertEqual(f, '2016.05-6.rc1') def test_format_dotR_fabricate_norc(self): norcseries = copy.deepcopy(self.rcseries) norcseries.rc = Rc() f = format(norcseries, '2016.05-6.%R') - self.assertEquals(f, '2016.05-6') + self.assertEqual(f, '2016.05-6') def test_format_R(self): f = format(self.rcseries, '2016.05-6-%R') - self.assertEquals(f, '2016.05-6-rc1') + self.assertEqual(f, '2016.05-6-rc1') def test_format_R_fabricate_norc(self): norcseries = copy.deepcopy(self.rcseries) norcseries.rc = Rc() f = format(norcseries, '2016.05-6#%R') - self.assertEquals(f, '2016.05-6#') + self.assertEqual(f, '2016.05-6#') if __name__ == '__main__': # logging.basicConfig(level="INFO") diff --git a/linaropy/vers.py b/linaropy/vers.py index 27fc0ce..c8a7ab4 100644 --- a/linaropy/vers.py +++ b/linaropy/vers.py @@ -7,7 +7,7 @@ class Vendor(object): def __init__(self, vendor="Linaro"): if not vendor: raise TypeError("Vendor requires a vendor string.") - if isinstance(vendor, basestring): + if isinstance(vendor, str): self.vendor = vendor else: raise TypeError("Input 'vendor' must be of type basestring.") @@ -28,13 +28,13 @@ class Version(object): def __init__(self, major, minor=None, point=None): - if isinstance(major, int) or isinstance(major, basestring): + if isinstance(major, int) or isinstance(major, str): # This will throw an exception if 'major' is an empty string. self.major = int(major) else: raise TypeError("major must be of type int, string.") - if isinstance(minor, int) or isinstance(minor, basestring): + if isinstance(minor, int) or isinstance(minor, str): # This will throw an exception if 'minor' is an empty string. self.minor = int(minor) elif not minor: @@ -42,7 +42,7 @@ class Version(object): else: raise TypeError("minor must be of type int, string, or None.") - if isinstance(point, int) or isinstance(point, basestring): + if isinstance(point, int) or isinstance(point, str): # This is illegal, as it'd mess up the output and make it look like # there's a minor that's really a point. @@ -60,9 +60,9 @@ class Version(object): def __str__(self): ver = str(self.major) if self.minor: - ver = ver + u'.' + str(self.minor) + ver = ver + '.' + str(self.minor) if self.point: - ver = ver + u'.' + str(self.point) + ver = ver + '.' + str(self.point) return ver # TODO: I'm sure there's a more pythonic way to do this but this is @@ -90,7 +90,7 @@ class Version(object): else: numtoks = delstoks - 1 - vers = u'' + vers = '' for tok in toks: if tok == 'M': vers = vers + str(self.major) @@ -112,15 +112,17 @@ class Version(object): raise ValueError("Minor must be greater than or equal to zero.") # Helper function which returns a Version. + + def versionFromStr(version): - if not isinstance(version, basestring): + if not isinstance(version, str): raise TypeError('input must be of type basestring') major = version.split('.', 1)[0] # split('.',1) will return index error on "5" but will return empty string on "5." # Any empty string is not a valid input into Version. - if major == u'': + if major == '': major = None try: @@ -128,7 +130,7 @@ def versionFromStr(version): except IndexError: minor = None - if minor == u'': + if minor == '': minor = None try: @@ -136,7 +138,7 @@ def versionFromStr(version): except IndexError: point = None - if point == u'': + if point == '': point = None return Version(major, minor, point) @@ -148,10 +150,10 @@ class Package(object): # instance. def __init__(self, package="GCC", version=None): - if not package or package == u'': + if not package or package == '': raise TypeError("Package requires 'package' as a non-empty string") - if isinstance(package, basestring): + if isinstance(package, str): self.package = package else: raise TypeError("Input 'package' must be of type basestring.") @@ -170,17 +172,17 @@ class Package(object): return str(self.version) def __str__(self): - return self.package + u'-' + str(self.version) + return self.package + '-' + str(self.version) def lower(self): - return self.package.lower() + u'-' + str(self.version) + return self.package.lower() + '-' + str(self.version) # TODO: Create format function which can change the separator to ' ' or to # '-'. def packageFromStr(package=None): - if not isinstance(package, basestring): + if not isinstance(package, str): raise TypeError('packageFromStr requires a string as input') # Get the part before the version numbers. That's the package @@ -194,9 +196,9 @@ def packageFromStr(package=None): except IndexError: raise ValueError('string must be -') - if package_name == u'': + if package_name == '': raise TypeError("Couldn't parse a package name from input string") - if package_version == u'': + if package_version == '': raise TypeError("Couldn't parse a package version from input string") # This will throw exceptions if the input are malformed. @@ -212,7 +214,7 @@ class Vers(object): self.val = 0 return - if isinstance(val, int) or isinstance(val, basestring): + if isinstance(val, int) or isinstance(val, str): # This should raise an exception if the string can't be converted # to an int. If val is already an int it's a nop. intval = int(val) @@ -346,6 +348,7 @@ class TestVersion(unittest.TestCase): version3 = Version(major="5", minor=None, point=None) self.assertEqual(version3.strfversion("%M%m%p"), "5") + class TestVendor(unittest.TestCase): def test_vendor_default(self): @@ -549,7 +552,7 @@ class TestPackageFromString(unittest.TestCase): def test_empty_str_package(self): with self.assertRaises(ValueError): - package = packageFromStr(package=u"") + package = packageFromStr(package="") def test_with_package(self): package = Package("GCC", "5.3.1") diff --git a/rn.py b/rn.py index 7c3551d..f055059 100644 --- a/rn.py +++ b/rn.py @@ -37,21 +37,24 @@ import traceback rnProj = [] # Cleanup the temporary project directory if necessary. + + def rncleanup(): if not rnProj: # This will be the case if the script is run via the test driver. - print "No cleanup needed" + print("No cleanup needed") else: print_info("Cleaning up Proj dir %s if possible." % rnProj[0].projdir) rnProj[0].cleanup() + def generate(track, to_date, to_series, gccsource, persist): # Delay creating the Proj directory until now so that the parser (and # parser validation functions) can be tested in the unittests without # invoking the internals of this driver. rnProj.append(Proj(prefix='rn-', persist=persist)) if persist: - andpersist="(and persist) " + andpersist = "(and persist) " print_info(BOLD + "Release notes will be generated %sin:" % andpersist) print_info(" %s" % rnProj[0].projdir) @@ -68,14 +71,17 @@ def generate(track, to_date, to_series, gccsource, persist): logging.info("%s is a tag. Creating Series from tag." % track) track_series = linaro_series_from_tag(track) else: - logging.info("%s is a branch. Creating Series from branchname." % track) + logging.info( + "%s is a branch. Creating Series from branchname." % + track) track_series = linaroSeriesFromBranchname(track) try: next_series = track_series.toNext(to_series) except TypeError: - logging.error( "Next series '%s' from '%s' in an invalid progression" - % (LinaroSeries.series[to_series], track_series.shorttype())) + logging.error( + "Next series '%s' from '%s' in an invalid progression" % + (LinaroSeries.series[to_series], track_series.shorttype())) logging.error( "If this is a release series try tracking the release-candidate" " tag instead of the release branch.") @@ -106,8 +112,8 @@ def generate(track, to_date, to_series, gccsource, persist): 'Please enter the location of the changelog csv file: ', "6.1-2016.06.csv") - username=pwd.getpwuid(os.getuid()).pw_name - public_html_dir= "/home/%s/public_html/" % username + username = pwd.getpwuid(os.getuid()).pw_name + public_html_dir = "/home/%s/public_html/" % username next_rn.update_series_readmes() while ans: @@ -122,17 +128,17 @@ def generate(track, to_date, to_series, gccsource, persist): # The default location to tell the user to look for generated files. # If there is a webserver this is overwritten if the users wants it. - dest_dir=rnProj[0].projdir + dest_dir = rnProj[0].projdir if os.path.isdir(public_html_dir): - todir=public_html_dir + os.path.basename(dest_dir) + "/" + todir = public_html_dir + os.path.basename(dest_dir) + "/" answer = yninput( - "Would you like to copy the .txt, .html, and .textile" - " files to your %s directory?" % todir, "N") + "Would you like to copy the .txt, .html, and .textile" + " files to your %s directory?" % todir, "N") if answer == "y": - dest_dir=todir + dest_dir = todir if not os.path.isdir(dest_dir): - os.mkdir(dest_dir, 0755) + os.mkdir(dest_dir, 0o755) for file in glob.glob(r'%s/*.txt' % rnProj[0].projdir): shutil.copy(file, dest_dir) @@ -152,6 +158,8 @@ def generate(track, to_date, to_series, gccsource, persist): ans = next_rn.update_series_readmes() # Verify that the GCC Source is located where it says it is. + + class VerifyGCCSourceAction(argparse.Action): def __init__(self, option_strings, dest, nargs=None, **kwargs): @@ -167,7 +175,10 @@ class VerifyGCCSourceAction(argparse.Action): # We simply want to test that the directory exists. We'll prove that # it is a git directory in a later step. if not os.path.isdir(values): - raise IOError("The GCC source directory %s does not exist." % values) + raise IOError( + "The GCC source directory %s does not exist." % + values) + def str_to_datetime(datestr): # strptime will throw an exception if the input date is not a string or is @@ -179,6 +190,7 @@ def str_to_datetime(datestr): # Force the 'day' to 15 to unify comparisons. return inputdate.replace(day=15) + def create_parser(): parser = argparse.ArgumentParser( prog="rn.py", -- cgit v1.2.3