35#include <wx/process.h>
36#include <wx/txtstrm.h>
37#include <wx/sstream.h>
38#include <wx/wfstream.h>
39#include <wx/mstream.h>
40#include <wx/tokenzr.h>
78 wxInputStream* inputStream =
process.GetInputStream();
79 wxInputStream* errorStream =
process.GetErrorStream();
82 auto streamToBuf = []( wxInputStream& aIs )
84 wxMemoryOutputStream memOut;
88 buf.AppendData( memOut.GetOutputStreamBuffer()->GetBufferStart(),
89 memOut.GetOutputStreamBuffer()->GetIntPosition() );
94 if( inputStream && errorStream )
96 wxMemoryBuffer memInBuf = streamToBuf( *inputStream );
97 wxMemoryBuffer memErrBuf = streamToBuf( *errorStream );
99 if( !memInBuf.IsEmpty() )
101 wxString str = wxString::FromUTF8( memInBuf, memInBuf.GetDataLen() );
102 wxStringTokenizer tokenizer( str,
"\r\n" );
104 while( tokenizer.HasMoreTokens() )
108 if( !memErrBuf.IsEmpty() )
110 wxString str = wxString::FromUTF8( memErrBuf, memErrBuf.GetDataLen() );
111 wxStringTokenizer tokenizer( str,
"\r\n" );
113 while( tokenizer.HasMoreTokens() )
121 wxFileName fn( aJob->
m_id );
122 fn.SetExt( wxT(
"log" ) );
128 if( !procOutput.IsOk() )
131 procOutput.WriteAll( memInBuf, memInBuf.GetDataLen() );
143 std::vector<wxString>& aPathsWritten )
150 wxFileName sourceFn(
source );
154 if( !aJob->
m_dest.IsEmpty() )
159 errors, aPathsWritten );
198 bool genOutputs =
true;
200 std::vector<JOBSET_JOB> jobsForDestination =
m_jobsFile->GetJobsForDestination( aDestination );
204 tmp.AssignDir( wxFileName::GetTempDir() );
205 tmp.AppendDir(
KIID().AsString() );
211 wxString tempDirPath = tmp.GetFullPath();
213 if( !wxFileName::Mkdir( tempDirPath, wxS_DIR_DEFAULT ) )
215 msg = wxString::Format( wxT(
"Failed to create temporary directory %s" ), tempDirPath );
227 msg = wxString::Format( wxT(
"Destination precheck failed for destination %s" ),
228 aDestination->
m_id );
235 msg += wxT(
"|--------------------------------\n" );
237 msg += wxString::Format( wxT(
"Running jobs for destination %s" ), aDestination->
m_id );
239 msg += wxT(
"|--------------------------------\n" );
241 msg += wxString::Format( wxT(
"|%-5s | %-50s\n" ), wxT(
"No." ), wxT(
"Description" ) );
245 for(
const JOBSET_JOB& job : jobsForDestination )
247 msg += wxString::Format( wxT(
"|%-5d | %-50s\n" ), jobNum, job.GetDescription() );
251 msg += wxT(
"|--------------------------------\n" );
257 std::vector<wxString> pathsWithOverwriteDisallowed;
258 std::vector<JOB_OUTPUT> outputs;
262 int successCount = 0;
266 for(
const JOBSET_JOB& job : jobsForDestination )
268 msg = wxT(
"|--------------------------------\n" );
270 msg += wxString::Format( wxT(
"| Running job %d: %s" ), jobNum, job.GetDescription() );
273 msg += wxT(
"|--------------------------------\n" );
279 msg.Printf(
_(
"Running job %d: %s" ), jobNum, job.GetDescription() );
288 job.m_job->SetTempOutputDirectory( tempDirPath );
311 if( job.m_job->GetType() ==
"special_execute" )
315 else if( job.m_job->GetType() ==
"special_copyfiles" )
318 std::vector<wxString> pathsWritten;
324 pathsWithOverwriteDisallowed.insert( pathsWithOverwriteDisallowed.end(), pathsWritten.begin(),
325 pathsWritten.end() );
328 else if( job.m_job->GetType() ==
"special_archive" )
334 msg = wxString::Format( wxT(
"Unsupported job type '%s'" ), job.m_type );
344 wxString msg_fmt = wxT(
"\033[32;1m%s\033[0m\n" );
345 msg = wxString::Format( msg_fmt,
_(
"Job successful" ) );
351 wxString msg_fmt = wxT(
"\033[31;1m%s\033[0m\n" );
352 msg = wxString::Format( msg_fmt,
_(
"Job failed" ) );
357 msg += wxT(
"\n\n" );
387 msg = wxString::Format( wxT(
"\n\n\033[33;1m%d %s, %d %s\033[0m\n" ),
389 wxT(
"jobs succeeded" ),
391 wxT(
"job failed" ) );
virtual bool OutputPrecheck()
Checks if the output process can proceed before doing anything else This can include user prompts.
virtual bool HandleOutputs(const wxString &aBaseTempPath, PROJECT *aProject, const std::vector< wxString > &aPathsWithOverwriteDisallowed, const std::vector< JOB_OUTPUT > &aOutputsToHandle, std::optional< wxString > &aResolvedOutputPath)=0
bool RunJobsAllDestinations(bool aBail=false)
JOBS_PROGRESS_REPORTER * m_progressReporter
bool RunJobsForDestination(JOBSET_DESTINATION *aDestination, bool aBail=false)
int runSpecialCopyFiles(const JOB_SPECIAL_COPYFILES *aJob, PROJECT *aProject, std::vector< wxString > &aPathsWritten)
int runSpecialArchive(const JOBSET_JOB *aJob, REPORTER *aReporter, PROJECT *aProject)
int runSpecialExecute(const JOBSET_JOB *aJob, REPORTER *aReporter, PROJECT *aProject)
JOBS_RUNNER(KIWAY *aKiway, JOBSET *aJobsFile, PROJECT *aProject, REPORTER &aReporter, JOBS_PROGRESS_REPORTER *aProgressReporter)
static KIWAY::FACE_T GetKifaceType(const wxString &aName)
bool m_generateErrorOnNoCopy
void SetConfiguredOutputPath(const wxString &aPath)
Sets the configured output path for the job, this path is always saved to file.
wxString GetFullOutputPath(PROJECT *aProject) const
Returns the full output path for the job, taking into account the configured output path,...
wxString GetConfiguredOutputPath() const
Returns the configured output path for the job.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
FACE_T
Known KIFACE implementations.
static REPORTER & GetInstance()
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
static bool Archive(const wxString &aSrcDir, const wxString &aDestFile, REPORTER &aReporter, bool aVerbose=true, bool aIncludeExtraFiles=false)
Create an archive of the project.
Container for project specific data.
virtual const wxString GetProjectPath() const
Return the full path of the project.
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
wxString ExpandPathVariables(const wxString &aPath, const PROJECT *aProject, const std::function< bool(wxString *)> *aTextResolver)
Expand text variables, environment variables and a leading '~' in a user-entered file path.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject, bool aAllowEscapes)
Replace any environment variable & text variable references with their values.
wxString ResolveProjectPath(const wxString &aPath, const PROJECT *aProject, const std::function< bool(wxString *)> *aTextResolver)
Expand a user-entered file path as ExpandPathVariables() does, then anchor a relative result at the p...
int ExecuteCommandThroughShell(const wxString &aCommand, wxProcess *aProcess)
Run a user-supplied command line through the platform shell so glob expansion, pipes,...
bool CopyFilesOrDirectory(const wxString &aSourcePath, const wxString &aDestDir, bool aAllowOverwrites, wxString &aErrors, std::vector< wxString > &aPathsWritten)
#define OUTPUT_TMP_PATH_VAR_NAME
static const int ERR_ARGS
static const int ERR_RC_VIOLATIONS
Rules check violation count was greater than 0.
static const int ERR_INVALID_OUTPUT_CONFLICT
static const int ERR_UNKNOWN
static PGM_BASE * process
std::unordered_map< wxString, std::shared_ptr< JOBSET_OUTPUT_REPORTER > > m_lastRunReporters
std::shared_ptr< JOBS_OUTPUT_HANDLER > m_outputHandler
std::optional< wxString > m_lastResolvedOutputPath
std::optional< bool > m_lastRunSuccess
std::unordered_map< wxString, std::optional< bool > > m_lastRunSuccessMap
std::shared_ptr< JOB > m_job
wxString result
Test unit parsing edge cases and error handling.