| @@ -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<File> 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; | |||
| @@ -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<File>& 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 {}; | |||
| } | |||
| @@ -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<File>& 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<File> userModulesPaths; | |||
| std::unique_ptr<AvailableModuleList> availableUserModules; | |||
| var metadata; | |||
| bool isTemp = false; | |||