diff options
Diffstat (limited to 'linaropy/rn/rnseries.py')
-rw-r--r-- | linaropy/rn/rnseries.py | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/linaropy/rn/rnseries.py b/linaropy/rn/rnseries.py new file mode 100644 index 0000000..d3e2c3f --- /dev/null +++ b/linaropy/rn/rnseries.py @@ -0,0 +1,193 @@ +import unittest +import logging +import os + +from sh import ls +from shutil import copyfile + +from ..proj import Proj +from ..git.gitrepo import cd +from ..git.clone import Clone +from ..git.workdir import Workdir +from ..series import Series +from ..series import seriesFromBranchname +from linaroseries import LinaroSeries +from linaroseries import linaroSeriesFromBranchname +from template import TemplateRN + +from ..rninput import yninput + +# Abstract base class for a release-notes series +# Every RNSeries has a templateRN instance and a workdir. The template +# instance is used for the base template. +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' + _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. + # @trackseries - an instance of a LinaroSeries to track. + # @nextseries - an instance of a LinaroSeries that is the next series. + def __init__(self, proj, rnrepo=None, trackseries=None, nextseries=None, headless=False): + + # Create the release-notes repository clone. The Clone constructor + # will throw an exception if proj is not a Proj. That is an + # unrecoverable error so don't catch it here. The Clone constructor + # will also throw and exception if rnrepo is not a string. + + if rnrepo: + logging.info('RNSeries() clone already exists. Using existing.') + self.rnclone=Clone(proj, clonedir=rnrepo) + else: + self.rnclone=Clone(proj, remote=RNSeries.rnremote) + + # TODO: Write a testcase that exposes this. + if not trackseries: + raise TypeError("Input variable trackseries is required.") + + # TODO: Write a testcase that exposes this. + if not isinstance(trackseries, LinaroSeries): + raise TypeError("Input variable trackseries not of type Series.") + + # TODO: Write a testcase that exposes this. + if not nextseries: + raise TypeError("Input variable nextseries is required.") + + # TODO: Write a testcase that exposes this. + if not isinstance(nextseries, LinaroSeries): + raise TypeError("Input variable nextseries not of type Series.") + + self.trackseries=trackseries + self.nextseries=nextseries + + self.proj=proj + + templ_branchname=self.nextseries.shorttype() + "_" + self.nextseries.getDir() + + logging.info('RNSeries() Creating TemplateRN') + # Every release-notes series contains a 'template' workdir checked out + # into a new templ_branchname branch that tracks master. + self.rntemplate=TemplateRN(self.proj,self.rnclone, branchname_suffix=templ_branchname) + + # We do this now because the SeriesRN workdir might be branched from the template. + self.rntemplate.updateTemplateReadme() + updateseries=self.rntemplate.updateTemplateSeries() + + self.rntemplate.commit() + + print "Please verify that your changes have been committed on the template branch." + self.rntemplate.log(1) + + # It's possible that self.trackseries.getBranchname() doesn't exist + # (such is the case if we're creating the first candidate from a + # snapshot). In this case 'track' should be the local template branch + # so that we pick up the template changes. + if not self.rntemplate.branchexists(self.trackseries.getBranchname()): + print("Creating RNSeries based on branch " + self.rntemplate.getbranch()) + self.rnworkdir=Workdir(proj=self.proj, clone=self.rnclone, workdir=self.nextseries.shorttype(), track=self.rntemplate.getbranch(), branchname=self.nextseries.getBranchname()) + else: + print "You updated the template README.textile.series but this will not be reflected in the Candidate README.textile.series." + print "Creating RNSeries based on branch " + self.trackseries.getBranchname() + self.rnworkdir=Workdir(proj=self.proj, clone=self.rnclone, workdir=self.nextseries.shorttype(), track=self.trackseries.getBranchname(), branchname=self.nextseries.getBranchname()) + + print "Log of last commit on workdir branch:" + self.rnworkdir.log(1) + + print "If you would like to make changes to the series release notes please update the the Candidate README.textile.series file:" + answer=yninput("Do you need to update the Candidate README.textile.series file?", "N") + if answer == "y": + self.rnworkdir.editFile(self._series) + else: + print "The Candidate README.textile.series file has not been updated." + + self.rnworkdir.commit() + + print "Log of last commit on workdir branch:" + self.rnworkdir.log(1) + + # TODO: Don't forget to push template and workdir changes. + # self.rntemplate.pushToBranch("origin/master") + # TODO: Should the workdir know where to push to? + # self.rnworkdir.pushToBranch(self.nextseries.getBranchname()) + + def get_next_series(self): + return self.nextseries + + def get_track_series(self): + return self.trackseries + +# Do we even need these, especially if they're all the same? +class SnapshotRN(RNSeries): + def __init__(self, proj, trackseries, rnrepo=None): + if not isinstance(trackseries, LinaroSeries): + raise TypeError('The series input must be of type LinaroSeries') + + nextseries=trackseries.toNextSnapshot(strict=True) + + super(SnapshotRN,self).__init__(proj, rnrepo, trackseries=trackseries, nextseries=nextseries) + +class CandidateRN(RNSeries): + def __init__(self, proj, trackseries, rnrepo=None): + if not isinstance(trackseries, LinaroSeries): + raise TypeError('The trackseries input must be of type LinaroSeries') + + self.nextseries=trackseries.toNextCandidate(strict=True) + + super(CandidateRN,self).__init__(proj, rnrepo, trackseries=trackseries, nextseries=self.nextseries) + +class ReleaseRN(RNSeries): + def __init__(self, proj, trackseries, rnrepo=None): + if not isinstance(trackseries, LinaroSeries): + raise TypeError('The series input must be of type LinaroSeries') + + nextseries=trackseries.toNextRelease(strict=True) + + super(ReleaseRN,self).__init__(proj, rnrepo, trackseries=trackseries, nextseries=nextseries) + +class TestCandidateRN(unittest.TestCase): + #logging.basicConfig(level="INFO") + testdirprefix="CandidateRNUT" + + @classmethod + def setUpClass(cls): + cls.proj=Proj(prefix=TestCandidateRN.testdirprefix, persist=True) + logging.info('11111 Created Proj dir') + cls.rnrepo=Clone(cls.proj,remote=u'http://git.linaro.org/toolchain/release-notes.git') + logging.info('22222 Created clone dir') + cls.branch=u'snapshots/linaro-6.1-2016.06' + cls.series=linaroSeriesFromBranchname(branch=cls.branch) + + @classmethod + def tearDownClass(cls): + cls.proj.cleanup() + + def test_candidate_newclone(self): + logging.info('33333 Going To Create CandidateRN') + candidatern=CandidateRN(self.proj, rnrepo=self.rnrepo.repodir, trackseries=self.series) + logging.info('44444 Created CandidateRN') + self.assertEqual(candidatern.nextseries.longuppertype(), "Release-Candidate") + self.assertEqual(candidatern.nextseries.longlowertype(), "release-candidate") + self.assertTrue(os.path.isdir(self.proj.projdir + "/release-notes.git")) + self.assertTrue(os.path.isdir(self.proj.projdir + "/candidate")) + self.assertTrue(os.path.isdir(self.proj.projdir + "/template")) + +# def test_candidate_existingclone(self): +# # Since this reuses an existing clone of a repository the +# # release-notes.git directory should actually be a symlink. +# candidatern=CandidateRN(self.proj, trackseries=self.series, rnrepo=TestCandidateRN.rnrepo.repodir) +# self.assertEqual(candidatern.series.longuppertype(), "Release-Candidate") +# self.assertEqual(candidatern.series.longlowertype(), "release-candidate") +# self.assertTrue(os.path.islink(self.proj.projdir + "/release-notes.git")) +# self.assertTrue(os.path.isdir(self.proj.projdir + "/candidate")) +# self.assertTrue(os.path.isdir(self.proj.projdir + "/template")) +# +# self.assertEqual(candidatern.rntemplate.getbranch().split("_")[0], "template") +## self.assertTrue(candidatern.rnworkdir.getbranch().startswith("releases/")) +# +# print "Based on: %s" % self.series.getBranchname() +# print "Template Branch: %s" % candidatern.rntemplate.getbranch() +# print "Candidate Branch: %s" % candidatern.rnworkdir.getbranch() + +if __name__ == '__main__': + unittest.main() |