Add --define-var / -D to the cli opts for some commands

Fixes https://gitlab.com/kicad/code/kicad/-/issues/15437
This commit is contained in:
Marek Roszko 2023-08-31 21:45:51 -04:00
parent b542539546
commit f357e79f77
18 changed files with 121 additions and 11 deletions

View File

@ -21,22 +21,38 @@
#ifndef JOB_H
#define JOB_H
#include <map>
#include <wx/string.h>
/**
* An simple container class that lets us dispatch output jobs to kifaces
*/
class JOB
{
public:
JOB( const std::string& aType, bool aIsCli ) : m_type( aType ), m_isCli( aIsCli ) {}
JOB( const std::string& aType, bool aIsCli ) :
m_type( aType ),
m_isCli( aIsCli ),
m_varOverrides()
{
}
virtual ~JOB() {}
const std::string& GetType() const { return m_type; };
bool IsCli() const { return m_isCli; };
private:
const std::map<wxString, wxString>& GetVarOverrides() const { return m_varOverrides; }
void SetVarOverrides( const std::map<wxString, wxString>& aVarOverrides )
{
m_varOverrides = aVarOverrides;
}
protected:
std::string m_type;
bool m_isCli;
std::map<wxString, wxString> m_varOverrides;
};
#endif

View File

@ -85,6 +85,21 @@ std::map<wxString, wxString>& PROJECT::GetTextVars() const
}
void PROJECT::ApplyTextVars( const std::map<wxString, wxString>& aVarsMap )
{
if( aVarsMap.size() == 0 )
return;
std::map<wxString, wxString>& existingVarsMap = GetTextVars();
for( const auto& var : aVarsMap )
{
// create or update the existing vars
existingVarsMap[var.first] = var.second;
}
}
void PROJECT::setProjectFullName( const wxString& aFullPathAndName )
{
// Compare paths, rather than inodes, to be less surprising to the user.

View File

@ -134,6 +134,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportPlot( JOB* aJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aPlotJob->m_filename, SCH_IO_MGR::SCH_KICAD );
sch->Prj().ApplyTextVars( aJob->GetVarOverrides() );
if( sch == nullptr )
{
@ -266,6 +267,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportBom( JOB* aJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aBomJob->m_filename, SCH_IO_MGR::SCH_KICAD );
sch->Prj().ApplyTextVars( aJob->GetVarOverrides() );
if( sch == nullptr )
{
@ -739,6 +741,7 @@ int EESCHEMA_JOBS_HANDLER::JobSchErc( JOB* aJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( ercJob->m_filename, SCH_IO_MGR::SCH_KICAD );
sch->Prj().ApplyTextVars( aJob->GetVarOverrides() );
if( sch == nullptr )
{
@ -838,4 +841,4 @@ DS_PROXY_VIEW_ITEM* EESCHEMA_JOBS_HANDLER::getDrawingSheetProxyView( SCHEMATIC*
drawingSheet->SetSheetPath( "" );
return drawingSheet;
}
}

View File

@ -62,6 +62,7 @@ public:
SCHEMATIC* aSch, const wxString& aDrawingSheetOverride = wxEmptyString );
private:
int doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob, KIGFX::SCH_RENDER_SETTINGS* aRenderSettings,
LIB_SYMBOL* symbol );

View File

@ -88,6 +88,11 @@ public:
virtual std::map<wxString, wxString>& GetTextVars() const;
/**
* Applies the given var map, it will create or update existing vars
*/
virtual void ApplyTextVars( const std::map<wxString, wxString>& aVarsMap );
/**
* Return the full path and name of the project.
*

View File

@ -22,6 +22,7 @@
#include <cli/exit_codes.h>
#include <wx/crt.h>
#include <macros.h>
#include <string_utils.h>
#include <sstream>
@ -70,6 +71,28 @@ int CLI::COMMAND::Perform( KIWAY& aKiway )
m_argDrawingSheet = FROM_UTF8( m_argParser.get<std::string>( ARG_DRAWING_SHEET ).c_str() );
}
if( m_hasDefineArg )
{
auto defines = m_argParser.get<std::vector<std::string>>( ARG_DEFINE_VAR_LONG );
for( const std::string& def : defines )
{
wxString str = FROM_UTF8( def.c_str() );
wxArrayString bits;
wxStringSplit( str, bits, wxS( '=' ) );
if( bits.Count() == 2 )
{
m_argDefineVars[bits[0]] = bits[1];
}
else
{
return EXIT_CODES::ERR_ARGS;
}
}
}
return doPerform( aKiway );
}
@ -119,4 +142,16 @@ void CLI::COMMAND::addDrawingSheetArg()
m_argParser.add_argument( ARG_DRAWING_SHEET )
.default_value( std::string() )
.help( UTF8STDSTR( _( "Path to drawing sheet, this overrides any existing project defined sheet when used" ) ) );
}
void CLI::COMMAND::addDefineArg()
{
m_hasDefineArg = true;
m_argParser.add_argument( ARG_DEFINE_VAR_LONG, ARG_DEFINE_VAR_SHORT )
.default_value( std::vector<std::string>() )
.help( UTF8STDSTR(
_( "Overrides or adds project variables, can be used multiple times to declare "
"multiple variables. Use in the format of '--define-var key=value'" ) ) );
}

View File

@ -33,6 +33,8 @@
#define ARG_OUTPUT "--output"
#define ARG_INPUT "input"
#define ARG_DRAWING_SHEET "--drawing-sheet"
#define ARG_DEFINE_VAR_SHORT "-D"
#define ARG_DEFINE_VAR_LONG "--define-var"
namespace CLI
{
@ -74,6 +76,11 @@ protected:
*/
void addDrawingSheetArg();
/**
* Sets up the drawing sheet arg used by many of the export commands
*/
void addDefineArg();
/**
* The internal handler that should be overloaded to implement command specific
* processing and work.
@ -104,6 +111,11 @@ protected:
*/
bool m_hasDrawingSheetArg;
/**
* Whether or not the input arg was added for parsing
*/
bool m_hasDefineArg;
/**
* Whether or not the output arg is expecting a directory
*/
@ -123,6 +135,11 @@ protected:
* Value of the drawing sheet arg if configured
*/
wxString m_argDrawingSheet;
/**
* Value of the drawing sheet arg if configured
*/
std::map<wxString, wxString> m_argDefineVars;
};
}

View File

@ -36,6 +36,7 @@ CLI::FP_EXPORT_SVG_COMMAND::FP_EXPORT_SVG_COMMAND() : PCB_EXPORT_BASE_COMMAND( "
m_argParser.add_description( UTF8STDSTR( _( "Exports the footprint or entire footprint library to SVG" ) ) );
addLayerArg( false );
addDefineArg();
m_argParser.add_argument( "-t", ARG_THEME )
.default_value( std::string() )
@ -64,6 +65,7 @@ int CLI::FP_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
svgJob->m_outputDirectory = m_argOutput;
svgJob->m_blackAndWhite = m_argParser.get<bool>( ARG_BLACKANDWHITE );
svgJob->m_footprint = FROM_UTF8( m_argParser.get<std::string>( ARG_FOOTPRINT ).c_str() );
svgJob->SetVarOverrides( m_argDefineVars );
if( !wxDir::Exists( svgJob->m_libraryPath ) )
{

View File

@ -40,6 +40,7 @@
CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : COMMAND( "drc" )
{
addCommonArgs( true, true, false );
addDefineArg();
m_argParser.add_description( UTF8STDSTR( _( "Runs the Design Rules Check (DRC) on the PCB and creates a report" ) ) );
@ -81,10 +82,6 @@ CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : COMMAND( "drc" )
.help( UTF8STDSTR( _( "Return a exit code depending on whether or not violations exist" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-o", ARG_OUTPUT )
.default_value( std::string() )
.help( UTF8STDSTR( _( "Output file name" ) ) );
}
@ -94,6 +91,7 @@ int CLI::PCB_DRC_COMMAND::doPerform( KIWAY& aKiway )
drcJob->m_outputFile = m_argOutput;
drcJob->m_filename = m_argInput;
drcJob->SetVarOverrides( m_argDefineVars );
drcJob->m_reportAllTrackErrors = m_argParser.get<bool>( ARG_ALL_TRACK_ERRORS );
drcJob->m_exitCodeViolations = m_argParser.get<bool>( ARG_EXIT_CODE_VIOLATIONS );

View File

@ -53,6 +53,7 @@ CLI::PCB_EXPORT_3D_COMMAND::PCB_EXPORT_3D_COMMAND( const std::string& aName,
m_format( aFormat )
{
addCommonArgs( true, true, false );
addDefineArg();
if( m_format == JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN )
{
@ -161,6 +162,7 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway )
step->m_filename = m_argInput;
step->m_outputFile = m_argOutput;
step->m_format = m_format;
step->SetVarOverrides( m_argDefineVars );
if( step->m_format == JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN )
{

View File

@ -37,6 +37,7 @@ CLI::PCB_EXPORT_DXF_COMMAND::PCB_EXPORT_DXF_COMMAND() : PCB_EXPORT_BASE_COMMAND(
{
addLayerArg( true );
addDrawingSheetArg();
addDefineArg();
m_argParser.add_argument( "--erd", ARG_EXCLUDE_REFDES )
.help( UTF8STDSTR( _( "Exclude the reference designator text" ) ) )
@ -75,6 +76,7 @@ int CLI::PCB_EXPORT_DXF_COMMAND::doPerform( KIWAY& aKiway )
dxfJob->m_filename = m_argInput;
dxfJob->m_outputFile = m_argOutput;
dxfJob->m_drawingSheet = m_argDrawingSheet;
dxfJob->SetVarOverrides( m_argDefineVars );
if( !wxFile::Exists( dxfJob->m_filename ) )
{

View File

@ -36,6 +36,7 @@ CLI::PCB_EXPORT_GERBER_COMMAND::PCB_EXPORT_GERBER_COMMAND( const std::string& aN
{
addLayerArg( true );
addDrawingSheetArg();
addDefineArg();
m_argParser.add_description( UTF8STDSTR( _( "Plot given layers to a single gerber file" ) ) );
@ -101,6 +102,7 @@ int CLI::PCB_EXPORT_GERBER_COMMAND::populateJob( JOB_EXPORT_PCB_GERBER* aJob )
aJob->m_filename = m_argInput;
aJob->m_outputFile = m_argOutput;
aJob->m_drawingSheet = m_argDrawingSheet;
aJob->SetVarOverrides( m_argDefineVars );
aJob->m_plotFootprintValues = !m_argParser.get<bool>( ARG_EXCLUDE_VALUE );
aJob->m_plotRefDes = !m_argParser.get<bool>( ARG_EXCLUDE_REFDES );

View File

@ -39,6 +39,7 @@ CLI::PCB_EXPORT_GERBERS_COMMAND::PCB_EXPORT_GERBERS_COMMAND() :
{
m_requireLayers = false;
addDrawingSheetArg();
addDefineArg();
m_argParser.add_description( UTF8STDSTR( _( "Plot multiple gerbers for a PCB, including the "
"ability to use stored board plot settings" ) ) );

View File

@ -37,6 +37,7 @@ CLI::PCB_EXPORT_PDF_COMMAND::PCB_EXPORT_PDF_COMMAND() : PCB_EXPORT_BASE_COMMAND(
{
addLayerArg( true );
addDrawingSheetArg();
addDefineArg();
m_argParser.add_argument( "-m", ARG_MIRROR )
.help( UTF8STDSTR( _( "Mirror the board (useful for trying to show bottom layers)" ) ) )
@ -92,6 +93,7 @@ int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway )
pdfJob->m_filename = m_argInput;
pdfJob->m_outputFile = m_argOutput;
pdfJob->m_drawingSheet = m_argDrawingSheet;
pdfJob->SetVarOverrides( m_argDefineVars );
if( !wxFile::Exists( pdfJob->m_filename ) )
{

View File

@ -40,6 +40,7 @@ CLI::PCB_EXPORT_SVG_COMMAND::PCB_EXPORT_SVG_COMMAND() : PCB_EXPORT_BASE_COMMAND(
{
addLayerArg( true );
addDrawingSheetArg();
addDefineArg();
m_argParser.add_argument( "-m", ARG_MIRROR )
.help( UTF8STDSTR( _( "Mirror the board (useful for trying to show bottom layers)" ) ) )
@ -98,6 +99,7 @@ int CLI::PCB_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
svgJob->m_outputFile = m_argOutput;
svgJob->m_colorTheme = FROM_UTF8( m_argParser.get<std::string>( ARG_THEME ).c_str() );
svgJob->m_plotDrawingSheet = !m_argParser.get<bool>( ARG_EXCLUDE_DRAWING_SHEET );
svgJob->SetVarOverrides( m_argDefineVars );
if( !wxFile::Exists( svgJob->m_filename ) )
{

View File

@ -39,6 +39,7 @@
CLI::SCH_ERC_COMMAND::SCH_ERC_COMMAND() : COMMAND( "erc" )
{
addCommonArgs( true, true, false );
addDefineArg();
m_argParser.add_description( UTF8STDSTR( _( "Runs the Electrical Rules Check (ERC) on the schematic and creates a report" ) ) );
@ -75,10 +76,6 @@ CLI::SCH_ERC_COMMAND::SCH_ERC_COMMAND() : COMMAND( "erc" )
.help( UTF8STDSTR( _( "Return a exit code depending on whether or not violations exist" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-o", ARG_OUTPUT )
.default_value( std::string() )
.help( UTF8STDSTR( _( "Output file name" ) ) );
}
@ -89,6 +86,7 @@ int CLI::SCH_ERC_COMMAND::doPerform( KIWAY& aKiway )
ercJob->m_outputFile = m_argOutput;
ercJob->m_filename = m_argInput;
ercJob->m_exitCodeViolations = m_argParser.get<bool>( ARG_EXIT_CODE_VIOLATIONS );
ercJob->SetVarOverrides( m_argDefineVars );
if( m_argParser.get<bool>( ARG_SEVERITY_ALL ) )
{

View File

@ -48,6 +48,7 @@ CLI::SCH_EXPORT_PLOT_COMMAND::SCH_EXPORT_PLOT_COMMAND( const std::string& aName,
{
addCommonArgs( true, true, aOutputIsDir );
addDrawingSheetArg();
addDefineArg();
m_argParser.add_argument( "-t", ARG_THEME )
.default_value( std::string() )
@ -114,6 +115,7 @@ int CLI::SCH_EXPORT_PLOT_COMMAND::doPerform( KIWAY& aKiway )
settings.m_outputFile = m_argOutput;
plotJob->m_drawingSheet = m_argDrawingSheet;
plotJob->SetVarOverrides( m_argDefineVars );
// HPGL local options
if( m_plotFormat == PLOT_FORMAT::HPGL )

View File

@ -98,6 +98,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob )
m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
BOARD* brd = LoadBoard( aStepJob->m_filename );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
if( aStepJob->m_format == JOB_EXPORT_PCB_3D::FORMAT::VRML )
{
@ -201,6 +202,7 @@ int PCBNEW_JOBS_HANDLER::JobExportSvg( JOB* aJob )
BOARD* brd = LoadBoard( aSvgJob->m_filename );
loadOverrideDrawingSheet( brd, aSvgJob->m_drawingSheet );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
if( aJob->IsCli() )
{
@ -226,6 +228,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob )
BOARD* brd = LoadBoard( aDxfJob->m_filename );
loadOverrideDrawingSheet( brd, aDxfJob->m_drawingSheet );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
if( aDxfJob->m_outputFile.IsEmpty() )
{
@ -282,6 +285,7 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob )
BOARD* brd = LoadBoard( aPdfJob->m_filename );
loadOverrideDrawingSheet( brd, aPdfJob->m_drawingSheet );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
if( aPdfJob->m_outputFile.IsEmpty() )
{
@ -478,6 +482,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob )
m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
BOARD* brd = LoadBoard( aGerberJob->m_filename );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
if( aGerberJob->m_outputFile.IsEmpty() )
{
@ -854,6 +859,7 @@ int PCBNEW_JOBS_HANDLER::doFpExportSvg( JOB_FP_EXPORT_SVG* aSvgJob, const FOOTPR
// until we refactor better plot api later
std::unique_ptr<BOARD> brd;
brd.reset( CreateEmptyBoard() );
brd->GetProject()->ApplyTextVars( aSvgJob->GetVarOverrides() );
FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aFootprint->Clone() );
@ -914,6 +920,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob )
m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
BOARD* brd = LoadBoard( drcJob->m_filename );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
if( drcJob->m_outputFile.IsEmpty() )
{