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 wxString tempDirPath = tmp.GetFullPath();
102 if( !wxFileName::Mkdir( tempDirPath, wxS_DIR_DEFAULT ) )
103 {
104 if( m_reporter )
105 {
106 msg = wxString::Format( wxT( "Failed to create temporary directory %s" ), tempDirPath );
108 }
109
110 return false;
111 }
112
113 if( m_reporter != nullptr )
114 {
115 msg += wxT( "|--------------------------------\n" );
116 msg += wxT( "| " );
117 msg += wxString::Format( "Performing jobs" );
118 msg += wxT( "\n" );
119 msg += wxT( "|--------------------------------\n" );
120
121 msg += wxString::Format( wxT( "|%-5s | %-50s\n" ), wxT( "No." ), wxT( "Description" ) );
122
123 int jobNum = 1;
124 for( const JOBSET_JOB& job : jobsForOutput )
125 {
126 msg += wxString::Format( wxT( "|%-5d | %-50s\n" ), jobNum,
127 job.m_job->GetDescription() );
128 jobNum++;
129 }
130 msg += wxT( "|--------------------------------\n" );
131 msg += wxT( "\n" );
132 msg += wxT( "\n" );
133
135 }
136
137 std::vector<JOB_OUTPUT> outputs;
138
139 int jobNum = 1;
140 int failCount = 0;
141 int successCount = 0;
142 for( const JOBSET_JOB& job : jobsForOutput )
143 {
144 if( m_reporter != nullptr )
145 {
146 msg = wxT( "|--------------------------------\n" );
147 msg += wxString::Format( wxT( "| Running job %d, %s" ), jobNum, job.m_job->GetDescription() );
148 msg += wxT( "\n" );
149 msg += wxT( "|--------------------------------\n" );
150
152 }
153
154 KIWAY::FACE_T iface = JOB_REGISTRY::GetKifaceType( job.m_type );
155
156 job.m_job->SetTempOutputDirectory( tempDirPath );
157
158 int result = 0;
159 if( iface < KIWAY::KIWAY_FACE_COUNT )
160 {
161 result = m_kiway->ProcessJob( iface, job.m_job.get() );
162 }
163 else
164 {
165 // special jobs
166 if( job.m_job->GetType() == "special_execute" )
167 {
168 JOB_SPECIAL_EXECUTE* specialJob = static_cast<JOB_SPECIAL_EXECUTE*>( job.m_job.get() );
169 // static cast requried because wx used `long` which is 64-bit on linux but 32-bit on windows
170 result = static_cast<int>( wxExecute( specialJob->m_command ) );
171 }
172 }
173
174 if( m_reporter )
175 {
176 if( result == 0 )
177 {
178 wxString msg_fmt = wxT( "\033[32;1m%s\033[0m\n" );
179 msg = wxString::Format( msg_fmt, _( "Job successful" ) );
180
181 successCount++;
182 }
183 else
184 {
185 wxString msg_fmt = wxT( "\033[31;1m%s\033[0m\n" );
186 msg = wxString::Format( msg_fmt, _( "Job failed" ) );
187
188 failCount++;
189 }
190
191 msg += wxT( "\n\n" );
193 }
194
195 if( result != 0 )
196 {
197 if( aBail )
198 {
199 return result;
200 }
201 else
202 {
203 success = false;
204 }
205 }
206 }
207
208 if( success )
209 {
210 aOutput->m_outputHandler->HandleOutputs( tempDirPath, outputs );
211 }
212
213 if( m_reporter )
214 {
215 msg = wxString::Format( wxT( "\n\n\033[33;1m%d %s, %d %s\033[0m\n" ),
216 successCount,
217 wxT( "jobs succeeded" ),
218 failCount,
219 wxT( "job failed" ) );
220
222 }
223
224 return success;
225}
Definition: jobset.h:70
std::vector< JOBSET_JOB > GetJobsForOutput(JOBSET_OUTPUT *aOutput)
Definition: jobset.cpp:213
std::vector< JOBSET_OUTPUT > & GetOutputs()
Definition: jobset.h:83
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
JOBS_OUTPUT_HANDLER * m_outputHandler
Definition: jobset.h:63