@@ -74,10 +74,7 @@ def get_build_project(git_repo_url: str):
7474 with tempfile .TemporaryDirectory (prefix = "osc_devel_project_git" ) as tmp_dir :
7575 try :
7676 gitea_api .Repo .clone (gitea_conn , gitea_owner , gitea_repo , branch = gitea_branch , quiet = True , directory = tmp_dir )
77- project_build_path = os .path .join (tmp_dir , "project.build" )
78- with open (project_build_path , "r" , encoding = "utf-8" ) as f :
79- project_build = f .readline ().strip ()
80- return project_build
77+ return GitStore (tmp_dir , check = False ).project
8178 except gitea_api .GiteaException :
8279 # "_ObsPrj" repo doesn't exist
8380 return None
@@ -88,63 +85,85 @@ def get_build_project(git_repo_url: str):
8885 # "project.build" file doesn't exist
8986 return None
9087
91- @property
92- def git_project_dir (self ):
93- if not hasattr (self , "_git_project_dir" ):
94- self ._git_project_dir = None
95- path = self .abspath
96- while path and path != "/" :
97- path , _ = os .path .split (path )
98-
99- osc_path = os .path .join (path , ".osc" )
100- git_path = os .path .join (path , ".git" )
101- config_path = os .path .join (path , "_config" )
102- pbuild_path = os .path .join (path , "_pbuild" )
103- subdirs_path = os .path .join (path , "_subdirs" )
104-
105- if (os .path .isdir (osc_path ) or os .path .isdir (git_path )) and (os .path .isfile (config_path ) or os .path .isfile (pbuild_path )):
106- if os .path .isfile (subdirs_path ):
107- # the _subdirs file contains a list of project subdirs that contain packages
108- yaml = ruamel .yaml .YAML ()
109- with open (subdirs_path , "r" ) as f :
110- data = yaml .load (f )
111-
112- # ``subdirs`` is a list of directories, which have subdirectories which are packages
113- subdirs = data .get ("subdirs" , [])
114-
115- # if set to "include", then all top-level directories are packages in addition to ``subdirs``
116- toplevel = data .get ("toplevel" , "" )
117-
118- if toplevel == "include" :
119- subdirs .append ("." )
120-
121- subdirs_abspath = [os .path .abspath (os .path .join (path , subdir )) for subdir in subdirs ]
122-
123- # paths listed in ``subdirs`` are never packages, their subdirs are
124- if self .abspath in subdirs_abspath :
125- break
126-
127- # we're outside paths specified in subdirs -> not a package
128- if os .path .abspath (os .path .join (self .abspath , ".." )) not in subdirs_abspath :
129- break
130- else :
131- # no _subdirs file and self.abspath is not directly under the project dir -> not a valid package
132- if path != os .path .abspath (os .path .join (self .abspath , ".." )):
133- break
134-
135- self ._git_project_dir = path
136- break
137- return self ._git_project_dir
88+ def get_project_obs_scm_store (self ):
89+ from ..obs_scm import Store
90+
91+ if not self .is_package :
92+ return None
93+
94+ try :
95+ store = Store (os .path .join (self .abspath , ".." ))
96+ store .assert_is_project ()
97+ return store
98+ except oscerr .NoWorkingCopy :
99+ return None
100+
101+ def get_project_git_scm_store (self ):
102+ if not self .is_package :
103+ return None
104+
105+ path = self .abspath
106+ while path :
107+ if path == "/" :
108+ # no git repo found
109+ return None
110+
111+ path , _ = os .path .split (path )
112+
113+ if os .path .isdir (os .path .join (path , ".git" )):
114+ break
115+
116+ config_path = os .path .join (path , "_config" )
117+ pbuild_path = os .path .join (path , "_pbuild" )
118+ subdirs_path = os .path .join (path , "_subdirs" )
119+
120+ # we always stop at the top-most directory that contains .git subdir
121+ if not os .path .isfile (config_path ) or os .path .isfile (pbuild_path ):
122+ # it's not a project, stop traversing and return
123+ return None
124+
125+ if os .path .isfile (subdirs_path ):
126+ # the _subdirs file contains a list of project subdirs that contain packages
127+ yaml = ruamel .yaml .YAML ()
128+ with open (subdirs_path , "r" ) as f :
129+ data = yaml .load (f )
130+
131+ # ``subdirs`` is a list of directories, which have subdirectories which are packages
132+ subdirs = data .get ("subdirs" , [])
133+
134+ # if set to "include", then all top-level directories are packages in addition to ``subdirs``
135+ toplevel = data .get ("toplevel" , "" )
136+
137+ if toplevel == "include" :
138+ subdirs .append ("." )
139+
140+ subdirs_abspath = [os .path .abspath (os .path .join (path , subdir )) for subdir in subdirs ]
141+
142+ # paths listed in ``subdirs`` are never packages, their subdirs are
143+ if self .abspath in subdirs_abspath :
144+ return None
145+
146+ # we're outside paths specified in subdirs -> not a package
147+ if os .path .abspath (os .path .join (self .abspath , ".." )) not in subdirs_abspath :
148+ return None
149+ else :
150+ # no _subdirs file and self.abspath is not directly under the project dir -> not a valid package
151+ if path != os .path .abspath (os .path .join (self .abspath , ".." )):
152+ return None
153+
154+ return GitStore (path )
138155
139156 def __init__ (self , path , check = True ):
140157 self .path = path
141158 self .abspath = os .path .abspath (self .path )
142159
160+ self ._apiurl = None
161+ self ._package = None
162+ self ._project = None
163+
143164 self .is_project = False
144165 self .is_package = False
145166
146- self .project_obs_scm_store = None
147-
148167 if os .path .isdir (os .path .join (self .abspath , ".git" )):
149168 # NOTE: we have only one store in project-git for all packages
150169 config_path = os .path .join (self .abspath , "_config" )
@@ -155,16 +174,17 @@ def __init__(self, path, check=True):
155174 else :
156175 # there's .git and no _config/_pbuild in the working directory -> it's a package
157176 self .is_package = True
158- elif self .git_project_dir :
159- from ..obs_scm import Store
160177
161- # there's no .git in the working directory and there's .osc, .git and _config/_pbuild in the parent directory tree -> it's a package
162- self .is_package = True
163- self .project_obs_scm_store = Store (self .git_project_dir , check = False )
178+ self .project_store = None
164179
165- self ._apiurl = None
166- self ._package = None
167- self ._project = None
180+ if self .project_store is None :
181+ self .project_store = self .get_project_obs_scm_store ()
182+
183+ if self .project_store is None :
184+ self .project_store = self .get_project_git_scm_store ()
185+
186+ if self .project_store :
187+ self .package = True
168188
169189 if check and not any ([self .is_project , self .is_package ]):
170190 msg = f"Directory '{ self .path } ' is not a Git SCM working copy"
@@ -193,9 +213,9 @@ def _run_git(self, args):
193213 @property
194214 def apiurl (self ):
195215 if not self ._apiurl :
196- if self .is_package and self .project_obs_scm_store :
216+ if self .is_package and self .project_store :
197217 # read apiurl from parent directory that contains a project with .osc metadata
198- self ._apiurl = self .project_obs_scm_store .apiurl
218+ self ._apiurl = self .project_store .apiurl
199219 if not self ._apiurl :
200220 # HACK: use the currently configured apiurl
201221 self ._apiurl = osc_conf .config ["apiurl" ]
@@ -208,16 +228,32 @@ def apiurl(self, value):
208228 @property
209229 def project (self ):
210230 if not self ._project :
211- if self .is_package and self .project_obs_scm_store :
212- # read project from parent directory that contains a project with .osc metadata
213- self ._project = self .project_obs_scm_store .project
214- if not self ._project :
215- # read project from Gitea (identical owner, repo: _ObsPrj, file: project.build)
216- origin = self ._run_git (["remote" , "get-url" , "origin" ])
217- self ._project = self .get_build_project (origin )
231+ if self .is_package :
232+ # handle _project in a package
233+
234+ if self .project_store :
235+ # read project from detected project store
236+ self ._project = self .project_store .project
237+
238+ if not self ._project :
239+ # read project from Gitea (identical owner, repo: _ObsPrj, file: project.build)
240+ origin = self ._run_git (["remote" , "get-url" , "origin" ])
241+ self ._project = self .get_build_project (origin )
242+
243+ else :
244+ # handle _project in a project
245+
246+ if not self ._project :
247+ # read project from "project.build" file
248+ path = os .path .join (self .abspath , "project.build" )
249+ if os .path .exists (path ):
250+ with open (path , "r" , encoding = "utf-8" ) as f :
251+ self ._project = f .readline ().strip ()
252+
218253 if not self ._project :
219254 # HACK: assume openSUSE:Factory project if project metadata is missing
220255 self ._project = "openSUSE:Factory"
256+
221257 return self ._project
222258
223259 @project .setter
0 commit comments