diff options
author | Martin Braun <martin.braun@kit.edu> | 2013-11-24 16:41:57 +0100 |
---|---|---|
committer | Martin Braun <martin.braun@kit.edu> | 2013-11-27 22:33:44 +0100 |
commit | 49ed57c55e01dffe69668ae34deddd619b3486c8 (patch) | |
tree | 8c8ba0c0e2c1f4658667aa8aad19eaa167f5447b | |
parent | fa5480e8bccec39278e9c5f81c09d1e702fd0fd7 (diff) |
modtool: Added git support
-rw-r--r-- | gr-utils/python/modtool/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_add.py | 48 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_base.py | 21 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_disable.py | 7 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_makexml.py | 13 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_newmod.py | 6 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_rm.py | 6 | ||||
-rw-r--r-- | gr-utils/python/modtool/scm.py | 221 |
8 files changed, 300 insertions, 23 deletions
diff --git a/gr-utils/python/modtool/CMakeLists.txt b/gr-utils/python/modtool/CMakeLists.txt index d7816816c3..bb4febe318 100644 --- a/gr-utils/python/modtool/CMakeLists.txt +++ b/gr-utils/python/modtool/CMakeLists.txt @@ -33,6 +33,7 @@ GR_PYTHON_INSTALL(FILES modtool_newmod.py modtool_rm.py parser_cc_block.py + scm.py templates.py util_functions.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/modtool diff --git a/gr-utils/python/modtool/modtool_add.py b/gr-utils/python/modtool/modtool_add.py index 1be20f0485..e188b7fd71 100644 --- a/gr-utils/python/modtool/modtool_add.py +++ b/gr-utils/python/modtool/modtool_add.py @@ -135,8 +135,10 @@ class ModToolAdd(ModTool): def _write_tpl(self, tpl, path, fname): """ Shorthand for writing a substituted template to a file""" - print "Adding file '%s'..." % fname - open(os.path.join(path, fname), 'w').write(get_template(tpl, **self._info)) + path_to_file = os.path.join(path, fname) + print "Adding file '%s'..." % path_to_file + open(path_to_file, 'w').write(get_template(tpl, **self._info)) + self.scm.add_files((path_to_file,)) def run(self): """ Go, go, go. """ @@ -185,6 +187,7 @@ class ModToolAdd(ModTool): ' s->addTest(gr::%s::qa_%s::suite());' % (self._info['modname'], self._info['blockname']) ) + self.scm.mark_files_updated((self._file['qalib'],)) except IOError: print "Can't add C++ QA files." def _add_qa36(): @@ -193,16 +196,16 @@ class ModToolAdd(ModTool): self._write_tpl('qa_cpp36', 'lib', fname_qa_cc) if not self._skip_cmakefiles: open(self._file['cmlib'], 'a').write( - str( - Cheetah.Template.Template( - Templates['qa_cmakeentry36'], - searchList={'basename': os.path.splitext(fname_qa_cc)[0], - 'upperbasename': os.path.splitext(fname_qa_cc)[0].upper(), - 'filename': fname_qa_cc, - 'modname': self._info['modname'] - } - ) - ) + str( + Cheetah.Template.Template( + Templates['qa_cmakeentry36'], + searchList={'basename': os.path.splitext(fname_qa_cc)[0], + 'upperbasename': os.path.splitext(fname_qa_cc)[0].upper(), + 'filename': fname_qa_cc, + 'modname': self._info['modname'] + } + ) + ) ) ed = CMakeFileEditor(self._file['cmlib']) ed.remove_double_newlines() @@ -223,6 +226,13 @@ class ModToolAdd(ModTool): fname_cc = self._info['fullblockname'] + '.cc' self._write_tpl('block_h36', self._info['includedir'], fname_h) self._write_tpl('block_cpp36', 'lib', fname_cc) + if self._add_cc_qa: + if self._info['version'] == '37': + _add_qa() + elif self._info['version'] == '36': + _add_qa36() + elif self._info['version'] == 'autofoo': + print "Warning: C++ QA files not supported for autotools." if not self._skip_cmakefiles: ed = CMakeFileEditor(self._file['cmlib']) cmake_list_var = '[a-z]*_?' + self._info['modname'] + '_sources' @@ -232,13 +242,7 @@ class ModToolAdd(ModTool): ed = CMakeFileEditor(self._file['cminclude']) ed.append_value('install', fname_h, to_ignore_end='DESTINATION[^()]+') ed.write() - if self._add_cc_qa: - if self._info['version'] == '37': - _add_qa() - elif self._info['version'] == '36': - _add_qa36() - elif self._info['version'] == 'autofoo': - print "Warning: C++ QA files not supported for autotools." + self.scm.mark_files_updated((self._file['cminclude'], self._file['cmlib'])) def _run_swig(self): """ Do everything that needs doing in the subdir 'swig'. @@ -264,6 +268,7 @@ class ModToolAdd(ModTool): regexp = re.compile('^%\{\n', re.MULTILINE) oldfile = regexp.sub('%%{\n%s\n' % include_str, oldfile, count=1) open(self._file['swig'], 'w').write(oldfile) + self.scm.mark_files_updated((self._file['swig'],)) def _run_python_qa(self): """ Do everything that needs doing in the subdir 'python' to add @@ -274,12 +279,14 @@ class ModToolAdd(ModTool): fname_py_qa = 'qa_' + self._info['blockname'] + '.py' self._write_tpl('qa_python', self._info['pydir'], fname_py_qa) os.chmod(os.path.join(self._info['pydir'], fname_py_qa), 0755) + self.scm.mark_files_updated((os.path.join(self._info['pydir'], fname_py_qa),)) if self._skip_cmakefiles or CMakeFileEditor(self._file['cmpython']).check_for_glob('qa_*.py'): return print "Editing %s/CMakeLists.txt..." % self._info['pydir'] open(self._file['cmpython'], 'a').write( 'GR_ADD_TEST(qa_%s ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/%s)\n' % \ (self._info['blockname'], fname_py_qa)) + self.scm.mark_files_updated((self._file['cmpython'],)) def _run_python(self): """ Do everything that needs doing in the subdir 'python' to add @@ -293,11 +300,13 @@ class ModToolAdd(ModTool): append_re_line_sequence(self._file['pyinit'], '(^from.*import.*\n|# import any pure.*\n)', 'from %s import %s' % (self._info['blockname'], self._info['blockname'])) + self.scm.mark_files_updated((self._file['pyinit'],)) if self._skip_cmakefiles: return ed = CMakeFileEditor(self._file['cmpython']) ed.append_value('GR_PYTHON_INSTALL', fname_py, to_ignore_end='DESTINATION[^()]+') ed.write() + self.scm.mark_files_updated((self._file['cmpython'],)) def _run_grc(self): """ Do everything that needs doing in the subdir 'grc' to add @@ -313,4 +322,5 @@ class ModToolAdd(ModTool): print "Editing grc/CMakeLists.txt..." ed.append_value('install', fname_grc, to_ignore_end='DESTINATION[^()]+') ed.write() + self.scm.mark_files_updated((self._file['cmgrc'],)) diff --git a/gr-utils/python/modtool/modtool_base.py b/gr-utils/python/modtool/modtool_base.py index 768bce0f77..a58b7abcb1 100644 --- a/gr-utils/python/modtool/modtool_base.py +++ b/gr-utils/python/modtool/modtool_base.py @@ -24,16 +24,17 @@ import os import re from optparse import OptionParser, OptionGroup +from gnuradio import gr from util_functions import get_modname - +from scm import SCMRepoFactory class ModToolException(BaseException): """ Standard exception for modtool classes. """ pass - class ModTool(object): """ Base class for all modtool command classes. """ + name = 'base' def __init__(self): self._subdirs = ['lib', 'include', 'python', 'swig', 'grc'] # List subdirs where stuff happens self._has_subdirs = {} @@ -68,6 +69,9 @@ class ModTool(object): help="Don't do anything in the python/ subdirectory.") ogroup.add_option("--skip-grc", action="store_true", default=False, help="Don't do anything in the grc/ subdirectory.") + ogroup.add_option("--scm-mode", type="choice", choices=('yes', 'no', 'auto'), + default=gr.prefs().get_string('modtool', 'scm_mode', 'no'), + help="Use source control management (yes, no or auto).") ogroup.add_option("-y", "--yes", action="store_true", default=False, help="Answer all questions with 'yes'. This can overwrite and delete your files, so be careful.") parser.add_option_group(ogroup) @@ -101,6 +105,8 @@ class ModTool(object): self._info['blockname'] = options.block_name self._setup_files() self._info['yes'] = options.yes + self.options = options + self._setup_scm() def _setup_files(self): """ Initialise the self._file[] dictionary """ @@ -124,6 +130,17 @@ class ModTool(object): self._file['cmswig'] = os.path.join('swig', 'CMakeLists.txt') self._file['cmfind'] = os.path.join('cmake', 'Modules', 'howtoConfig.cmake') + + def _setup_scm(self, mode='active'): + """ Initialize source control management. """ + if mode == 'active': + self.scm = SCMRepoFactory(self.options, '.').make_active_scm_manager() + else: + self.scm = SCMRepoFactory(self.options, '.').make_empty_scm_manager() + if self.scm is None: + print "Error: Can't set up SCM." + exit(1) + def _check_directory(self, directory): """ Guesses if dir is a valid GNU Radio module directory by looking for CMakeLists.txt and at least one of the subdirs lib/, python/ and swig/. diff --git a/gr-utils/python/modtool/modtool_disable.py b/gr-utils/python/modtool/modtool_disable.py index 0538b47142..4ae2242f99 100644 --- a/gr-utils/python/modtool/modtool_disable.py +++ b/gr-utils/python/modtool/modtool_disable.py @@ -53,6 +53,7 @@ class ModToolDisable(ModTool): def _handle_py_qa(cmake, fname): """ Do stuff for py qa """ cmake.comment_out_lines('GR_ADD_TEST.*'+fname) + self.scm.mark_file_updated(cmake.filename) return True def _handle_py_mod(cmake, fname): """ Do stuff for py extra files """ @@ -64,6 +65,7 @@ class ModToolDisable(ModTool): pymodname = os.path.splitext(fname)[0] initfile = re.sub(r'((from|import)\s+\b'+pymodname+r'\b)', r'#\1', initfile) open(self._file['pyinit'], 'w').write(initfile) + self.scm.mark_file_updated(self._file['pyinit']) return False def _handle_cc_qa(cmake, fname): """ Do stuff for cc qa """ @@ -74,10 +76,12 @@ class ModToolDisable(ModTool): ed.comment_out_lines('#include\s+"%s.h"' % fname_base, comment_str='//') ed.comment_out_lines('%s::suite\(\)' % fname_base, comment_str='//') ed.write() + self.scm.mark_file_updated(self._file['qalib']) elif self._info['version'] == '36': cmake.comment_out_lines('add_executable.*'+fname) cmake.comment_out_lines('target_link_libraries.*'+os.path.splitext(fname)[0]) cmake.comment_out_lines('GR_ADD_TEST.*'+os.path.splitext(fname)[0]) + self.scm.mark_file_updated(cmake.filename) return True def _handle_h_swig(cmake, fname): """ Comment out include files from the SWIG file, @@ -96,6 +100,7 @@ class ModToolDisable(ModTool): if nsubs > 1: print "Hm, changed more then expected while editing %s." % self._file['swig'] open(self._file['swig'], 'w').write(swigfile) + self.scm.mark_file_updated(self._file['swig']) return False def _handle_i_swig(cmake, fname): """ Comment out include files from the SWIG file, @@ -108,6 +113,7 @@ class ModToolDisable(ModTool): print "Changing %s..." % self._file['swig'] swigfile = re.sub('(GR_SWIG_BLOCK_MAGIC2?.+'+blockname+'.+;)', r'//\1', swigfile) open(self._file['swig'], 'w').write(swigfile) + self.scm.mark_file_updated(self._file['swig']) return False # List of special rules: 0: subdir, 1: filename re match, 2: callback special_treatments = ( @@ -145,5 +151,6 @@ class ModToolDisable(ModTool): if not file_disabled: cmake.disable_file(fname) cmake.write() + self.scm.mark_files_updated((os.path.join(subdir, 'CMakeLists.txt'),)) print "Careful: 'gr_modtool disable' does not resolve dependencies." diff --git a/gr-utils/python/modtool/modtool_makexml.py b/gr-utils/python/modtool/modtool_makexml.py index 4b67d1b062..28eabe1b81 100644 --- a/gr-utils/python/modtool/modtool_makexml.py +++ b/gr-utils/python/modtool/modtool_makexml.py @@ -66,6 +66,7 @@ class ModToolMakeXML(ModTool): (params, iosig, blockname) = self._parse_cc_h(f) self._make_grc_xml_from_block_data(params, iosig, blockname) # 2) Go through python/ + # TODO def _search_files(self, path, path_glob): """ Search for files matching pattern in the given path. """ @@ -84,6 +85,7 @@ class ModToolMakeXML(ModTool): generator. Also, check the makefile if the .xml file is in there. If necessary, add. """ fname_xml = '%s_%s.xml' % (self._info['modname'], blockname) + path_to_xml = os.path.join('grc', fname_xml) # Some adaptions for the GRC for inout in ('in', 'out'): if iosig[inout]['max_ports'] == '-1': @@ -93,11 +95,13 @@ class ModToolMakeXML(ModTool): 'name': 'Num %sputs' % inout, 'default': '2', 'in_constructor': False}) - if os.path.isfile(os.path.join('grc', fname_xml)): + file_exists = False + if os.path.isfile(path_to_xml): if not self._info['yes']: if not ask_yes_no('Overwrite existing GRC file?', False): return else: + file_exists = True print "Warning: Overwriting existing GRC file." grc_generator = GRCXMLGenerator( modname=self._info['modname'], @@ -105,13 +109,18 @@ class ModToolMakeXML(ModTool): params=params, iosig=iosig ) - grc_generator.save(os.path.join('grc', fname_xml)) + grc_generator.save(path_to_xml) + if file_exists: + self.scm.mark_files_updated((path_to_xml,)) + else: + self.scm.add_files((path_to_xml,)) if not self._skip_subdirs['grc']: ed = CMakeFileEditor(self._file['cmgrc']) if re.search(fname_xml, ed.cfile) is None and not ed.check_for_glob('*.xml'): print "Adding GRC bindings to grc/CMakeLists.txt..." ed.append_value('install', fname_xml, to_ignore_end='DESTINATION[^()]+') ed.write() + self.scm.mark_files_updated(self._file['cmgrc']) def _parse_cc_h(self, fname_cc): """ Go through a .cc and .h-file defining a block and return info """ diff --git a/gr-utils/python/modtool/modtool_newmod.py b/gr-utils/python/modtool/modtool_newmod.py index 59818b1e62..3e05ecbf48 100644 --- a/gr-utils/python/modtool/modtool_newmod.py +++ b/gr-utils/python/modtool/modtool_newmod.py @@ -26,6 +26,7 @@ import re from optparse import OptionGroup from gnuradio import gr from modtool_base import ModTool, ModToolException +from scm import SCMRepoFactory class ModToolNewModule(ModTool): """ Create a new out-of-tree module """ @@ -45,6 +46,7 @@ class ModToolNewModule(ModTool): return parser def setup(self, options, args): + # Don't call ModTool.setup(), that assumes an existing module. self._info['modname'] = options.module_name if self._info['modname'] is None: if len(args) >= 2: @@ -67,6 +69,8 @@ class ModToolNewModule(ModTool): self._srcdir = gr.prefs().get_string('modtool', 'newmod_path', options.srcdir) if not os.path.isdir(self._srcdir): raise ModToolException('Could not find gr-newmod source dir.') + self.options = options + self._setup_scm(mode='new') def run(self): """ @@ -92,5 +96,7 @@ class ModToolNewModule(ModTool): if os.path.basename(root) == 'howto': os.rename(root, os.path.join(os.path.dirname(root), self._info['modname'])) print "Done." + if self.scm.init_repo(path_to_repo="."): + print "Created repository... you might want to commit before continuing." print "Use 'gr_modtool add' to add a new block to this currently empty module." diff --git a/gr-utils/python/modtool/modtool_rm.py b/gr-utils/python/modtool/modtool_rm.py index 4b69be180a..47128dbc87 100644 --- a/gr-utils/python/modtool/modtool_rm.py +++ b/gr-utils/python/modtool/modtool_rm.py @@ -66,16 +66,19 @@ class ModToolRemove(ModTool): '^\s*s->addTest\(gr::%s::%s::suite\(\)\);\s*$' % ( self._info['modname'], base) ) + self.scm.mark_file_updated(self._file['qalib']) elif ext == '.cc': ed.remove_value('list', '\$\{CMAKE_CURRENT_SOURCE_DIR\}/%s' % filename, to_ignore_start='APPEND test_%s_sources' % self._info['modname']) + self.scm.mark_file_updated(ed.filename) else: filebase = os.path.splitext(filename)[0] ed.delete_entry('add_executable', filebase) ed.delete_entry('target_link_libraries', filebase) ed.delete_entry('GR_ADD_TEST', filebase) ed.remove_double_newlines() + self.scm.mark_file_updated(ed.filename) def _remove_py_test_case(filename=None, ed=None): """ Special function that removes the occurrences of a qa*.{cc,h} file @@ -103,6 +106,7 @@ class ModToolRemove(ModTool): for f in incl_files_deleted + swig_files_deleted: # TODO do this on all *.i files remove_pattern_from_file(self._file['swig'], _make_swig_regex(f)) + self.scm.mark_file_updated(self._file['swig']) if not self._skip_subdirs['python']: py_files_deleted = self._run_subdir('python', ('*.py',), ('GR_PYTHON_INSTALL',), cmakeedit_func=_remove_py_test_case) @@ -148,6 +152,7 @@ class ModToolRemove(ModTool): continue files_deleted.append(b) print "Deleting %s." % f + self.scm.remove_file(f) os.unlink(f) print "Deleting occurrences of %s from %s/CMakeLists.txt..." % (b, path) for var in makefile_vars: @@ -155,4 +160,5 @@ class ModToolRemove(ModTool): if cmakeedit_func is not None: cmakeedit_func(b, ed) ed.write() + self.scm.mark_files_updated(('%s/CMakeLists.txt' % path,)) return files_deleted diff --git a/gr-utils/python/modtool/scm.py b/gr-utils/python/modtool/scm.py new file mode 100644 index 0000000000..ec6023ab3b --- /dev/null +++ b/gr-utils/python/modtool/scm.py @@ -0,0 +1,221 @@ +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +""" Class to handle source code management repositories. """ + +import subprocess + +try: + import git + HAS_GITPYTHON = True +except ImportError: + HAS_GITPYTHON = False +# GitPython is a bit too unstable currently +HAS_GITPYTHON = False + +class InvalidSCMError(Exception): + """ Exception for when trying to access a repo of wrong type. """ + def __init__(self): + Exception.__init__(self) + +### Base class ############################################################### +class SCMRepository(object): + """ Base class to handle interactions with source code management systems. """ + handles_scm_type = '*' + def __init__(self, path_to_repo, is_empty=False): + self.path_to_repo = path_to_repo + self.is_empty = is_empty + + def init_repo(self, path_to_repo=None, add_files=True): + """ Initialize the directory as a repository. Assumes the self.path_to_repo + (or path_to_repo, if specified) does *not* contain a valid repository. + If add_files is True, all files in this directory are added to version control. + Returns true if actually created a repo. + """ + if path_to_repo is not None: + self.path_to_repo = path_to_repo + return False + + def add_files(self, paths_to_files): + """ Add a tuple or list of files to the current repository. """ + pass + + def add_file(self, path_to_file): + """ Add a file to the current repository. """ + self.add_files([path_to_file]) + + def remove_files(self, paths_to_files): + """ Remove a tuple or list of files from the current repository. """ + pass + + def remove_file(self, path_to_file): + """ Remove a file from the current repository. """ + self.remove_files([path_to_file]) + + def mark_files_updated(self, paths_to_files): + """ Mark a list of tuple of files as changed. """ + pass + + def mark_file_updated(self, path_to_file): + """ Mark a file as changed. """ + self.mark_files_updated([path_to_file]) + + def is_active(self): + """ Returns true if this repository manager is operating on an active, source-controlled directory. """ + return self.is_empty + + +### Git ##################################################################### +class GitManagerGitPython(object): + """ Manage git through GitPython (preferred way). """ + def __init__(self, path_to_repo, init=False): + if init: + self.repo = git.Repo.init(path_to_repo, mkdir=False) + else: + try: + self.repo = git.Repo(path_to_repo) + except git.InvalidGitRepositoryError: + self.repo = None + raise InvalidSCMError + self.index = self.repo.index + + def add_files(self, paths_to_files): + """ Adds a tuple of files to the index of the current repository. """ + if self.repo is not None: + self.index.add(paths_to_files) + + def remove_files(self, paths_to_files): + """ Removes a tuple of files from the index of the current repository. """ + if self.repo is not None: + self.index.remove(paths_to_files) + + +class GitManagerShell(object): + """ Call the git executable through a shell. """ + def __init__(self, path_to_repo, init=False, git_executable=None): + self.path_to_repo = path_to_repo + if git_executable is None: + try: + self.git_executable = subprocess.check_output('which git', shell=True).strip() + except (OSError, subprocess.CalledProcessError): + raise InvalidSCMError + try: + if init: + subprocess.check_output([self.git_executable, 'init']) + else: + subprocess.check_output([self.git_executable, 'status']) + except OSError: + raise InvalidSCMError + except subprocess.CalledProcessError: + raise InvalidSCMError + + def add_files(self, paths_to_files): + """ Adds a tuple of files to the index of the current repository. Does not commit. """ + subprocess.check_output([self.git_executable, 'add'] + list(paths_to_files)) + + def remove_files(self, paths_to_files): + """ Removes a tuple of files from the index of the current repository. Does not commit. """ + subprocess.check_output([self.git_executable, 'rm', '--cached'] + list(paths_to_files)) + + +class GitRepository(SCMRepository): + """ Specific to operating on git repositories. """ + handles_scm_type = 'git' + def __init__(self, path_to_repo, is_empty=False): + SCMRepository.__init__(self, path_to_repo, is_empty) + if not is_empty: + try: + if HAS_GITPYTHON: + self.repo_manager = GitManagerGitPython(path_to_repo) + else: + self.repo_manager = GitManagerShell(path_to_repo) + except InvalidSCMError: + self.repo_manager = None + else: + self.repo_manager = None + + def init_repo(self, path_to_repo=None, add_files=True): + """ Makes the directory in self.path_to_repo a git repo. + If add_file is True, all files in this dir are added to the index. """ + SCMRepository.init_repo(self, path_to_repo, add_files) + if HAS_GITPYTHON: + self.repo_manager = GitManagerGitPython(self.path_to_repo, init=True) + else: + self.repo_manager = GitManagerShell(self.path_to_repo, init=True) + if add_files: + self.add_files(('*',)) + return True + + def add_files(self, paths_to_files): + """ Add a file to the current repository. Does not commit. """ + self.repo_manager.add_files(paths_to_files) + + def remove_files(self, paths_to_files): + """ Remove a file from the current repository. Does not commit. """ + self.repo_manager.remove_files(paths_to_files) + + def mark_files_updated(self, paths_to_files): + """ Mark a file as changed. Since this is git, same as adding new files. """ + self.add_files(paths_to_files) + + def is_active(self): + return self.repo_manager is not None + + +############################################################################## +### Factory ################################################################## +class SCMRepoFactory(object): + """ Factory object to create the correct SCM class from the given options and dir. """ + def __init__(self, options, path_to_repo): + self.path_to_repo = path_to_repo + self.options = options + + def make_active_scm_manager(self): + """ Returns a valid, usable object of type SCMRepository. """ + if self.options.scm_mode == 'no': + return SCMRepository(self.path_to_repo) + for glbl in globals().values(): + try: + if issubclass(glbl, SCMRepository): + the_scm = glbl(self.path_to_repo) + if the_scm.is_active(): + print 'Found SCM of type:', the_scm.handles_scm_type + return the_scm + except (TypeError, AttributeError, InvalidSCMError): + pass + if self.options == 'yes': + return None + return SCMRepository(self.path_to_repo) + + def make_empty_scm_manager(self, scm_type='git'): + """ Returns a valid, usable object of type SCMRepository for an unitialized dir. """ + if self.options.scm_mode == 'no': + return SCMRepository(self.path_to_repo) + for glbl in globals().values(): + try: + if issubclass(glbl, SCMRepository): + if glbl.handles_scm_type == scm_type: + return glbl(self.path_to_repo, is_empty=True) + except (TypeError, AttributeError, InvalidSCMError): + pass + if self.options == 'yes': + return None + return SCMRepository(self.path_to_repo) + |