9898import pathlib
9999
100100import dfetch .commands .command
101- import dfetch .project
102101from dfetch .log import get_logger
103- from dfetch .manifest .project import ProjectEntry
104- from dfetch .project .git import GitSubProject
105- from dfetch .project .subproject import SubProject
106102from dfetch .project .superproject import SuperProject
107- from dfetch .project .svn import SvnSubProject
108103from dfetch .util .util import catch_runtime_exceptions , in_directory
109- from dfetch .vcs .git import GitLocalRepo
110- from dfetch .vcs .svn import SvnRepo
111104
112105logger = get_logger (__name__ )
113106
@@ -143,7 +136,7 @@ def create_menu(subparsers: dfetch.commands.command.SubparserActionType) -> None
143136 def __call__ (self , args : argparse .Namespace ) -> None :
144137 """Perform the diff."""
145138 superproject = SuperProject ()
146- revs = [ r for r in args .revs . strip ( ":" ). split ( ":" , maxsplit = 1 ) if r ]
139+ old_rev , new_rev = self . _parse_revs ( args .revs )
147140
148141 with in_directory (superproject .root_directory ):
149142 exceptions : list [str ] = []
@@ -153,49 +146,44 @@ def __call__(self, args: argparse.Namespace) -> None:
153146 f"No (such) project found! { ', ' .join (args .projects )} "
154147 )
155148 for project in projects :
156- patch_name = f"{ project .name } .patch"
157149 with catch_runtime_exceptions (exceptions ) as exceptions :
158- patch = _get_sub_project (superproject , project ).diff (revs )
159-
160- _dump_patch (
161- superproject .root_directory , revs , project , patch_name , patch
162- )
150+ if not os .path .exists (project .destination ):
151+ raise RuntimeError (
152+ "You cannot generate a diff of a project that was never fetched"
153+ )
154+ subproject = superproject .get_sub_project (project )
155+
156+ if subproject is None :
157+ raise RuntimeError (
158+ "Can only create patch if your project is an SVN or Git repo" ,
159+ )
160+ old_rev = old_rev or subproject .metadata_revision ()
161+ patch = subproject .diff (old_rev , new_rev )
162+
163+ msg = self ._rev_msg (old_rev , new_rev )
164+ if patch :
165+ patch_path = pathlib .Path (f"{ project .name } .patch" )
166+ logger .print_info_line (
167+ project .name ,
168+ f"Generating patch { patch_path } { msg } in { superproject .root_directory } " ,
169+ )
170+ patch_path .write_text (patch , encoding = "UTF-8" )
171+ else :
172+ logger .print_info_line (project .name , f"No diffs found { msg } " )
163173
164174 if exceptions :
165175 raise RuntimeError ("\n " .join (exceptions ))
166176
177+ @staticmethod
178+ def _parse_revs (revs_arg : str ) -> tuple [str , str ]:
179+ revs = [r for r in revs_arg .strip (":" ).split (":" , maxsplit = 1 ) if r ]
167180
168- def _get_sub_project (superproject : SuperProject , project : ProjectEntry ) -> SubProject :
169- """Get the subproject in the same vcs type as the superproject."""
170- if not os .path .exists (project .destination ):
171- raise RuntimeError (
172- "You cannot generate a diff of a project that was never fetched"
173- )
174- if GitLocalRepo (superproject .root_directory ).is_git ():
175- return GitSubProject (project )
176- if SvnRepo (superproject .root_directory ).is_svn ():
177- return SvnSubProject (project )
178-
179- raise RuntimeError (
180- "Can only create patch if your project is an SVN or Git repo" ,
181- )
182-
183-
184- def _dump_patch (
185- path : str , revs : list [str ], project : ProjectEntry , patch_name : str , patch : str
186- ) -> None :
187- """Dump the patch to a file."""
188- if patch :
189- rev_range = f"from { revs [0 ]} to { revs [1 ]} " if revs [1 ] else f"since { revs [0 ]} "
190- logger .print_info_line (
191- project .name ,
192- f"Generating patch { patch_name } { rev_range } in { os .path .dirname (path )} " ,
193- )
194- pathlib .Path (patch_name ).write_text (patch , encoding = "UTF-8" )
195- else :
196- if revs [1 ]:
197- msg = f"No diffs found from { revs [0 ]} to { revs [1 ]} "
198- else :
199- msg = f"No diffs found since { revs [0 ]} "
200-
201- logger .print_info_line (project .name , msg )
181+ if len (revs ) == 0 :
182+ return "" , ""
183+ if len (revs ) == 1 :
184+ return revs [0 ], ""
185+ return revs [0 ], revs [1 ]
186+
187+ @staticmethod
188+ def _rev_msg (old_rev : str , new_rev : str ) -> str :
189+ return f"from { old_rev } to { new_rev } " if new_rev else f"since { old_rev } "
0 commit comments