Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for local paths and project bundles #5735

Merged
merged 36 commits into from
Apr 2, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5bfad37
Adds a baseDir for the local path
IanCaio Oct 25, 2020
1e89441
Starts implementing the makeBundle functionality
IanCaio Oct 26, 2020
f34e966
Starts implementing logic to go through resources
IanCaio Oct 26, 2020
ff9af55
Adds logic to copy files and update the project
IanCaio Oct 26, 2020
f59cc9c
Makes the writeBundle method more organized
IanCaio Oct 26, 2020
14992ff
Adds a project bundle folder
IanCaio Oct 28, 2020
c174b3e
Handles local paths when a project isn't open
IanCaio Oct 28, 2020
b76e9f8
Sanitizes the bundle name
IanCaio Oct 29, 2020
3aac591
Moves away from projectbundle folder concept
IanCaio Oct 29, 2020
3e86cd6
Adds an option to save project as bundle
IanCaio Oct 29, 2020
218c211
Fix local: prefix saving bug
IanCaio Oct 29, 2020
6b1e5ac
Adds a warning message box
IanCaio Oct 29, 2020
1b13381
Removes unused header
IanCaio Oct 29, 2020
dbffea7
Removes Vestige plugins bundling
IanCaio Oct 31, 2020
2c15d4e
Extracts code from loadProject to another method
IanCaio Oct 31, 2020
598396b
Merge branch 'master' into feature/localPath
IanCaio Nov 9, 2020
93915b9
Merge branch 'master' into feature/localPath
IanCaio Feb 21, 2021
88278ea
Removes debug warnings
IanCaio Feb 21, 2021
14c1d3c
Fixes small bug with error logging
IanCaio Feb 21, 2021
941ad2a
Merge branch 'master' into feature/localPath
IanCaio Mar 18, 2021
465900d
Saves the bundle in a newly created folder
IanCaio Mar 18, 2021
4459d3c
Enhances the name conflict workaround
IanCaio Mar 18, 2021
e0a4c12
Starts addressing Johannes review
IanCaio Mar 25, 2021
43b3dfd
Adds makebundle action to bash completion file
IanCaio Mar 25, 2021
45b62e8
Improves safety check on project files
IanCaio Mar 26, 2021
b8bbea6
Addresses Spekular change request
IanCaio Mar 26, 2021
0ea10ff
Makes hasLocalPlugins method const
IanCaio Mar 26, 2021
8970cc4
Replaces literal uses of "local:"
IanCaio Mar 27, 2021
18c6239
Fix some comments on the header and cpp file
IanCaio Mar 27, 2021
e0eba3c
Changes variable on PathUtil to const
IanCaio Mar 27, 2021
d1d50b5
Leave doxygen comment on CPP file only
IanCaio Mar 28, 2021
9ef814f
Fix doxygen comment @param
IanCaio Mar 28, 2021
64b652d
Remove assert statements
IanCaio Mar 28, 2021
efef46a
Skips local paths when looking for shortest path
IanCaio Mar 28, 2021
5ffc99c
Address Spekular's review
IanCaio Mar 31, 2021
91509bd
Replaces "ok" with "error"
IanCaio Mar 31, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions include/PathUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ namespace PathUtil
LocalDir };

//! Return the directory associated with a given base as a QString
QString LMMS_EXPORT baseLocation(const Base base);
//! Return the directory associated with a given base as a QDir
QDir LMMS_EXPORT baseQDir (const Base base);
//! Optionally, if a pointer to boolean is given the method will
//! use it to indicate whether the prefix could be resolved properly
//! or not.
QString LMMS_EXPORT baseLocation(const Base base, bool* ok = nullptr);
//! Return the directory associated with a given base as a QDir.
//! Optional pointer to boolean to indicate if the prefix could
//! be resolved properly.
QDir LMMS_EXPORT baseQDir (const Base base, bool* ok = nullptr);
//! Return the prefix used to denote this base in path strings
QString LMMS_EXPORT basePrefix(const Base base);
//! Check the prefix of a path and return the base it corresponds to
Expand All @@ -29,13 +34,15 @@ namespace PathUtil
//! Upgrade prefix-less relative paths to the new format
QString LMMS_EXPORT oldRelativeUpgrade(const QString & input);

//! Make this path absolute
QString LMMS_EXPORT toAbsolute(const QString & input);
//! Make this path absolute. If a pointer to boolean is given
//! it will indicate whether the path was converted successfully
QString LMMS_EXPORT toAbsolute(const QString & input, bool* ok = nullptr);
//! Make this path relative to a given base, return an absolute path if that fails
QString LMMS_EXPORT relativeOrAbsolute(const QString & input, const Base base);
//! Make this path relative to any base, choosing the shortest if there are
//! multiple options. Defaults to an absolute path if all bases fail.
QString LMMS_EXPORT toShortestRelative(const QString & input);
//! multiple options. allowLocal defines whether local paths should be considered.
//! Defaults to an absolute path if all bases fail.
QString LMMS_EXPORT toShortestRelative(const QString & input, bool allowLocal = false);

}

Expand Down
5 changes: 3 additions & 2 deletions src/core/DataFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,11 @@ bool DataFile::copyResources(const QString& resourcesDir)
if (el.hasAttribute(*res))
{
// Get absolute path to resource
QString resPath = PathUtil::toAbsolute(el.attribute(*res));
bool ok;
QString resPath = PathUtil::toAbsolute(el.attribute(*res), &ok);
// If we are running without the project loaded (from CLI), "local:" base
// prefixes aren't converted, so we need to convert it ourselves
if (PathUtil::baseLookup(resPath) == PathUtil::Base::LocalDir)
if (!ok)
{
resPath = QFileInfo(m_fileName).path() + "/" + resPath.remove(0,
PathUtil::basePrefix(PathUtil::Base::LocalDir).length());
Expand Down
55 changes: 34 additions & 21 deletions src/core/PathUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ namespace PathUtil
Base::UserLADSPA, Base::DefaultLADSPA, Base::UserSoundfont, Base::DefaultSoundfont, Base::UserGIG, Base::DefaultGIG,
Base::LocalDir };

QString baseLocation(const Base base)
QString baseLocation(const Base base, bool* ok /* = nullptr*/)
{
// ok is true unless something goes wrong
Spekular marked this conversation as resolved.
Show resolved Hide resolved
if (ok) { *ok = true; }

QString loc = "";
switch (base)
{
Expand All @@ -37,28 +40,30 @@ namespace PathUtil
case Base::LocalDir:
{
const Song* s = Engine::getSong();
QString projectPath;
if (s)
{
QString projectPath = s->projectFileName();
projectPath = s->projectFileName();
loc = QFileInfo(projectPath).path();
}
else
{
// Keeps the base prefix so the method calling this
// can handle the situation.
return basePrefix(Base::LocalDir);
}
// We resolved it properly if we had an open Song and the project
// filename wasn't empty
if (ok) { *ok = (s && !projectPath.isEmpty()); }
break;
}
default : return QString("");
}
return QDir::cleanPath(loc) + "/";
JohannesLorenz marked this conversation as resolved.
Show resolved Hide resolved
}

QDir baseQDir (const Base base)
QDir baseQDir (const Base base, bool* ok /* = nullptr*/)
{
if (base == Base::Absolute) { return QDir::root(); }
return QDir(baseLocation(base));
if (base == Base::Absolute)
{
if (ok) { *ok = true; }
return QDir::root();
}
return QDir(baseLocation(base, ok));
}

QString basePrefix(const Base base)
Expand Down Expand Up @@ -131,28 +136,37 @@ namespace PathUtil



QString toAbsolute(const QString & input)
QString toAbsolute(const QString & input, bool* ok /* = nullptr*/)
{
//First, do no harm to absolute paths
QFileInfo inputFileInfo = QFileInfo(input);
if (inputFileInfo.isAbsolute()) { return input; }
if (inputFileInfo.isAbsolute())
{
if (ok) { *ok = true; }
return input;
}
//Next, handle old relative paths with no prefix
QString upgraded = input.contains(":") ? input : oldRelativeUpgrade(input);

Base base = baseLookup(upgraded);
return baseLocation(base) + upgraded.remove(0, basePrefix(base).length());
return baseLocation(base, ok) + upgraded.remove(0, basePrefix(base).length());
}

QString relativeOrAbsolute(const QString & input, const Base base)
{
if (input.isEmpty()) { return input; }
QString absolutePath = toAbsolute(input);
if (base == Base::Absolute) { return absolutePath; }
QString relativePath = baseQDir(base).relativeFilePath(absolutePath);
return relativePath.startsWith("..") ? absolutePath : relativePath;
bool ok;
QString relativePath = baseQDir(base, &ok).relativeFilePath(absolutePath);
// Return the relative path if it didn't result in a path starting with ..
// and the baseQDir was resolved properly
return (relativePath.startsWith("..") || !ok)
? absolutePath
: relativePath;
}

QString toShortestRelative(const QString & input)
QString toShortestRelative(const QString & input, bool allowLocal /* = false*/)
Spekular marked this conversation as resolved.
Show resolved Hide resolved
{
QFileInfo inputFileInfo = QFileInfo(input);
QString absolutePath = inputFileInfo.isAbsolute() ? input : toAbsolute(input);
Expand All @@ -161,10 +175,9 @@ namespace PathUtil
QString shortestPath = relativeOrAbsolute(absolutePath, shortestBase);
for (auto base: relativeBases)
{
// Skip local paths when searching for the shortest relative, since those
// are only allowed for particular resources and will only be applied when
// saving bundles
if (base == Base::LocalDir) { continue; }
// Skip local paths when searching for the shortest relative if those
// are not allowed for that resource
if (base == Base::LocalDir && !allowLocal) { continue; }

QString otherPath = relativeOrAbsolute(absolutePath, base);
if (otherPath.length() < shortestPath.length())
Expand Down