File indexing completed on 2024-04-28 04:37:00

0001 /*
0002     SPDX-FileCopyrightText: 2012 Ivan Shapovalov <intelfx100@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_OUTPUTEXECUTEJOB_H
0008 #define KDEVPLATFORM_OUTPUTEXECUTEJOB_H
0009 
0010 #include "outputjob.h"
0011 #include "outputmodel.h"
0012 #include <QProcess>
0013 #include <QUrl>
0014 
0015 namespace KDevelop
0016 {
0017 class OutputExecuteJobPrivate;
0018 
0019 class KDEVPLATFORMOUTPUTVIEW_EXPORT OutputExecuteJob : public OutputJob
0020 {
0021     Q_OBJECT
0022 
0023 public:
0024     enum JobStatus
0025     {
0026         JobRunning = 0,    /**< The job is running */
0027         JobSucceeded = 1,  /**< The job has succeeded */
0028         JobCanceled = 2,   /**< The job has been cancelled */
0029         JobFailed = 3,     /**< The job has failed */
0030         JobNotStarted = 4  /**< The job hasn't been started so far */
0031     };
0032 
0033     enum
0034     {
0035         InvalidWorkingDirectoryError = OutputJob::UserDefinedError,
0036         UserDefinedError
0037     };
0038 
0039     enum JobProperty
0040     {
0041         AppendProcessString   = 0x001, /**< Whether to append a process string to the user-specified job name */
0042         NeedWorkingDirectory  = 0x002, /**< Whether to require a non-empty working directory to be provided */
0043         CheckWorkingDirectory = 0x004, /**< Whether to check that the working directory actually exists (and not to create it if needed) */
0044         PortableMessages      = 0x008, /**< Whether to set LC_MESSAGES=C in the process' environment */
0045         DisplayStdout         = 0x010, /**< Whether to pass process' stdout to the output model */
0046         DisplayStderr         = 0x020, /**< Whether to pass process' stderr to the output model */
0047         NoSilentOutput        = 0x040, /**< Whether to call \ref startOutput() only if verbosity is \ref OutputJob::Verbose */
0048         PostProcessOutput     = 0x080, /**< Whether to connect line maker's signals to \ref postProcessStdout() and \ref postProcessStderr() */
0049         IsBuilderHint         = 0x100, /**< Whether to use builder-specific messages to talk to user (e. g. "build directory" instead of "working directory" */
0050     };
0051     Q_FLAGS(JobProperty JobProperties)
0052     Q_DECLARE_FLAGS(JobProperties, JobProperty)
0053 
0054     explicit OutputExecuteJob( QObject* parent = nullptr, OutputJobVerbosity verbosity = OutputJob::Verbose );
0055     ~OutputExecuteJob() override;
0056 
0057     /**
0058      * Get the job's status (associated with the process).
0059      *
0060      * @returns The job's status.
0061      * @see JobStatus
0062      */
0063     JobStatus status() const;
0064 
0065     /**
0066      * Get the job's output model.
0067      *
0068      * @returns The job's output model, downcasted to \ref OutputModel
0069      */
0070     OutputModel* model() const;
0071 
0072     /**
0073      * Returns a working directory for the job's process.
0074      *
0075      * @returns URL which has been set through \ref setWorkingDirectory(); empty URL if unset.
0076      */
0077     virtual QUrl workingDirectory() const;
0078 
0079     /**
0080      * Set a working directory for the job's process.
0081      * Effective if \ref workingDirectory() hasn't been overridden.
0082      *
0083      * @param directory a valid local directory URL, or an empty URL to unset.
0084      */
0085     void setWorkingDirectory( const QUrl& directory );
0086 
0087     /**
0088      * Get process' command line.
0089      *
0090      * @returns The command line for the process, with first element in list being the program path.
0091      */
0092     virtual QStringList commandLine() const;
0093 
0094     /**
0095      * Append an element to the command line argument list for this process.
0096      * If no executable is set yet, it will be set instead.
0097      * Effective if \ref commandLine() hasn't been overridden.
0098      *
0099      * @param argument the argument to add
0100      */
0101     OutputExecuteJob& operator<<( const QString& argument );
0102 
0103     /**
0104      * Append a list of elements to the command line argument list for this process.
0105      * If no executable is set yet, it will be set from the first argument in given list.
0106      * Effective if \ref commandLine() hasn't been overridden.
0107      *
0108      * @param arguments the arguments to add
0109      */
0110     OutputExecuteJob& operator<<( const QStringList& arguments );
0111 
0112     /**
0113      * Get the privilege escalation command ("su", "sudo", etc.) used for the job's process.
0114      *
0115      * @returns The privilege escalation command name and arguments; empty list if not set.
0116      */
0117     virtual QStringList privilegedExecutionCommand() const;
0118 
0119     /**
0120      * Set the privilege escalation command ("su", "sudo", etc.) which will be used for the job's process.
0121      * Effective if \ref privilegedExecutionCommand() hasn't been overridden.
0122      *
0123      * @param command The privilege escalation command's name and arguments; empty list to unset.
0124      * @see privilegedCommand
0125      */
0126     void setPrivilegedExecutionCommand( const QStringList& command );
0127 
0128     /**
0129      * A convenience function to set the job name.
0130      *
0131      * Calls \ref setTitle() and \ref setObjectName().
0132      *
0133      * @note If you need the command-line to be appended to the job name,
0134      * make sure that it is already configured upon calling this function.
0135      *
0136      * @param name The name to set; empty string to use default (process string).
0137      */
0138     void setJobName( const QString& name );
0139 
0140     /**
0141      * Set one of the standard filtering strategies for the output model.
0142      */
0143     void setFilteringStrategy( OutputModel::OutputFilterStrategy strategy );
0144 
0145     /**
0146      * Set the filtering strategy for the output model.
0147      */
0148     void setFilteringStrategy(IFilterStrategy* filterStrategy);
0149 
0150     /**
0151      * Get the current properties of the job.
0152      *
0153      * @note Default-set properties are: \ref DisplayStdout.
0154      */
0155     virtual JobProperties properties() const;
0156 
0157     /**
0158      * Set properties of the job.
0159      * Effective if \ref properties() hasn't been overridden.
0160      *
0161      * @param properties Which flags to add to the job.
0162      * @param override Whether to assign instead of doing bitwise OR.
0163      * @see JobProperties, properties(), unsetProperties()
0164      */
0165     void setProperties( JobProperties properties, bool override = false );
0166 
0167     /**
0168      * Unset properties of the job.
0169      *
0170      * @param properties Which flags to remove from the job
0171      * @see JobProperties, properties(), setProperties()
0172      */
0173     void unsetProperties( JobProperties properties );
0174 
0175     /**
0176      * Add a variable to the job's process environment.
0177      *
0178      * The variables added with this method override ones from the system environment and
0179      * the global environment profile, but are overridden by "PortableMessages" property.
0180      *
0181      * @param name The name of a variable to add
0182      * @param value The value of a variable to add; empty string to unset.
0183      */
0184     void addEnvironmentOverride( const QString& name, const QString& value );
0185 
0186     /**
0187      * Remove a variable from the override set.
0188      *
0189      * @param name The name of a variable to remove.
0190      * @note This does not force a variable to empty value; this is to undo the overriding itself.
0191      */
0192     void removeEnvironmentOverride( const QString& name );
0193 
0194     /**
0195      * Get the global environment profile name for the job's process.
0196      *
0197      * @returns The environment profile name to use in the job's process; empty if unset.
0198      */
0199     virtual QString environmentProfile() const;
0200 
0201     /**
0202      * Set the environment profile name for the job's process.
0203      * Effective if \ref environmentProfile() hasn't been overridden.
0204      *
0205      * @param profile The name of profile to set.
0206      */
0207     void setEnvironmentProfile( const QString& profile );
0208 
0209     void start() override;
0210 
0211     /**
0212      * If @p executeHost is enabled, the process will be executed in the local host.
0213      * Otherwise the currentRuntime will be used to execute the process.
0214      *
0215      * @sa IRuntimeController::setCurrentRuntime()
0216      */
0217     void setExecuteOnHost(bool executeHost);
0218     bool executeOnHost() const;
0219 
0220     /**
0221      * The job fails whether the process exit code is different to 0 depending on @p check
0222      */
0223     void setCheckExitCode(bool check);
0224 
0225     /**
0226      * @returns whether the job will fail if the process returns other than 0
0227      */
0228     bool checkExitCode() const;
0229 
0230 protected:
0231     bool doKill() override;
0232 
0233 protected Q_SLOTS:
0234     // Redefine these functions if you want to post-process the output somehow
0235     // before it hits the output model.
0236     // Default implementations for either function call "model()->appendLines( lines );".
0237     // Do the same if you need the output to be visible.
0238     virtual void postProcessStdout( const QStringList& lines );
0239     virtual void postProcessStderr( const QStringList& lines );
0240 
0241     // Redefine these functions if you want to handle process' exit codes in a special manner.
0242     // One possible usage is in "cvs diff" job which returns 1 on success.
0243     virtual void childProcessExited( int exitCode, QProcess::ExitStatus exitStatus );
0244     virtual void childProcessError( QProcess::ProcessError processError );
0245 
0246 private:
0247     const QScopedPointer<class OutputExecuteJobPrivate> d_ptr;
0248     Q_DECLARE_PRIVATE(OutputExecuteJob)
0249     friend class OutputExecuteJobPrivate;
0250 };
0251 
0252 Q_DECLARE_OPERATORS_FOR_FLAGS(OutputExecuteJob::JobProperties)
0253 } // namespace KDevelop
0254 
0255 #endif // KDEVPLATFORM_OUTPUTEXECUTEJOB_H