Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita1e2f63

Browse files
committed
submodule: Fleshed out interface, and a partial test which is not yet usable. It showed that the ConfigParser needs some work. If the root is set, it also needs to refer to the root_commit instead of to the root-tree, as it will have to decide whether it works on the working tree's version of the .gitmodules file or the one in the repository
1 parenta1d1d2c commita1e2f63

File tree

5 files changed

+171
-34
lines changed

5 files changed

+171
-34
lines changed

‎lib/git/config.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
fromgit.odictimportOrderedDict
1616
fromgit.utilimportLockFile
1717

18-
__all__= ('GitConfigParser', )
18+
__all__= ('GitConfigParser','SectionConstraint')
1919

2020
classMetaParserBuilder(type):
2121
"""Utlity class wrapping base-class methods into decorators that assure read-only properties"""
@@ -63,7 +63,29 @@ def flush_changes(self, *args, **kwargs):
6363
flush_changes.__name__=non_const_func.__name__
6464
returnflush_changes
6565

66+
67+
classSectionConstraint(object):
68+
"""Constrains a ConfigParser to only option commands which are constrained to
69+
always use the section we have been initialized with.
70+
71+
It supports all ConfigParser methods that operate on an option"""
72+
__slots__= ("_config","_section_name")
73+
_valid_attrs_= ("get_value","set_value","get","set","getint","getfloat","getboolean","has_option")
6674

75+
def__init__(self,config,section):
76+
self._config=config
77+
self._section_name=section
78+
79+
def__getattr__(self,attr):
80+
ifattrinself._valid_attrs_:
81+
returnlambda*args,**kwargs:self._call_config(attr,*args,**kwargs)
82+
returnsuper(SectionConstraint,self).__getattribute__(attr)
83+
84+
def_call_config(self,method,*args,**kwargs):
85+
"""Call the configuration at the given method which must take a section name
86+
as first argument"""
87+
returngetattr(self._config,method)(self._section_name,*args,**kwargs)
88+
6789

6890
classGitConfigParser(cp.RawConfigParser,object):
6991
"""Implements specifics required to read git style configuration files.

‎lib/git/ext/gitdb

Submodule gitdb updated from 78665b1 to 2ddc5ba

‎lib/git/objects/submodule.py

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
importbase
2+
fromcStringIOimportStringIO
3+
fromgit.configimportGitConfigParser
4+
fromgit.utilimportjoin_path_native
5+
fromgit.excimportInvalidGitRepositoryError,NoSuchPathError
26

37
__all__= ("Submodule", )
48

@@ -7,10 +11,115 @@ class Submodule(base.IndexObject):
711
represents a commit in the submodule's repository which is to be checked out
812
at the path of this instance.
913
The submodule type does not have a string type associated with it, as it exists
10-
solely as a marker in the tree and index"""
14+
solely as a marker in the tree and index.
15+
16+
All methods work in bare and non-bare repositories."""
17+
18+
kModulesFile='.gitmodules'
1119

1220
# this is a bogus type for base class compatability
1321
type='submodule'
1422

15-
# TODO: Add functions to retrieve a repo for the submodule, to allow
16-
# its initiailization and handling
23+
__slots__= ('_root_tree','_url','_ref')
24+
25+
def_set_cache_(self,attr):
26+
ifattr=='size':
27+
raiseValueError("Submodules do not have a size as they do not refer to anything in this repository")
28+
elifattr=='_root_tree':
29+
# set a default value, which is the root tree of the current head
30+
self._root_tree=self.repo.tree()
31+
elifattrin ('path','_url','_ref'):
32+
reader=self.config_reader()
33+
# default submodule values
34+
self._path=reader.get_value('path')
35+
self._url=reader.get_value('url')
36+
# git-python extension values - optional
37+
self._ref=reader.get_value('ref','master')
38+
else:
39+
super(Submodule,self)._set_cache_(attr)
40+
# END handle attribute name
41+
42+
def_fp_config(self):
43+
""":return: Configuration file as StringIO - we only access it through the respective blob's data"""
44+
returnStringIO(self._root_tree[self.kModulesFile].datastream.read())
45+
46+
def_config_parser(self,read_only):
47+
""":return: Config Parser constrained to our submodule in read or write mode"""
48+
parser=GitConfigParser(self._fp_config(),read_only=read_only)
49+
returnSectionConstraint(parser,'submodule "%s"'%self.path)
50+
51+
#{ Edit Interface
52+
53+
@classmethod
54+
defadd(cls,repo,path,url,skip_init=False):
55+
"""Add a new submodule to the given repository. This will alter the index
56+
as well as the .gitmodules file, but will not create a new commit.
57+
:param repo: Repository instance which should receive the submodule
58+
:param path: repository-relative path at which the submodule should be located
59+
It will be created as required during the repository initialization.
60+
:param url: git-clone compatible URL, see git-clone reference for more information
61+
:param skip_init: if True, the new repository will not be cloned to its location.
62+
:return: The newly created submodule instance"""
63+
64+
defset_root_tree(self,root_tree):
65+
"""Set this instance to use the given tree which is supposed to contain the
66+
.gitmodules blob.
67+
:param root_tree: Tree'ish reference pointing at the root_tree
68+
:raise ValueError: if the root_tree didn't contain the .gitmodules blob."""
69+
tree=self.repo.tree(root_tree)
70+
ifself.kModulesFilenotintree:
71+
raiseValueError("Tree %s did not contain the %s file"% (root_tree,self.kModulesFile))
72+
# END handle exceptions
73+
self._root_tree=tree
74+
75+
# clear the possibly changing values
76+
del(self.path)
77+
del(self._ref)
78+
del(self._url)
79+
80+
defconfig_writer(self):
81+
""":return: a config writer instance allowing you to read and write the data
82+
belonging to this submodule into the .gitmodules file."""
83+
returnself._config_parser(read_only=False)
84+
85+
#} END edit interface
86+
87+
#{ Query Interface
88+
89+
defmodule(self):
90+
""":return: Repo instance initialized from the repository at our submodule path
91+
:raise InvalidGitRepositoryError: if a repository was not available"""
92+
ifself.repo.bare:
93+
raiseInvalidGitRepositoryError("Cannot retrieve module repository in bare parent repositories")
94+
# END handle bare mode
95+
96+
repo_path=join_path_native(self.repo.working_tree_dir,self.path)
97+
try:
98+
returnRepo(repo_path)
99+
except (InvalidGitRepositoryError,NoSuchPathError):
100+
raiseInvalidGitRepositoryError("No valid repository at %s"%self.path)
101+
# END handle exceptions
102+
103+
defref(self):
104+
""":return: The reference's name that we are to checkout"""
105+
returnself._ref
106+
107+
defurl(self):
108+
""":return: The url to the repository which our module-repository refers to"""
109+
returnself._url
110+
111+
defroot_tree(self):
112+
""":return: Tree instance referring to the tree which contains the .gitmodules file
113+
we are to use
114+
:note: will always point to the current head's root tree if it was not set explicitly"""
115+
returnself._root_tree
116+
117+
defconfig_reader(self):
118+
""":return: ConfigReader instance which allows you to qurey the configuration values
119+
of this submodule, as provided by the .gitmodules file
120+
:note: The config reader will actually read the data directly from the repository
121+
and thus does not need nor care about your working tree.
122+
:note: Should be cached by the caller and only kept as long as needed"""
123+
returnself._config_parser.read_only(read_only=True)
124+
125+
#} END query interface

‎lib/git/remote.py

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
fromexcimportGitCommandError
99
fromobjectsimportCommit
10-
fromConfigParserimportNoOptionError
10+
fromConfigParserimportNoOptionError
11+
fromconfigimportSectionConstraint
1112

1213
fromgit.utilimport (
1314
LazyMixin,
@@ -30,29 +31,6 @@
3031

3132
__all__= ('RemoteProgress','PushInfo','FetchInfo','Remote')
3233

33-
class_SectionConstraint(object):
34-
"""Constrains a ConfigParser to only option commands which are constrained to
35-
always use the section we have been initialized with.
36-
37-
It supports all ConfigParser methods that operate on an option"""
38-
__slots__= ("_config","_section_name")
39-
_valid_attrs_= ("get_value","set_value","get","set","getint","getfloat","getboolean","has_option")
40-
41-
def__init__(self,config,section):
42-
self._config=config
43-
self._section_name=section
44-
45-
def__getattr__(self,attr):
46-
ifattrinself._valid_attrs_:
47-
returnlambda*args,**kwargs:self._call_config(attr,*args,**kwargs)
48-
returnsuper(_SectionConstraint,self).__getattribute__(attr)
49-
50-
def_call_config(self,method,*args,**kwargs):
51-
"""Call the configuration at the given method which must take a section name
52-
as first argument"""
53-
returngetattr(self._config,method)(self._section_name,*args,**kwargs)
54-
55-
5634
classRemoteProgress(object):
5735
"""
5836
Handler providing an interface to parse progress information emitted by git-push
@@ -449,7 +427,7 @@ def _config_section_name(self):
449427

450428
def_set_cache_(self,attr):
451429
ifattr=="_config_reader":
452-
self._config_reader=_SectionConstraint(self.repo.config_reader(),self._config_section_name())
430+
self._config_reader=SectionConstraint(self.repo.config_reader(),self._config_section_name())
453431
else:
454432
super(Remote,self)._set_cache_(attr)
455433

@@ -735,4 +713,4 @@ def config_writer(self):
735713

736714
# clear our cache to assure we re-read the possibly changed configuration
737715
del(self._config_reader)
738-
return_SectionConstraint(writer,self._config_section_name())
716+
returnSectionConstraint(writer,self._config_section_name())

‎test/git/test_submodule.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,35 @@
66

77
classTestSubmodule(TestBase):
88

9-
deftest_base(self):
10-
# TODO
11-
pass
9+
kCOTag='0.1.6'
10+
11+
def_do_base_tests(self,rwrepo):
12+
"""Perform all tests in the given repository, it may be bare or nonbare"""
13+
14+
# uncached path/url - retrieves information from .gitmodules file
15+
16+
# changing the root_tree yields new values when querying them (i.e. cache is cleared)
17+
18+
19+
# size is invalid
20+
self.failUnlessRaises(ValueError,getattr,sm,'size')
21+
22+
# fails if tree has no gitmodule file
23+
24+
ifrwrepo.bare:
25+
# module fails
26+
pass
27+
else:
28+
# get the module repository
29+
pass
30+
# END bare handling
31+
32+
@with_rw_repo(kCOTag)
33+
deftest_base_rw(self,rwrepo):
34+
self._do_base_tests(rwrepo)
35+
36+
@with_bare_rw_repo
37+
deftest_base_bare(self,rwrepo):
38+
self._do_base_tests(rwrepo)
39+
1240

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp