File indexing completed on 2024-05-19 15:46:09
0001 /* 0002 SPDX-FileCopyrightText: 2018 Morten Danielsen Volden 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "perforceimportmetadatawidget.h" 0008 0009 #include <vcslocation.h> 0010 0011 #include <QProcess> 0012 #include <QTemporaryDir> 0013 #include <QTextStream> 0014 #include <QStandardPaths> 0015 0016 using namespace KDevelop; 0017 0018 PerforceImportMetadataWidget::PerforceImportMetadataWidget(QWidget* parent) 0019 : VcsImportMetadataWidget(parent) 0020 , m_ui(new Ui::PerforceImportMetadataWidget) 0021 { 0022 m_ui->setupUi(this); 0023 0024 m_ui->executableLoc->setText(QStringLiteral("/usr/bin/p4")); 0025 m_ui->p4portEdit->setText(QStringLiteral("perforce:1666")); 0026 0027 QProcessEnvironment curEnv = QProcessEnvironment::systemEnvironment(); 0028 m_ui->p4configEdit->setText(curEnv.value(QStringLiteral("P4CONFIG"))); 0029 m_ui->p4portEdit->setText(curEnv.value(QStringLiteral("P4PORT"))); 0030 m_ui->p4userEdit->setText(curEnv.value(QStringLiteral("P4USER"))); 0031 0032 const auto hasP4Config = curEnv.contains(QStringLiteral("P4CONFIG")); 0033 m_ui->radioButtonConfig->setChecked(hasP4Config); 0034 m_ui->radioButtonVariables->setChecked(!hasP4Config); 0035 m_ui->p4configEdit->setEnabled(hasP4Config); 0036 0037 m_ui->sourceLoc->setEnabled(false); 0038 m_ui->sourceLoc->setMode(KFile::Directory); 0039 0040 m_ui->errorMsg->setTextColor(QColor(255, 0, 0)); 0041 m_ui->errorMsg->setReadOnly(true); 0042 0043 m_ui->p4clientEdit->setEditable(true); 0044 0045 connect(m_ui->p4clientEdit, QOverload<const QString&>::of(&KComboBox::returnPressed), 0046 this, &PerforceImportMetadataWidget::changed); 0047 0048 connect(m_ui->radioButtonConfig, &QRadioButton::clicked, m_ui->p4configEdit, &QLineEdit::setEnabled); 0049 connect(m_ui->radioButtonVariables, &QRadioButton::clicked, m_ui->p4configEdit, &QLineEdit::setDisabled); 0050 0051 connect(m_ui->testP4setupButton, &QPushButton::pressed, this, &PerforceImportMetadataWidget::testP4setup); 0052 } 0053 0054 QUrl PerforceImportMetadataWidget::source() const 0055 { 0056 return m_ui->sourceLoc->url(); 0057 } 0058 0059 VcsLocation PerforceImportMetadataWidget::destination() const 0060 { 0061 VcsLocation dest; 0062 dest.setRepositoryServer(m_ui->p4portEdit->text()); 0063 dest.setUserData(QVariant::fromValue(m_ui->p4userEdit->text())); 0064 dest.setRepositoryBranch(m_ui->p4clientEdit->itemText(0)); 0065 return dest; 0066 } 0067 0068 QString PerforceImportMetadataWidget::message() const 0069 { 0070 return QString(); 0071 //TODO: return m_ui->message->toPlainText(); 0072 } 0073 0074 void PerforceImportMetadataWidget::setSourceLocation(const VcsLocation& url) 0075 { 0076 m_ui->sourceLoc->setUrl(url.localUrl()); 0077 } 0078 0079 void PerforceImportMetadataWidget::setSourceLocationEditable(bool enable) 0080 { 0081 m_ui->sourceLoc->setEnabled(enable); 0082 } 0083 0084 void PerforceImportMetadataWidget::setMessage(const QString& message) 0085 { 0086 Q_UNUSED(message); 0087 0088 //FIXME: correct ui field needs to be set 0089 //m_ui->message->setText(message); 0090 } 0091 0092 bool PerforceImportMetadataWidget::hasValidData() const 0093 { 0094 // FIXME: It has valid data if testP4setup has completed correctly. AND client name has been set to something 0095 return !m_ui->p4clientEdit->itemText(0).isEmpty(); 0096 } 0097 0098 void PerforceImportMetadataWidget::testP4setup() 0099 { 0100 m_ui->errorMsg->clear(); 0101 m_ui->p4clientEdit->clear(); 0102 0103 if (!validateP4executable()) 0104 return; 0105 0106 QDir execDir(m_ui->sourceLoc->url().toLocalFile()); 0107 QTemporaryDir tmpDir; 0108 if (!execDir.exists()) 0109 execDir.setPath(tmpDir.path()); 0110 0111 if(!validateP4port(execDir.path())) 0112 return; 0113 0114 if(!validateP4user(execDir.path())) 0115 return; 0116 0117 emit changed(); 0118 } 0119 0120 bool PerforceImportMetadataWidget::validateP4executable() 0121 { 0122 if (QStandardPaths::findExecutable(m_ui->executableLoc->url().toLocalFile()).isEmpty()) { 0123 m_ui->errorMsg->setText( 0124 i18n("Unable to find perforce executable. Is it installed on the system? Is it in your PATH?")); 0125 return false; 0126 } 0127 return true; 0128 } 0129 0130 bool PerforceImportMetadataWidget::validateP4user(const QString& projectDir) const 0131 { 0132 QProcess exec; 0133 QProcessEnvironment p4execEnvironment; 0134 p4execEnvironment.insert(QStringLiteral("P4PORT"), m_ui->p4portEdit->displayText()); 0135 exec.setWorkingDirectory(projectDir); 0136 exec.setProcessEnvironment(p4execEnvironment); 0137 exec.start(m_ui->executableLoc->url().toLocalFile(), QStringList{QStringLiteral("workspaces"), 0138 QStringLiteral("-u"), m_ui->p4userEdit->text()} 0139 ); 0140 exec.waitForFinished(); 0141 0142 const auto processStdout = QString::fromUtf8(exec.readAllStandardOutput()); 0143 const auto processStderr = QString::fromUtf8(exec.readAllStandardError()); 0144 0145 // std::cout << "Exited with code: " << exec.exitCode() << std::endl; 0146 // std::cout << "Exited with stdout" << processStdout.toStdString() << std::endl; 0147 // std::cout << "Exited with stderr" << processStderr.toStdString() << std::endl; 0148 if (exec.exitCode() != 0) { 0149 if(!processStderr.isEmpty()) { 0150 m_ui->errorMsg->setText(processStderr); 0151 } else { 0152 m_ui->errorMsg->setText(i18n("P4 Client failed with exit code: %1", exec.exitCode())); 0153 } 0154 return false; 0155 } 0156 if(!processStdout.isEmpty()) { 0157 const auto clientCmdOutput = processStdout.splitRef(QLatin1Char('\n'), Qt::SkipEmptyParts); 0158 QStringList clientItems; 0159 clientItems.reserve(clientCmdOutput.size()); 0160 for (const auto& clientLine : clientCmdOutput) { 0161 const auto wordsInLine = clientLine.split(QLatin1Char(' ')); 0162 // Client mvo_testkdevinteg 2017/05/22 root C:\P4repo 'Created by mvo. ' -- Line would be expected to look like so 0163 clientItems.append(wordsInLine.at(1).toString()); 0164 } 0165 m_ui->p4clientEdit->addItems(clientItems); 0166 } 0167 return true; 0168 } 0169 0170 bool PerforceImportMetadataWidget::validateP4port(const QString& projectDir) const 0171 { 0172 QProcess exec; 0173 QProcessEnvironment p4execEnvironment; 0174 p4execEnvironment.insert(QStringLiteral("P4PORT"), m_ui->p4portEdit->displayText()); 0175 QTextStream out(stdout); 0176 const auto& env = p4execEnvironment.toStringList(); 0177 for (const QString& x : env) { 0178 out << x << QLatin1Char('\n'); 0179 } 0180 out.flush(); 0181 0182 exec.setWorkingDirectory(projectDir); 0183 exec.setProcessEnvironment(p4execEnvironment); 0184 exec.start(m_ui->executableLoc->url().toLocalFile(), QStringList() << QStringLiteral("info")); 0185 exec.waitForFinished(); 0186 //QString processStdout(exec.readAllStandardOutput()); 0187 const auto processStderr = QString::fromUtf8(exec.readAllStandardError()); 0188 0189 //std::cout << "Exited with code: " << exec.exitCode() << std::endl; 0190 //std::cout << "Exited with stdout" << processStdout.toStdString() << std::endl; 0191 //std::cout << "Exited with stderr" << processStderr.toStdString() << std::endl; 0192 if (exec.exitCode() != 0) { 0193 if(!processStderr.isEmpty()) { 0194 m_ui->errorMsg->setText(processStderr); 0195 } else { 0196 m_ui->errorMsg->setText(i18n("P4 Client failed with error code: %1", exec.exitCode())); 0197 } 0198 return false; 0199 } 0200 return true; 0201 } 0202 0203 #include "moc_perforceimportmetadatawidget.cpp"