summaryrefslogtreecommitdiff
path: root/linaropy/rn/rnseries.py
blob: d3e2c3f23c175a580429ce091e7e5f3458867302 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
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()