Use Spectre to parse command-line arguments.

master
Pacman Ghost 2 years ago
parent adaa1aa0c5
commit 2c95104ee9
  1. 102
      cli/Program.fs
  2. 4
      cli/cli.fsproj
  3. 5
      git-guts/GitGuts.fs
  4. 5
      git-guts/tests/Utils.fs

@ -1,42 +1,56 @@
open System
open System.IO
open Argu
open Spectre.Console
open Spectre.Console.Cli
open git_guts
// --------------------------------------------------------------------
type DumpPackFileArgs =
| [<AltCommandLine("-f")>] Pack_Filename of packFilename:string
interface IArgParserTemplate with
member this.Usage =
match this with
| Pack_Filename _ -> "Pack file to dump."
let _getPackFilename packFilename repoDir =
if packFilename <> "" then
packFilename
else
// auto-detect pack files
let fnames = findRepoPacks repoDir
match fnames.Length with
| 0 -> failwith "No pack file was specified."
| 1 -> fnames.[0]
| _ -> failwith "Multiple pack files were found."
// --------------------------------------------------------------------
type CliArguments =
| [<AltCommandLine("-r")>] Repo of path:string
| [<CliPrefix(CliPrefix.None)>] Dump_PackFile of ParseResults<DumpPackFileArgs>
interface IArgParserTemplate with
member this.Usage =
match this with
| Repo _ -> "specify the git repo directory."
| Dump_PackFile _ -> "dump a pack file."
type AppSettings() =
inherit CommandSettings()
[<CommandOption( "-r|--repo <GIT-REPO>" )>]
member val RepoDir = "." with get, set
override this.Validate() =
this.RepoDir <- Path.GetFullPath( this.RepoDir )
if not ( Directory.Exists this.RepoDir ) then
ValidationResult.Error( "Can't find git repo directory." )
else
ValidationResult.Success()
type CliExiter() =
interface IExiter with
member __.Name = "CliExiter"
member __.Exit( msg, code ) =
if code = ErrorCode.HelpText then
// show the help text
printfn "%s" msg
exit 0
else
// show the error message (sans help text)
let pos = msg.IndexOf "USAGE:"
let msg2 = msg.Substring( 0, pos-1 )
printfn "%s" msg2
printfn "Use --help to get help."
exit 1
// FUDGE! We need this for the settings in AppSettings to be recognized :-/
type AppCommand() =
inherit Command<AppSettings>()
override this.Execute( ctx, settings ) =
failwith "No command was specified."
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type DumpPackFileSettings() =
inherit AppSettings()
[<CommandOption( "-f|--pack-file <PACK-FILE>" )>]
member val PackFilename = "" with get, set
type DumpPackFileCommand() =
inherit Command<DumpPackFileSettings>()
override this.Execute( ctx, settings ) =
let fname = _getPackFilename settings.PackFilename settings.RepoDir
dumpPackFile fname
0
// --------------------------------------------------------------------
@ -50,23 +64,11 @@ let main argv =
disableSpectreCapabilities
// parse the command-line arguments
let programName = System.AppDomain.CurrentDomain.FriendlyName
let parser = ArgumentParser.Create<CliArguments>( programName=programName, helpTextMessage="Examine the guts of a git repo.", errorHandler=CliExiter() )
let parsedArgs = parser.Parse argv
let repoDir = Path.GetFullPath( parsedArgs.GetResult( Repo, defaultValue="." ) )
if not ( Directory.Exists repoDir ) then
failwith "Can't find git repo directory."
// perform the requested action
if parsedArgs.Contains Dump_PackFile then
// dump a pack file
let args = parsedArgs.GetResult Dump_PackFile
if not ( args.Contains Pack_Filename ) then
failwith "No pack file was specified." // nb: because [<Mandatory>] doesn't seem to work :-/
let fname = args.GetResult Pack_Filename
dumpPackFile fname
else
// no action was specified - print help
printfn "%s" ( parser.PrintUsage() )
0
let app = CommandApp<AppCommand>()
app.Configure( fun cfg ->
cfg.SetApplicationName( System.AppDomain.CurrentDomain.FriendlyName ) |> ignore
cfg.AddCommand<DumpPackFileCommand>( "dump-packfile" ).WithDescription(
"Dump a pack file."
) |> ignore
)
app.Run( argv )

@ -10,10 +10,6 @@
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Argu" Version="6.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\git-guts\git-guts.fsproj" />
</ItemGroup>

@ -69,3 +69,8 @@ module GitGuts =
let buf = Array.zeroCreate 4
inp.Read( buf, 0, 4 ) |> ignore
( int(buf.[0]) <<< 24 ) ||| ( int(buf.[1]) <<< 16 ) ||| ( int(buf.[2]) <<< 8 ) ||| int(buf.[3])
let findRepoPacks repoDir =
// find pack files in the git repo
let dname = Path.Combine( repoDir, ".git/objects/pack" )
Directory.GetFiles( dname, "*.pack" )

@ -104,8 +104,3 @@ module Utils =
let runGitGc repoDir =
// run git garbage collection
runGit repoDir "gc" [] |> ignore
let findRepoPacks repoDir =
// find pack files in the git repo
let dname = Path.Combine( repoDir, ".git/objects/pack" )
Directory.GetFiles( dname, "*.pack" )

Loading…
Cancel
Save