From 9761a03334ba90e2b66b5d2f92f578abc4598668 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 6 Sep 2018 16:49:35 +0100 Subject: [PATCH] Projucer: Made it possible to specify a semicolon-separated list of user modules paths to override the global default when generating a project from a PIP using the "--create-project-from-pip" command-line option --- .../Source/Application/jucer_CommandLine.cpp | 39 +++++++++++++--- .../Utility/PIPs/jucer_PIPGenerator.cpp | 45 ++++++++++++------- .../Source/Utility/PIPs/jucer_PIPGenerator.h | 11 ++++- 3 files changed, 70 insertions(+), 25 deletions(-) diff --git a/extras/Projucer/Source/Application/jucer_CommandLine.cpp b/extras/Projucer/Source/Application/jucer_CommandLine.cpp index 4c24b7ad7a..9e2b2ec22b 100644 --- a/extras/Projucer/Source/Application/jucer_CommandLine.cpp +++ b/extras/Projucer/Source/Application/jucer_CommandLine.cpp @@ -659,6 +659,13 @@ namespace || id == "androidSDKPath" || id == "androidNDKPath" || id == "defaultJuceModulePath" || id == "defaultUserModulePath"; } + static void checkIfUserModulesPathsAreValid (const String& list) + { + for (auto& p : StringArray::fromTokens (list, ";", {})) + if (! File (p.trim()).exists()) + ConsoleApplication::fail (p + " doesn't exist!"); + } + static void setGlobalPath (const ArgumentList& args) { args.checkMinNumArguments (3); @@ -697,9 +704,16 @@ namespace ConsoleApplication::fail ("Failed to set the requested setting!"); if (args[2].text == Ids::defaultUserModulePath.toString()) - childToSet.setProperty (args[2].text, args[3].text.removeCharacters ("\""), nullptr); + { + auto pathList = args[3].text.removeCharacters ("\""); + checkIfUserModulesPathsAreValid (pathList); + + childToSet.setProperty (args[2].text, pathList, nullptr); + } else + { childToSet.setProperty (args[2].text, args[3].resolveAsFile().getFullPathName(), nullptr); + } settingsFile.replaceWithText (settingsTree.toXmlString()); } @@ -721,17 +735,27 @@ namespace std::cout << "Creating directory " << outputDir.getFullPathName() << std::endl; } - File juceDir; + File juceModulesPath; + Array userModulesPaths; if (args.size() > 3) { - juceDir = args[3].resolveAsFile(); + juceModulesPath = args[3].resolveAsFile(); - if (! juceDir.exists()) + if (! juceModulesPath.exists()) ConsoleApplication::fail ("Specified JUCE modules directory doesn't exist."); + + if (args.size() == 5) + { + auto pathList = args[4].text.removeCharacters ("\""); + checkIfUserModulesPathsAreValid (pathList); + + for (auto& p : StringArray::fromTokens (pathList, ";", {})) + userModulesPaths.add ({ p }); + } } - PIPGenerator generator (pipFile, outputDir, juceDir); + PIPGenerator generator (pipFile, outputDir, juceModulesPath, userModulesPaths); auto createJucerFileResult = generator.createJucerFile(); @@ -811,8 +835,9 @@ namespace << "defaultJuceModulePath, defaultUserModulePath, vst3Path, aaxPath (not valid on linux), rtasPath (not valid on linux), androidSDKPath or androidNDKPath. " "When setting defaultUserModulePath you can specify multiple paths by surrounding a semicolon-separated list of paths with double quotes \"like;so\"" << std::endl << std::endl - << " " << appName << " --create-project-from-pip path/to/PIP path/to/output path/to/JUCE/modules (optional)" << std::endl - << " Generates a JUCE project from a PIP file." << std::endl + << " " << appName << " --create-project-from-pip path/to/PIP path/to/output path/to/JUCE/modules (optional) path/to/user/modules (optional)" << std::endl + << " Generates a folder containing a JUCE project in the specified output path using the specified PIP file. Use the optional JUCE and user module paths to override " + "the global module paths (you can specify multiple user module paths by using a semicolon-separated list)." << std::endl << std::endl << "Note that for any of the file-rewriting commands, add the option \"--lf\" if you want it to use LF linefeeds instead of CRLF" << std::endl << std::endl; diff --git a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp index 05a09774b9..1431b90381 100644 --- a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp +++ b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp @@ -27,6 +27,7 @@ #include "../../Application/jucer_Headers.h" #include "../../ProjectSaving/jucer_ProjectExporter.h" #include "jucer_PIPGenerator.h" +#include "../../Project/jucer_Module.h" //============================================================================== static String removeEnclosed (const String& input, const String& start, const String& end) @@ -97,9 +98,10 @@ static bool isMobileExporter (const String& exporterName) } //============================================================================== -PIPGenerator::PIPGenerator (const File& pip, const File& output, const File& juceDir) +PIPGenerator::PIPGenerator (const File& pip, const File& output, const File& jucePath, const Array& userPaths) : pipFile (pip), - juceDirectory (juceDir), + juceModulesPath (jucePath), + userModulesPaths (userPaths), metadata (parsePIPMetadata()) { if (output != File()) @@ -118,6 +120,12 @@ PIPGenerator::PIPGenerator (const File& pip, const File& output, const File& juc outputDirectory = outputDirectory.getChildFile (metadata[Ids::name].toString()); useLocalCopy = metadata[Ids::useLocalCopy].toString().isNotEmpty() || isClipboard; + + if (! userModulesPaths.isEmpty()) + { + availableUserModules.reset (new AvailableModuleList()); + availableUserModules->scanPaths (userModulesPaths); + } } //============================================================================== @@ -291,7 +299,7 @@ ValueTree PIPGenerator::createModulePathChild (const String& moduleID) ValueTree modulePath (Ids::MODULEPATH); modulePath.setProperty (Ids::ID, moduleID, nullptr); - modulePath.setProperty (Ids::path, juceDirectory.getFullPathName(), nullptr); + modulePath.setProperty (Ids::path, getPathForModule (moduleID).getFullPathName(), nullptr); return modulePath; } @@ -348,12 +356,7 @@ ValueTree PIPGenerator::createExporterChild (const String& exporterName) auto modules = StringArray::fromTokens (metadata[Ids::dependencies_].toString(), ",", {}); for (auto m : modules) - { - m = m.trim(); - - if (isJUCEModule (m)) - modulePaths.addChild (createModulePathChild (m), -1, nullptr); - } + modulePaths.addChild (createModulePathChild (m.trim()), -1, nullptr); exporter.addChild (modulePaths, -1, nullptr); } @@ -368,7 +371,7 @@ ValueTree PIPGenerator::createModuleChild (const String& moduleID) module.setProperty (Ids::ID, moduleID, nullptr); module.setProperty (Ids::showAllCode, 1, nullptr); module.setProperty (Ids::useLocalCopy, 0, nullptr); - module.setProperty (Ids::useGlobalPath, (juceDirectory == File() ? 1 : 0), nullptr); + module.setProperty (Ids::useGlobalPath, (getPathForModule (moduleID) == File() ? 1 : 0), nullptr); return module; } @@ -407,12 +410,7 @@ void PIPGenerator::addModules (ValueTree& jucerTree) modules.mergeArray (getModulesRequiredForAudioProcessor()); for (auto& m : modules) - { - m = m.trim(); - - if (isJUCEModule (m)) - modulesTree.addChild (createModuleChild (m), -1, nullptr); - } + modulesTree.addChild (createModuleChild (m.trim()), -1, nullptr); jucerTree.addChild (modulesTree, -1, nullptr); } @@ -597,3 +595,18 @@ StringArray PIPGenerator::getPluginCharacteristics() const return {}; } + +File PIPGenerator::getPathForModule (const String& moduleID) const +{ + if (isJUCEModule (moduleID)) + { + if (juceModulesPath != File()) + return juceModulesPath; + } + else if (availableUserModules != nullptr) + { + return availableUserModules->getModuleWithID (moduleID).second.getParentDirectory(); + } + + return {}; +} diff --git a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h index a039588bcf..2dcda2646a 100644 --- a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h +++ b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h @@ -32,7 +32,8 @@ class PIPGenerator { public: - PIPGenerator (const File& pipFile, const File& outputDirectory = {}, const File& juceDirectory = {}); + PIPGenerator (const File& pipFile, const File& outputDirectory = {}, + const File& pathToJUCEModules = {}, const Array& pathsToUserModules = {}); //============================================================================== bool hasValidPIP() const noexcept { return ! metadata[Ids::name].toString().isEmpty(); } @@ -77,8 +78,14 @@ private: StringArray getExtraPluginFormatsToBuild() const; StringArray getPluginCharacteristics() const; + File getPathForModule (const String&) const; + //============================================================================== - File pipFile, outputDirectory, juceDirectory; + File pipFile, outputDirectory, juceModulesPath; + + Array userModulesPaths; + std::unique_ptr availableUserModules; + var metadata; bool isTemp = false;