diff options
Diffstat (limited to 'repoman/lib/repoman/modules/vcs/svn/changes.py')
-rw-r--r-- | repoman/lib/repoman/modules/vcs/svn/changes.py | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/repoman/lib/repoman/modules/vcs/svn/changes.py b/repoman/lib/repoman/modules/vcs/svn/changes.py new file mode 100644 index 000000000..dfed1655b --- /dev/null +++ b/repoman/lib/repoman/modules/vcs/svn/changes.py @@ -0,0 +1,142 @@ +''' +Subversion module Changes class submodule +''' + +from itertools import chain + +from repoman.modules.vcs.changes import ChangesBase +from repoman._subprocess import repoman_popen +from repoman._subprocess import repoman_getstatusoutput +from repoman.modules.vcs.vcs import vcs_files_to_cps +from repoman._portage import portage +from portage import os +from portage.output import green +from portage.package.ebuild.digestgen import digestgen + + +class Changes(ChangesBase): + '''Class object to scan and hold the resultant data + for all changes to process. + ''' + + vcs = 'svn' + + def __init__(self, options, repo_settings): + '''Class init + + @param options: the run time cli options + @param repo_settings: RepoSettings instance + ''' + super(Changes, self).__init__(options, repo_settings) + + def _scan(self): + '''VCS type scan function, looks for all detectable changes''' + with repoman_popen("svn status") as f: + svnstatus = f.readlines() + self.changed = [ + "./" + elem.split()[-1:][0] + for elem in svnstatus + if elem and elem[:1] in "MR"] + self.new = [ + "./" + elem.split()[-1:][0] + for elem in svnstatus + if elem.startswith("A")] + self.removed = [ + "./" + elem.split()[-1:][0] + for elem in svnstatus + if elem.startswith("D")] + + @property + def expansion(self): + '''VCS method of getting the expanded keywords in the repository''' + if self._expansion is not None: + return self._expansion + # Subversion expands keywords specified in svn:keywords properties. + with repoman_popen("svn propget -R svn:keywords") as f: + props = f.readlines() + self._expansion = dict( + ("./" + prop.split(" - ")[0], prop.split(" - ")[1].split()) + for prop in props if " - " in prop) + del props + return self._expansion + + @property + def unadded(self): + '''VCS method of getting the unadded files in the repository''' + if self._unadded is not None: + return self._unadded + with repoman_popen("svn status --no-ignore") as f: + svnstatus = f.readlines() + self._unadded = [ + "./" + elem.rstrip().split()[1] + for elem in svnstatus + if elem.startswith("?") or elem.startswith("I")] + del svnstatus + return self._unadded + + def thick_manifest(self, updates, headers, no_expansion, expansion): + '''Create a thick manifest + + @param updates: + @param headers: + @param no_expansion: + @param expansion: + ''' + svn_keywords = dict((k.lower(), k) for k in [ + "Rev", + "Revision", + "LastChangedRevision", + "Date", + "LastChangedDate", + "Author", + "LastChangedBy", + "URL", + "HeadURL", + "Id", + "Header", + ]) + + for _file in updates: + # for SVN, expansion contains files that are included in expansion + if _file not in expansion: + continue + + # Subversion keywords are case-insensitive + # in svn:keywords properties, + # but case-sensitive in contents of files. + enabled_keywords = [] + for k in expansion[_file]: + keyword = svn_keywords.get(k.lower()) + if keyword is not None: + enabled_keywords.append(keyword) + + headerstring = r"'\$(%s).*\$'" % "|".join(enabled_keywords) + + _out = repoman_getstatusoutput( + "egrep -q %s %s" % (headerstring, portage._shell_quote(_file))) + if _out[0] == 0: + headers.append(_file) + + print("%s have headers that will change." % green(str(len(headers)))) + print( + "* Files with headers will" + " cause the manifests to be changed and committed separately.") + + def digest_regen(self, updates, removed, manifests, scanner, broken_changelog_manifests): + '''Regenerate manifests + + @param updates: updated files + @param removed: removed files + @param manifests: Manifest files + @param scanner: The repoman.scanner.Scanner instance + @param broken_changelog_manifests: broken changelog manifests + ''' + if updates or removed: + for x in sorted(vcs_files_to_cps( + chain(updates, removed, manifests), + scanner.repo_settings.repodir, + scanner.repolevel, scanner.reposplit, scanner.categories)): + self.repoman_settings["O"] = os.path.join(self.repo_settings.repodir, x) + digestgen(mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb) + + |