KiCad PCB EDA Suite
Loading...
Searching...
No Matches
jobs_runner.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2024 Mark Roszko <[email protected]>
5 * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <jobs_runner.h>
22#include <jobs/job_registry.h>
23#include <jobs/jobset.h>
25#include <kiway.h>
26#include <kiway_express.h>
27#include <reporter.h>
28#include <wx/process.h>
29#include <wx/txtstrm.h>
30#include <wx/sstream.h>
31#include <wx/wfstream.h>
32
34 REPORTER* aReporter ) :
35 m_kiway( aKiway ),
36 m_jobsFile( aJobsFile ),
37 m_reporter( aReporter )
38{
39 if( !m_reporter )
40 {
42 }
43}
44
45
47{
48 bool success = true;
49
50 for( JOBSET_OUTPUT& output : m_jobsFile->GetOutputs() )
51 {
52 success &= RunJobsForOutput( &output, aBail );
53 }
54
55 return success;
56}
57
58
60{
61 JOB_SPECIAL_EXECUTE* specialJob = static_cast<JOB_SPECIAL_EXECUTE*>( aJob->m_job.get() );
62
63 // static cast required because wx uses `long` which is 64-bit on Linux but 32-bit on Windows
64 wxProcess process;
65 process.Redirect();
66
67 int result = static_cast<int>( wxExecute( specialJob->m_command, wxEXEC_SYNC, &process ) );
68
69 wxString output;
70
71 if( specialJob->m_recordOutput )
72 {
73 wxFFileOutputStream procOutput( specialJob->GetFullOutputPath() );
74 wxInputStream* inputStream = process.GetInputStream();
75 if( inputStream )
76 {
77 inputStream->Read( procOutput );
78 }
79 procOutput.Close();
80 }
81
82 if( specialJob->m_ignoreExitcode )
83 {
84 return 0;
85 }
86
87 return result;
88}
89
90
91bool JOBS_RUNNER::RunJobsForOutput( JOBSET_OUTPUT* aOutput, bool aBail )
92{
93 bool success = true;
94 std::vector<JOBSET_JOB> jobsForOutput = m_jobsFile->GetJobsForOutput( aOutput );
95 wxString msg;
96
97 wxFileName tmp;
98 tmp.AssignDir( wxFileName::GetTempDir() );
99 tmp.AppendDir( KIID().AsString() );
100
101 aOutput->m_lastRunSuccessMap.clear();
102
103 wxString tempDirPath = tmp.GetFullPath();
104 if( !wxFileName::Mkdir( tempDirPath, wxS_DIR_DEFAULT ) )
105 {
106 if( m_reporter )
107 {
108 msg = wxString::Format( wxT( "Failed to create temporary directory %s" ), tempDirPath );
110 }
111
112 aOutput->m_lastRunSuccess = false;
113
114 return false;
115 }
116
117 bool continueOuput = aOutput->m_outputHandler->OutputPrecheck();
118
119 if( !continueOuput )
120 {
121 if( m_reporter )
122 {
123 msg = wxString::Format( wxT( "Output precheck failed for output %s" ), aOutput->m_id );
125 }
126 aOutput->m_lastRunSuccess = false;
127 return false;
128 }
129
130 if( m_reporter != nullptr )
131 {
132 msg += wxT( "|--------------------------------\n" );
133 msg += wxT( "| " );
134 msg += wxString::Format( "Performing jobs" );
135 msg += wxT( "\n" );
136 msg += wxT( "|--------------------------------\n" );
137
138 msg += wxString::Format( wxT( "|%-5s | %-50s\n" ), wxT( "No." ), wxT( "Description" ) );
139
140 int jobNum = 1;
141 for( const JOBSET_JOB& job : jobsForOutput )
142 {
143 msg += wxString::Format( wxT( "|%-5d | %-50s\n" ), jobNum,
144 job.m_job->GetDescription() );
145 jobNum++;
146 }
147 msg += wxT( "|--------------------------------\n" );
148 msg += wxT( "\n" );
149 msg += wxT( "\n" );
150
152 }
153
154 std::vector<JOB_OUTPUT> outputs;
155
156 int jobNum = 1;
157 int failCount = 0;
158 int successCount = 0;
159 for( const JOBSET_JOB& job : jobsForOutput )
160 {
161 if( m_reporter != nullptr )
162 {
163 msg = wxT( "|--------------------------------\n" );
164 msg += wxString::Format( wxT( "| Running job %d, %s" ), jobNum, job.m_job->GetDescription() );
165 msg += wxT( "\n" );
166 msg += wxT( "|--------------------------------\n" );
167
169 }
170
171 KIWAY::FACE_T iface = JOB_REGISTRY::GetKifaceType( job.m_type );
172
173 job.m_job->SetTempOutputDirectory( tempDirPath );
174
175 int result = 0;
176 if( iface < KIWAY::KIWAY_FACE_COUNT )
177 {
178 result = m_kiway->ProcessJob( iface, job.m_job.get() );
179 }
180 else
181 {
182 // special jobs
183 if( job.m_job->GetType() == "special_execute" )
184 {
185 JOB_SPECIAL_EXECUTE* specialJob = static_cast<JOB_SPECIAL_EXECUTE*>( job.m_job.get() );
186 // static cast requried because wx used `long` which is 64-bit on linux but 32-bit on windows
187 result = static_cast<int>( wxExecute( specialJob->m_command ) );
188 }
189 }
190
191 if( result == 0 )
192 {
193 aOutput->m_lastRunSuccessMap[job.m_id] = true;
194 }
195 else
196 {
197 aOutput->m_lastRunSuccessMap[job.m_id] = false;
198 }
199
200 if( m_reporter )
201 {
202 if( result == 0 )
203 {
204 wxString msg_fmt = wxT( "\033[32;1m%s\033[0m\n" );
205 msg = wxString::Format( msg_fmt, _( "Job successful" ) );
206
207 successCount++;
208 }
209 else
210 {
211 wxString msg_fmt = wxT( "\033[31;1m%s\033[0m\n" );
212 msg = wxString::Format( msg_fmt, _( "Job failed" ) );
213
214 failCount++;
215 }
216
217 msg += wxT( "\n\n" );
219 }
220
221 if( result != 0 )
222 {
223 if( aBail )
224 {
225 return result;
226 }
227 else
228 {
229 success = false;
230 }
231 }
232 }
233
234 if( success )
235 {
236 success = aOutput->m_outputHandler->HandleOutputs( tempDirPath, outputs );
237 }
238
239 aOutput->m_lastRunSuccess = success;
240
241 if( m_reporter )
242 {
243 msg = wxString::Format( wxT( "\n\n\033[33;1m%d %s, %d %s\033[0m\n" ),
244 successCount,
245 wxT( "jobs succeeded" ),
246 failCount,
247 wxT( "job failed" ) );
248
250 }
251
252 return success;
253}
Definition: jobset.h:72
std::vector< JOBSET_JOB > GetJobsForOutput(JOBSET_OUTPUT *aOutput)
Definition: jobset.cpp:234
std::vector< JOBSET_OUTPUT > & GetOutputs()
Definition: jobset.h:85
virtual bool OutputPrecheck()
Checks if the output process can proceed before doing anything else This can include user prompts.
Definition: jobs_output.h:42
virtual bool HandleOutputs(const wxString &baseTempPath, const std::vector< JOB_OUTPUT > &aOutputsToHandle)=0
bool RunJobsForOutput(JOBSET_OUTPUT *aOutput, bool aBail=false)
Definition: jobs_runner.cpp:91
KIWAY * m_kiway
Definition: jobs_runner.h:41
JOBSET * m_jobsFile
Definition: jobs_runner.h:42
int runSpecialExecute(JOBSET_JOB *aJob)
Definition: jobs_runner.cpp:59
bool RunJobsAllOutputs(bool aBail=false)
Definition: jobs_runner.cpp:46
REPORTER * m_reporter
Definition: jobs_runner.h:43
JOBS_RUNNER(KIWAY *aKiway, JOBSET *aJobsFile, REPORTER *aReporter=nullptr)
Definition: jobs_runner.cpp:33
static KIWAY::FACE_T GetKifaceType(const wxString &aName)
wxString GetFullOutputPath() const
Definition: job.cpp:87
Definition: kiid.h:49
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:284
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob)
Definition: kiway.cpp:709
FACE_T
Known KIFACE implementations.
Definition: kiway.h:290
@ KIWAY_FACE_COUNT
Definition: kiway.h:300
static REPORTER & GetInstance()
Definition: reporter.cpp:115
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:72
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
#define _(s)
static PGM_BASE * process
Definition: pgm_base.cpp:1058
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
std::shared_ptr< JOB > m_job
Definition: jobset.h:39
wxString m_id
Definition: jobset.h:58
JOBS_OUTPUT_HANDLER * m_outputHandler
Definition: jobset.h:60
std::unordered_map< wxString, std::optional< bool > > m_lastRunSuccessMap
Definition: jobset.h:65
std::optional< bool > m_lastRunSuccess
Definition: jobset.h:64