From fe7a64d5ab0f556e0ac87305808dfe5ea3d7653a Mon Sep 17 00:00:00 2001
From: Teo Mrnjavac <teo@kde.org>
Date: Thu, 10 Jul 2014 12:08:43 +0200
Subject: [PATCH] Add ProcessJob, a wrapper for external commands.

---
 src/libcalamares/CMakeLists.txt |  1 +
 src/libcalamares/ProcessJob.cpp | 85 +++++++++++++++++++++++++++++++++
 src/libcalamares/ProcessJob.h   | 43 +++++++++++++++++
 3 files changed, 129 insertions(+)
 create mode 100644 src/libcalamares/ProcessJob.cpp
 create mode 100644 src/libcalamares/ProcessJob.h

diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt
index 958d5e23ac..2675f07269 100644
--- a/src/libcalamares/CMakeLists.txt
+++ b/src/libcalamares/CMakeLists.txt
@@ -17,6 +17,7 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../calamares/CalamaresVersion.h.in
 set( libSources
     Job.cpp
     JobQueue.cpp
+    ProcessJob.cpp
 
     kdsingleapplicationguard/kdsingleapplicationguard.cpp
     kdsingleapplicationguard/kdsharedmemorylocker.cpp
diff --git a/src/libcalamares/ProcessJob.cpp b/src/libcalamares/ProcessJob.cpp
new file mode 100644
index 0000000000..7c9393b5e5
--- /dev/null
+++ b/src/libcalamares/ProcessJob.cpp
@@ -0,0 +1,85 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ProcessJob.h"
+
+#include <QProcess>
+
+namespace Calamares {
+
+
+ProcessJob::ProcessJob( const QString& command, int secondsTimeout, QObject* parent )
+    : Job( parent )
+    , m_command( command )
+    , m_timeoutSec( secondsTimeout )
+{}
+
+
+ProcessJob::~ProcessJob()
+{}
+
+
+QString
+ProcessJob::prettyName() const
+{
+    //TODO: show something more meaningful
+    return tr( "Run %1" ).arg( m_command );
+}
+
+
+JobResult
+ProcessJob::exec()
+{
+    QProcess p;
+    p.setProcessChannelMode( QProcess::MergedChannels );
+    p.start( m_command );
+
+    // It's ok to block here because JobQueue runs this method in a separate thread.
+    if ( !p.waitForStarted() )
+        return JobResult::error( tr( "External command failed to start" ),
+                                 tr( "Command %1 failed to start in 30s." )
+                                    .arg( m_command ) );
+
+    if ( !p.waitForFinished( m_timeoutSec * 1000/*msec*/ ) )
+        return JobResult::error( tr( "External command failed to finish" ),
+                                 tr( "Command %1 failed to finish in %2s." )
+                                    .arg( m_command )
+                                    .arg( m_timeoutSec ) );
+
+    if ( p.exitStatus() == QProcess::NormalExit && p.exitCode() == 0 )
+    {
+        return JobResult::ok();
+    }
+    else if ( p.exitStatus() == QProcess::CrashExit )
+    {
+        return JobResult::error( tr( "External command crashed" ),
+                                 tr( "Command %1 crashed.\nOutput:\n%2" )
+                                    .arg( m_command )
+                                    .arg( QString::fromLocal8Bit( p.readAll() ) ) );
+    }
+    else //NormalExit with non-zero exit code
+    {
+        return JobResult::error( tr( "External command finished with errors" ),
+                                 tr( "Command %1 finished with exit code %2.\nOutput:\n%3" )
+                                    .arg( m_command )
+                                    .arg( p.exitCode() )
+                                    .arg( QString::fromLocal8Bit( p.readAll() ) ) );
+    }
+}
+
+} // namespace Calamares
diff --git a/src/libcalamares/ProcessJob.h b/src/libcalamares/ProcessJob.h
new file mode 100644
index 0000000000..7056095d57
--- /dev/null
+++ b/src/libcalamares/ProcessJob.h
@@ -0,0 +1,43 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   Calamares is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CALAMARES_PROCESSJOB_H
+#define CALAMARES_PROCESSJOB_H
+
+#include "Job.h"
+
+namespace Calamares {
+
+class ProcessJob : public Job
+{
+    Q_OBJECT
+public:
+    explicit ProcessJob( const QString& command, int secondsTimeout, QObject* parent = nullptr );
+    virtual ~ProcessJob();
+
+    QString prettyName() const override;
+    JobResult exec() override;
+
+private:
+    QString m_command;
+    int m_timeoutSec;
+};
+
+} // namespace Calamares
+
+#endif // CALAMARES_PROCESSJOB_H
-- 
GitLab