Fix the handling of help in the cli commands

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13293
This commit is contained in:
Marek Roszko 2023-01-01 11:50:40 -05:00
parent 16fd586c41
commit e335423cb6
37 changed files with 123 additions and 56 deletions

View File

@ -25,11 +25,44 @@
#include <sstream>
int CLI::COMMAND::Perform( KIWAY& aKiway )
CLI::COMMAND::COMMAND( const std::string& aName ) :
m_name( aName ),
m_argParser( aName, "", argparse::default_arguments::none )
{
m_argParser.add_argument( ARG_HELP_SHORT, ARG_HELP )
.default_value( false )
.help( UTF8STDSTR( ARG_HELP_DESC ) )
.implicit_value( true )
.nargs( 0 );
}
void CLI::COMMAND::PrintHelp()
{
std::stringstream ss;
ss << m_argParser;
wxPrintf( FROM_UTF8( ss.str().c_str() ) );
}
int CLI::COMMAND::Perform( KIWAY& aKiway )
{
if( m_argParser[ARG_HELP] == true )
{
PrintHelp();
return 0;
}
return doPerform( aKiway );
}
int CLI::COMMAND::doPerform( KIWAY& aKiway )
{
// default case if we aren't overloaded, just print the help
PrintHelp();
return EXIT_CODES::OK;
}

View File

@ -26,25 +26,44 @@
#define UTF8STDSTR( s ) ( std::string( s.utf8_str() ) )
#define ARG_VERSION "--version"
#define ARG_HELP "--help"
#define ARG_HELP_SHORT "-h"
#define ARG_HELP_DESC _( "shows help message and exits" )
namespace CLI
{
class COMMAND
{
public:
COMMAND( const std::string& aName,
argparse::default_arguments aDefaultArgs = argparse::default_arguments::help ) :
m_name( aName ),
m_argParser( aName, "", aDefaultArgs ){};
/**
* Define a new COMMAND instance
*
* @param aName The name of the command that is to be used in the cli interface
*/
COMMAND( const std::string& aName );
virtual int Perform( KIWAY& aKiway );
/**
* Entry point to processing commands from args and doing work
*/
int Perform( KIWAY& aKiway );
virtual ~COMMAND() = default;
argparse::ArgumentParser& GetArgParser() { return m_argParser; }
const std::string& GetName() const { return m_name; }
void PrintHelp();
protected:
/**
* The internal handler that should be overloaded to implement command specific
* processing and work.
*
* If not overloaded, the command will simply emit the help options by default
*/
virtual int doPerform( KIWAY& aKiway );
std::string m_name;
argparse::ArgumentParser m_argParser;
};

View File

@ -101,7 +101,7 @@ void CLI::EXPORT_PCB_BASE_COMMAND::addLayerArg( bool aRequire )
}
int CLI::EXPORT_PCB_BASE_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_BASE_COMMAND::doPerform( KIWAY& aKiway )
{
if( m_hasLayerArg )
{

View File

@ -39,9 +39,8 @@ struct EXPORT_PCB_BASE_COMMAND : public COMMAND
{
EXPORT_PCB_BASE_COMMAND( const std::string& aName );
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
LSET convertLayerStringList( wxString& aLayerString, bool& aLayerArgSet ) const;
void addLayerArg( bool aRequire );

View File

@ -94,7 +94,7 @@ CLI::EXPORT_PCB_DRILL_COMMAND::EXPORT_PCB_DRILL_COMMAND() : EXPORT_PCB_BASE_COMM
}
int CLI::EXPORT_PCB_DRILL_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_DRILL_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_PCB_DRILL> drillJob( new JOB_EXPORT_PCB_DRILL( true ) );

View File

@ -30,7 +30,8 @@ class EXPORT_PCB_DRILL_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_PCB_DRILL_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -61,9 +61,9 @@ CLI::EXPORT_PCB_DXF_COMMAND::EXPORT_PCB_DXF_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_PCB_DXF_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_DXF_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
int baseExit = EXPORT_PCB_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;

View File

@ -30,7 +30,8 @@ class EXPORT_PCB_DXF_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_PCB_DXF_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -114,9 +114,9 @@ int CLI::EXPORT_PCB_GERBER_COMMAND::populateJob( JOB_EXPORT_PCB_GERBER* aJob )
}
int CLI::EXPORT_PCB_GERBER_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_GERBER_COMMAND::doPerform( KIWAY& aKiway )
{
int exitCode = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
int exitCode = EXPORT_PCB_BASE_COMMAND::doPerform( aKiway );
if( exitCode != EXIT_CODES::OK )
return exitCode;

View File

@ -39,9 +39,8 @@ public:
EXPORT_PCB_GERBER_COMMAND( const std::string& aName );
EXPORT_PCB_GERBER_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
int populateJob( JOB_EXPORT_PCB_GERBER* aJob );
};
} // namespace CLI

View File

@ -51,9 +51,9 @@ CLI::EXPORT_PCB_GERBERS_COMMAND::EXPORT_PCB_GERBERS_COMMAND() :
}
int CLI::EXPORT_PCB_GERBERS_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_GERBERS_COMMAND::doPerform( KIWAY& aKiway )
{
int exitCode = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
int exitCode = EXPORT_PCB_BASE_COMMAND::doPerform( aKiway );
if( exitCode != EXIT_CODES::OK )
return exitCode;

View File

@ -30,7 +30,8 @@ class EXPORT_PCB_GERBERS_COMMAND : public EXPORT_PCB_GERBER_COMMAND
public:
EXPORT_PCB_GERBERS_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -62,9 +62,9 @@ CLI::EXPORT_PCB_PDF_COMMAND::EXPORT_PCB_PDF_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_PCB_PDF_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_PDF_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
int baseExit = EXPORT_PCB_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;

View File

@ -30,7 +30,8 @@ class EXPORT_PCB_PDF_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_PCB_PDF_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -83,9 +83,9 @@ CLI::EXPORT_PCB_POS_COMMAND::EXPORT_PCB_POS_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_PCB_POS_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_POS_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
int baseExit = EXPORT_PCB_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;

View File

@ -30,7 +30,8 @@ class EXPORT_PCB_POS_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_PCB_POS_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -89,7 +89,7 @@ CLI::EXPORT_PCB_STEP_COMMAND::EXPORT_PCB_STEP_COMMAND() : COMMAND( "step" )
m_argParser.add_argument( ARG_INPUT ).help( UTF8STDSTR( _( "Input file" ) ) );
}
int CLI::EXPORT_PCB_STEP_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_STEP_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_PCB_STEP> step( new JOB_EXPORT_PCB_STEP( true ) );

View File

@ -29,7 +29,8 @@ struct EXPORT_PCB_STEP_COMMAND : public COMMAND
{
EXPORT_PCB_STEP_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
}

View File

@ -66,9 +66,9 @@ CLI::EXPORT_PCB_SVG_COMMAND::EXPORT_PCB_SVG_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_PCB_SVG_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_PCB_SVG_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
int baseExit = EXPORT_PCB_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;

View File

@ -29,7 +29,8 @@ struct EXPORT_PCB_SVG_COMMAND : public EXPORT_PCB_BASE_COMMAND
{
EXPORT_PCB_SVG_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -37,7 +37,7 @@ CLI::EXPORT_SCH_NETLIST_COMMAND::EXPORT_SCH_NETLIST_COMMAND() : EXPORT_PCB_BASE_
}
int CLI::EXPORT_SCH_NETLIST_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_SCH_NETLIST_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_SCH_NETLIST> netJob =
std::make_unique<JOB_EXPORT_SCH_NETLIST>( true );

View File

@ -30,7 +30,8 @@ class EXPORT_SCH_NETLIST_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_SCH_NETLIST_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -54,7 +54,7 @@ CLI::EXPORT_SCH_PDF_COMMAND::EXPORT_SCH_PDF_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_SCH_PDF_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_SCH_PDF_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_SCH_PDF> pdfJob = std::make_unique<JOB_EXPORT_SCH_PDF>( true );

View File

@ -30,7 +30,8 @@ class EXPORT_SCH_PDF_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_SCH_PDF_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -34,7 +34,7 @@ CLI::EXPORT_SCH_PYTHONBOM_COMMAND::EXPORT_SCH_PYTHONBOM_COMMAND() :
}
int CLI::EXPORT_SCH_PYTHONBOM_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_SCH_PYTHONBOM_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_SCH_PYTHONBOM> bomJob =
std::make_unique<JOB_EXPORT_SCH_PYTHONBOM>( true );

View File

@ -30,7 +30,8 @@ class EXPORT_SCH_PYTHONBOM_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_SCH_PYTHONBOM_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -54,7 +54,7 @@ CLI::EXPORT_SCH_SVG_COMMAND::EXPORT_SCH_SVG_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_SCH_SVG_COMMAND::Perform( KIWAY& aKiway )
int CLI::EXPORT_SCH_SVG_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_SCH_SVG> svgJob = std::make_unique<JOB_EXPORT_SCH_SVG>( true );

View File

@ -30,7 +30,8 @@ class EXPORT_SCH_SVG_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_SCH_SVG_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -48,7 +48,7 @@ CLI::FP_EXPORT_SVG_COMMAND::FP_EXPORT_SVG_COMMAND() : EXPORT_PCB_BASE_COMMAND( "
}
int CLI::FP_EXPORT_SVG_COMMAND::Perform( KIWAY& aKiway )
int CLI::FP_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_FP_EXPORT_SVG> svgJob = std::make_unique<JOB_FP_EXPORT_SVG>( true );

View File

@ -30,7 +30,8 @@ class FP_EXPORT_SVG_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
FP_EXPORT_SVG_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -40,7 +40,7 @@ CLI::FP_UPGRADE_COMMAND::FP_UPGRADE_COMMAND() : EXPORT_PCB_BASE_COMMAND( "upgrad
}
int CLI::FP_UPGRADE_COMMAND::Perform( KIWAY& aKiway )
int CLI::FP_UPGRADE_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_FP_UPGRADE> fpJob = std::make_unique<JOB_FP_UPGRADE>( true );

View File

@ -30,7 +30,8 @@ class FP_UPGRADE_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
FP_UPGRADE_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -48,7 +48,7 @@ CLI::SYM_EXPORT_SVG_COMMAND::SYM_EXPORT_SVG_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::SYM_EXPORT_SVG_COMMAND::Perform( KIWAY& aKiway )
int CLI::SYM_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_SYM_EXPORT_SVG> svgJob = std::make_unique<JOB_SYM_EXPORT_SVG>( true );

View File

@ -30,7 +30,8 @@ class SYM_EXPORT_SVG_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
SYM_EXPORT_SVG_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -40,7 +40,7 @@ CLI::SYM_UPGRADE_COMMAND::SYM_UPGRADE_COMMAND() : EXPORT_PCB_BASE_COMMAND( "upgr
}
int CLI::SYM_UPGRADE_COMMAND::Perform( KIWAY& aKiway )
int CLI::SYM_UPGRADE_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_SYM_UPGRADE> symJob = std::make_unique<JOB_SYM_UPGRADE>( true );

View File

@ -30,7 +30,8 @@ class SYM_UPGRADE_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
SYM_UPGRADE_COMMAND();
int Perform( KIWAY& aKiway ) override;
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -108,6 +108,7 @@ PGM_KICAD& PgmTop()
return program;
}
struct COMMAND_ENTRY
{
CLI::COMMAND* handler;
@ -119,6 +120,7 @@ struct COMMAND_ENTRY
handler( aHandler ), subCommands( aSub ){};
};
static CLI::EXPORT_PCB_DRILL_COMMAND exportPcbDrillCmd{};
static CLI::EXPORT_PCB_DXF_COMMAND exportPcbDxfCmd{};
static CLI::EXPORT_PCB_STEP_COMMAND exportPcbStepCmd{};
@ -144,6 +146,7 @@ static CLI::SYM_EXPORT_COMMAND symExportCmd{};
static CLI::SYM_EXPORT_SVG_COMMAND symExportSvgCmd{};
static CLI::SYM_UPGRADE_COMMAND symUpgradeCmd{};
static std::vector<COMMAND_ENTRY> commandStack = {
{
&fpCmd,
@ -270,8 +273,6 @@ bool PGM_KICAD::OnPgmInit()
return true;
}
#define ARG_VERSION "--version"
#define ARG_HELP "--help"
int PGM_KICAD::OnPgmRun()
{
@ -284,9 +285,9 @@ int PGM_KICAD::OnPgmRun()
.implicit_value( true )
.nargs( 0 );
argParser.add_argument( "-h", ARG_HELP )
argParser.add_argument( ARG_HELP_SHORT, ARG_HELP )
.default_value( false )
.help( UTF8STDSTR( _( "shows help message and exits" ) ) )
.help( UTF8STDSTR( ARG_HELP_DESC ) )
.implicit_value( true )
.nargs( 0 );
@ -316,13 +317,14 @@ int PGM_KICAD::OnPgmRun()
// arg parser uses a stream overload for printing the help
// we want to intercept so we can wxString the utf8 contents
// because on windows our terminal codepage might not be utf8
std::stringstream ss;
if( cliCmd )
ss << cliCmd->handler->GetArgParser();
cliCmd->handler->PrintHelp();
else
{
std::stringstream ss;
ss << argParser;
wxPrintf( FROM_UTF8( ss.str().c_str() ) );
}
return CLI::EXIT_CODES::ERR_ARGS;
}