JsonWizard: Enable directories as file source in file generator

Change-Id: I303f31311a619a86c5669ec7b15c341ab77a2c48
Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Tim Jenssen
2015-11-16 14:05:15 +01:00
committed by Tobias Hunger
parent 79f82d0d0a
commit db16798e0d
2 changed files with 122 additions and 73 deletions

View File

@@ -40,9 +40,11 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
#include <utils/templateengine.h> #include <utils/templateengine.h>
#include <utils/algorithm.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
#include <QDirIterator>
#include <QVariant> #include <QVariant>
namespace ProjectExplorer { namespace ProjectExplorer {
@@ -108,49 +110,30 @@ bool JsonWizardFileGenerator::setup(const QVariant &data, QString *errorMessage)
return true; return true;
} }
Core::GeneratedFiles JsonWizardFileGenerator::fileList(Utils::MacroExpander *expander, Core::GeneratedFile JsonWizardFileGenerator::generateFile(const File &file,
const QString &wizardDir, const QString &projectDir, Utils::MacroExpander *expander, QString *errorMessage)
QString *errorMessage)
{ {
errorMessage->clear();
QDir wizard(wizardDir);
QDir project(projectDir);
Core::GeneratedFiles result;
foreach (const File &f, m_fileList) {
if (!JsonWizard::boolFromVariant(f.condition, expander))
continue;
const bool keepExisting = f.source.isEmpty();
const QString targetPath = project.absoluteFilePath(expander->expand(f.target));
const QString sourcePath
= keepExisting ? targetPath : wizard.absoluteFilePath(expander->expand(f.source));
const bool isBinary = JsonWizard::boolFromVariant(f.isBinary, expander);
// Read contents of source file // Read contents of source file
const QFile::OpenMode openMode const QFile::OpenMode openMode = file.isBinary.toBool() ?
= JsonWizard::boolFromVariant(isBinary, expander) QIODevice::ReadOnly : (QIODevice::ReadOnly|QIODevice::Text);
? QIODevice::ReadOnly : (QIODevice::ReadOnly|QIODevice::Text);
Utils::FileReader reader; Utils::FileReader reader;
if (!reader.fetch(sourcePath, openMode, errorMessage)) if (!reader.fetch(file.source, openMode, errorMessage))
return Core::GeneratedFiles(); return Core::GeneratedFile();
// Generate file information: // Generate file information:
Core::GeneratedFile gf; Core::GeneratedFile gf;
gf.setPath(targetPath); gf.setPath(file.target);
if (!keepExisting) { if (!file.keepExisting) {
if (isBinary) { if (file.isBinary.toBool()) {
gf.setBinary(true); gf.setBinary(true);
gf.setBinaryContents(reader.data()); gf.setBinaryContents(reader.data());
} else { } else {
// TODO: Document that input files are UTF8 encoded! // TODO: Document that input files are UTF8 encoded!
gf.setBinary(false); gf.setBinary(false);
Utils::MacroExpander nested; Utils::MacroExpander nested;
const File *fPtr = &f; const File *fPtr = &file;
Utils::MacroExpander *thisExpander = &nested; Utils::MacroExpander *thisExpander = &nested;
nested.registerExtraResolver([fPtr, thisExpander](QString n, QString *ret) -> bool { nested.registerExtraResolver([fPtr, thisExpander](QString n, QString *ret) -> bool {
foreach (const File::OptionDefinition &od, fPtr->options) { foreach (const File::OptionDefinition &od, fPtr->options) {
@@ -169,26 +152,93 @@ Core::GeneratedFiles JsonWizardFileGenerator::fileList(Utils::MacroExpander *exp
errorMessage)); errorMessage));
if (!errorMessage->isEmpty()) { if (!errorMessage->isEmpty()) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizard", "When processing \"%1\":<br>%2") *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizard", "When processing \"%1\":<br>%2")
.arg(sourcePath, *errorMessage); .arg(file.source, *errorMessage);
return Core::GeneratedFiles(); return Core::GeneratedFile();
} }
} }
} }
Core::GeneratedFile::Attributes attributes = 0; Core::GeneratedFile::Attributes attributes = 0;
if (JsonWizard::boolFromVariant(f.openInEditor, expander)) if (JsonWizard::boolFromVariant(file.openInEditor, expander))
attributes |= Core::GeneratedFile::OpenEditorAttribute; attributes |= Core::GeneratedFile::OpenEditorAttribute;
if (JsonWizard::boolFromVariant(f.openAsProject, expander)) if (JsonWizard::boolFromVariant(file.openAsProject, expander))
attributes |= Core::GeneratedFile::OpenProjectAttribute; attributes |= Core::GeneratedFile::OpenProjectAttribute;
if (JsonWizard::boolFromVariant(f.overwrite, expander)) if (JsonWizard::boolFromVariant(file.overwrite, expander))
attributes |= Core::GeneratedFile::ForceOverwrite; attributes |= Core::GeneratedFile::ForceOverwrite;
if (keepExisting) if (file.keepExisting)
attributes |= Core::GeneratedFile::KeepExistingFileAttribute; attributes |= Core::GeneratedFile::KeepExistingFileAttribute;
gf.setAttributes(attributes); gf.setAttributes(attributes);
result.append(gf); return gf;
}
Core::GeneratedFiles JsonWizardFileGenerator::fileList(Utils::MacroExpander *expander,
const QString &wizardDir, const QString &projectDir,
QString *errorMessage)
{
errorMessage->clear();
QDir wizard(wizardDir);
QDir project(projectDir);
const QList<File> enabledFiles
= Utils::filtered(m_fileList, [&expander](const File &f) {
return JsonWizard::boolFromVariant(f.condition, expander);
});
const QList<File> concreteFiles
= Utils::transform(enabledFiles,
[&expander, &wizard, &project](const File &f) -> File {
// Return a new file with concrete values based on input file:
File file = f;
file.keepExisting = file.source.isEmpty();
file.target = project.absoluteFilePath(expander->expand(file.target));
file.source = file.keepExisting ? file.target : wizard.absoluteFilePath(
expander->expand(file.source));
file.isBinary = JsonWizard::boolFromVariant(file.isBinary, expander);
return file;
});
QList<File> fileList;
QList<File> dirList;
std::tie(fileList, dirList)
= Utils::partition(concreteFiles, [](const File &f) { return !QFileInfo(f.source).isDir(); });
const QSet<QString> knownFiles
= QSet<QString>::fromList(Utils::transform(fileList, [](const File &f) { return f.target; }));
foreach (const File &dir, dirList) {
QDir sourceDir(dir.source);
QDirIterator it(dir.source, QDir::NoDotAndDotDot | QDir::Files| QDir::Hidden,
QDirIterator::Subdirectories);
while (it.hasNext()) {
const QString relativeFilePath = sourceDir.relativeFilePath(it.next());
const QString targetPath = dir.target + QLatin1Char('/') + relativeFilePath;
if (knownFiles.contains(targetPath))
continue;
// initialize each new file with properties (isBinary etc)
// from the current directory json entry
File newFile = dir;
newFile.source = dir.source + QLatin1Char('/') + relativeFilePath;
newFile.target = targetPath;
fileList.append(newFile);
} }
}
const Core::GeneratedFiles result
= Utils::transform(fileList,
[this, &expander, &errorMessage](const File &f) {
return generateFile(f, expander, errorMessage);
});
if (Utils::contains(result, [](const Core::GeneratedFile &gf) { return gf.path().isEmpty(); }))
return Core::GeneratedFiles();
return result; return result;
} }

View File

@@ -53,18 +53,14 @@ public:
private: private:
class File { class File {
public: public:
File() : bool keepExisting = false;
condition(true), isBinary(false), overwrite(false),
openInEditor(false), openAsProject(false)
{ }
QString source; QString source;
QString target; QString target;
QVariant condition; QVariant condition = true;
QVariant isBinary; QVariant isBinary = false;
QVariant overwrite; QVariant overwrite = false;
QVariant openInEditor; QVariant openInEditor = false;
QVariant openAsProject; QVariant openAsProject = false;
class OptionDefinition { class OptionDefinition {
public: public:
@@ -75,6 +71,9 @@ private:
QList<OptionDefinition> options; QList<OptionDefinition> options;
}; };
Core::GeneratedFile generateFile(const File &file, Utils::MacroExpander *expander,
QString *errorMessage);
QList<File> m_fileList; QList<File> m_fileList;
}; };