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

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

@ -69,3 +69,8 @@ module GitGuts =
let buf = Array.zeroCreate 4 let buf = Array.zeroCreate 4
inp.Read( buf, 0, 4 ) |> ignore inp.Read( buf, 0, 4 ) |> ignore
( int(buf.[0]) <<< 24 ) ||| ( int(buf.[1]) <<< 16 ) ||| ( int(buf.[2]) <<< 8 ) ||| int(buf.[3]) ( 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 = let runGitGc repoDir =
// run git garbage collection // run git garbage collection
runGit repoDir "gc" [] |> ignore 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