@@ -279,3 +279,207 @@ extension SystemCommand.GetentCommand: Output {
279279 return entries
280280 }
281281}
282+
283+ extension SystemCommand {
284+ public static func git( executable: Executable = GitCommand . defaultExecutable, workingDir: FilePath ? = nil ) -> GitCommand {
285+ GitCommand ( executable: executable, workingDir: workingDir)
286+ }
287+
288+ public struct GitCommand {
289+ public static var defaultExecutable : Executable { . name( " git " ) }
290+
291+ var executable : Executable
292+
293+ var workingDir : FilePath ?
294+
295+ internal init ( executable: Executable , workingDir: FilePath ? ) {
296+ self . executable = executable
297+ self . workingDir = workingDir
298+ }
299+
300+ func config( ) -> Configuration {
301+ var args : [ String ] = [ ]
302+
303+ if let workingDir {
304+ args += [ " -C " , " \( workingDir) " ]
305+ }
306+
307+ return Configuration (
308+ executable: self . executable,
309+ arguments: Arguments ( args) ,
310+ environment: . inherit
311+ )
312+ }
313+
314+ public func _init( ) -> InitCommand {
315+ InitCommand ( self )
316+ }
317+
318+ public struct InitCommand {
319+ var git : GitCommand
320+
321+ internal init ( _ git: GitCommand ) {
322+ self . git = git
323+ }
324+
325+ public func config( ) -> Configuration {
326+ var c = self . git. config ( )
327+
328+ var args = c. arguments. storage. map ( \. description)
329+
330+ args += [ " init " ]
331+
332+ c. arguments = . init( args)
333+
334+ return c
335+ }
336+ }
337+
338+ public func commit( _ options: CommitCommand . Option ... ) -> CommitCommand {
339+ self . commit ( options: options)
340+ }
341+
342+ public func commit( options: [ CommitCommand . Option ] ) -> CommitCommand {
343+ CommitCommand ( self , options: options)
344+ }
345+
346+ public struct CommitCommand {
347+ var git : GitCommand
348+
349+ var options : [ Option ]
350+
351+ internal init ( _ git: GitCommand , options: [ Option ] ) {
352+ self . git = git
353+ self . options = options
354+ }
355+
356+ public enum Option {
357+ case allowEmpty
358+ case allowEmptyMessage
359+ case message( String )
360+
361+ public func args( ) -> [ String ] {
362+ switch self {
363+ case . allowEmpty:
364+ [ " --allow-empty " ]
365+ case . allowEmptyMessage:
366+ [ " --allow-empty-message " ]
367+ case let . message( message) :
368+ [ " -m " , message]
369+ }
370+ }
371+ }
372+
373+ public func config( ) -> Configuration {
374+ var c = self . git. config ( )
375+
376+ var args = c. arguments. storage. map ( \. description)
377+
378+ args += [ " commit " ]
379+ for option in self . options {
380+ args += option. args ( )
381+ }
382+
383+ c. arguments = . init( args)
384+
385+ return c
386+ }
387+ }
388+
389+ public func log( _ options: LogCommand . Option ... ) -> LogCommand {
390+ LogCommand ( self , options)
391+ }
392+
393+ public struct LogCommand {
394+ var git : GitCommand
395+ var options : [ Option ]
396+
397+ internal init ( _ git: GitCommand , _ options: [ Option ] ) {
398+ self . git = git
399+ self . options = options
400+ }
401+
402+ public enum Option {
403+ case maxCount( Int )
404+ case pretty( String )
405+
406+ func args( ) -> [ String ] {
407+ switch self {
408+ case let . maxCount( num) :
409+ return [ " --max-count= \( num) " ]
410+ case let . pretty( format) :
411+ return [ " --pretty= \( format) " ]
412+ }
413+ }
414+ }
415+
416+ public func config( ) -> Configuration {
417+ var c = self . git. config ( )
418+
419+ var args = c. arguments. storage. map ( \. description)
420+
421+ args += [ " log " ]
422+
423+ for opt in self . options {
424+ args += opt. args ( )
425+ }
426+
427+ c. arguments = . init( args)
428+
429+ return c
430+ }
431+ }
432+
433+ public func diffIndex( _ options: DiffIndexCommand . Option ... , treeIsh: String ? ) -> DiffIndexCommand {
434+ DiffIndexCommand ( self , options, treeIsh: treeIsh)
435+ }
436+
437+ public struct DiffIndexCommand {
438+ var git : GitCommand
439+ var options : [ Option ]
440+ var treeIsh : String ?
441+
442+ internal init ( _ git: GitCommand , _ options: [ Option ] , treeIsh: String ? ) {
443+ self . git = git
444+ self . options = options
445+ self . treeIsh = treeIsh
446+ }
447+
448+ public enum Option {
449+ case quiet
450+
451+ func args( ) -> [ String ] {
452+ switch self {
453+ case . quiet:
454+ return [ " --quiet " ]
455+ }
456+ }
457+ }
458+
459+ public func config( ) -> Configuration {
460+ var c = self . git. config ( )
461+
462+ var args = c. arguments. storage. map ( \. description)
463+
464+ args += [ " diff-index " ]
465+
466+ for opt in self . options {
467+ args += opt. args ( )
468+ }
469+
470+ if let treeIsh = self . treeIsh {
471+ args += [ treeIsh]
472+ }
473+
474+ c. arguments = . init( args)
475+
476+ return c
477+ }
478+ }
479+ }
480+ }
481+
482+ extension SystemCommand . GitCommand . LogCommand : Output { }
483+ extension SystemCommand . GitCommand . DiffIndexCommand : Runnable { }
484+ extension SystemCommand . GitCommand . InitCommand : Runnable { }
485+ extension SystemCommand . GitCommand . CommitCommand : Runnable { }
0 commit comments