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

DRAFT: Improved FSW symlink handling #3550

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions CodeLite/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ target_include_directories(libcodelite
"${CL_SRC_ROOT}/CodeLite"
"${CL_SRC_ROOT}/CodeLite/ssh"
"${CL_SRC_ROOT}/PCH"
"${CL_SRC_ROOT}/Interfaces"
"${CL_SRC_ROOT}/Plugin"
PRIVATE
"${CL_SRC_ROOT}/submodules/asio/asio/include"
"${CL_SRC_ROOT}/submodules/websocketpp"
Expand Down
23 changes: 12 additions & 11 deletions CodeLite/clFilesCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "file_logger.h"
#include "fileutils.h"
#include "globals.h"

#include <queue>
#include <unordered_set>
Expand Down Expand Up @@ -110,19 +111,19 @@ size_t clFilesScanner::Scan(const wxString& rootFolder, std::vector<wxString>& f
filename.MakeLower();
#endif
bool isDirectory = wxFileName::DirExists(fullpath);
// Use FileUtils::RealPath() here to cope with symlinks on Linux
// Use CLRealPath() here to cope with symlinks on Linux
bool isExcludeDir =
isDirectory &&
(
#if defined(__FreeBSD__)
((FileUtils::IsSymlink(fullpath) && excludeFolders.count(FileUtils::RealPath(fullpath)))
((FileUtils::IsSymlink(fullpath) && excludeFolders.count(CLRealPath(fullpath)))
#else
(excludeFolders.count(FileUtils::RealPath(fullpath))
(excludeFolders.count(CLRealPath(fullpath))
#endif
|| IsRelPathContainedInSpec(rootFolder, fullpath, excludeFolders)));
if (isDirectory && !isExcludeDir) {
// Traverse into this folder
wxString realPath = FileUtils::RealPath(fullpath);
wxString realPath = CLRealPath(fullpath);
if (Visited.insert(realPath).second) {
Q.push(fullpath);
}
Expand Down Expand Up @@ -153,8 +154,8 @@ size_t clFilesScanner::Scan(const wxString& rootFolder, const wxString& filespec
std::queue<wxString> Q;
std::unordered_set<wxString> Visited;

Q.push(FileUtils::RealPath(rootFolder));
Visited.insert(FileUtils::RealPath(rootFolder));
Q.push(CLRealPath(rootFolder));
Visited.insert(CLRealPath(rootFolder));

size_t nCount = 0;
while (!Q.empty()) {
Expand All @@ -174,11 +175,11 @@ size_t clFilesScanner::Scan(const wxString& rootFolder, const wxString& filespec
fullpath << dir.GetNameWithSep() << filename;
bool isDirectory = wxFileName::DirExists(fullpath);
bool isFile = !isDirectory;
// Use FileUtils::RealPath() here to cope with symlinks on Linux
// Use CLRealPath() here to cope with symlinks on Linux
if (isDirectory /* a folder */ &&
!FileUtils::WildMatch(excludeFoldersSpecArr, filename) /* does not match the exclude folder spec */) {
// Traverse into this folder
wxString real_path = FileUtils::RealPath(fullpath);
wxString real_path = CLRealPath(fullpath);
if (Visited.count(real_path) == 0) {
Visited.insert(real_path);
Q.push(fullpath);
Expand Down Expand Up @@ -259,8 +260,8 @@ void clFilesScanner::ScanWithCallbacks(const wxString& rootFolder, std::function
std::vector<wxString> Q;
std::unordered_set<wxString> Visited;

Q.push_back(FileUtils::RealPath(rootFolder));
Visited.insert(FileUtils::RealPath(rootFolder));
Q.push_back(CLRealPath(rootFolder));
Visited.insert(CLRealPath(rootFolder));

while (!Q.empty()) {
wxString dirpath = Q.front();
Expand Down Expand Up @@ -299,7 +300,7 @@ void clFilesScanner::ScanWithCallbacks(const wxString& rootFolder, std::function

if (on_folder_cb && on_folder_cb(fullpath)) {
// Traverse into this folder
wxString real_path = FileUtils::RealPath(fullpath);
wxString real_path = CLRealPath(fullpath);
if (Visited.insert(real_path).second) {
Q.push_back(fullpath);
}
Expand Down
23 changes: 16 additions & 7 deletions LiteEditor/mainbook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ int MainBook::FindEditorIndexByFullPath(const wxString& fullpath)
{
#ifdef __WXGTK__
// On gtk either fileName or the editor filepath (or both) may be (or their paths contain) symlinks
wxString fileNameDest = CLRealPath(fullpath);
wxString fileNameDest = CLRealPath(fullpath, true);
#endif

for (size_t i = 0; i < m_book->GetPageCount(); ++i) {
Expand Down Expand Up @@ -489,7 +489,7 @@ int MainBook::FindEditorIndexByFullPath(const wxString& fullpath)

#if defined(__WXGTK__)
// Try again, dereferencing the editor fpath
wxString editorDest = CLRealPath(unixStyleFile);
wxString editorDest = CLRealPath(unixStyleFile, true);
if (editorDest.Cmp(fullpath) == 0 || editorDest.Cmp(fileNameDest) == 0) {
return i;
}
Expand Down Expand Up @@ -517,8 +517,9 @@ wxWindow* MainBook::FindPage(const wxString& text)
return editor;
}

if (m_book->GetPageText(i) == text)
if (m_book->GetPageText(i) == text) {
return m_book->GetPage(i);
}
}
return NULL;
}
Expand Down Expand Up @@ -625,6 +626,13 @@ clEditor* MainBook::OpenFile(const wxString& file_name,
const wxString& tooltip /* wxEmptyString */)
{
wxFileName fileName(CLRealPath(file_name));

if (fileName.IsRelative()) {
if (clWorkspaceManager::Get().IsWorkspaceOpened()) {
wxFileName wsPath = clWorkspaceManager::Get().GetWorkspace()->GetDir();
fileName.MakeAbsolute(wsPath.GetFullPath());
}
}
fileName.MakeAbsolute();

#ifdef __WXMSW__
Expand Down Expand Up @@ -1741,7 +1749,7 @@ WelcomePage* MainBook::GetWelcomePage(bool createIfMissing)

clEditor* MainBook::OpenFileAsync(const wxString& file_name, std::function<void(IEditor*)>&& callback)
{
wxString real_path = CLRealPath(file_name);
wxString real_path = CLRealPath(file_name, true);
auto editor = FindEditor(real_path);
if (editor) {
push_callback(std::move(callback), real_path);
Expand All @@ -1752,7 +1760,7 @@ clEditor* MainBook::OpenFileAsync(const wxString& file_name, std::function<void(
m_book->SetSelection(index);
}
} else {
editor = OpenFile(real_path);
editor = OpenFile(file_name);
if (editor) {
push_callback(std::move(callback), real_path);
}
Expand Down Expand Up @@ -1817,11 +1825,12 @@ void MainBook::OnIdle(wxIdleEvent& event)
auto editor = GetActiveEditor();
CHECK_PTR_RET(editor);

execute_callbacks_for_file(CLRealPath(editor->GetFileName().GetFullPath()));
execute_callbacks_for_file(CLRealPath(editor->GetFileName().GetFullPath(), true));
}

void MainBook::OnEditorModified(clCommandEvent& event) { event.Skip(); }

void MainBook::OnEditorSaved(clCommandEvent& event) { event.Skip(); }

void MainBook::OnSessionLoaded(clCommandEvent& event) { event.Skip(); }
void MainBook::OnSessionLoaded(clCommandEvent& event) { event.Skip(); }

12 changes: 9 additions & 3 deletions Plugin/globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@
#include "SFTPBrowserDlg.h"
#endif

static const char* pEnv_CL_RealPath = getenv("CL_REALPATH");

const wxEventType wxEVT_COMMAND_CL_INTERNAL_0_ARGS = ::wxNewEventType();
const wxEventType wxEVT_COMMAND_CL_INTERNAL_1_ARGS = ::wxNewEventType();

Expand Down Expand Up @@ -928,7 +930,7 @@ wxFileName wxReadLink(const wxFileName& filename)
if (wxIsFileSymlink(filename)) {
#if defined(__WXGTK__)
// Use 'realpath' on Linux, otherwise this breaks on relative symlinks, and (untested) on symlinks-to-symlinks
return wxFileName(CLRealPath(filename.GetFullPath()));
return wxFileName(CLRealPath(filename.GetFullPath(), true));

#else // OSX
wxFileName realFileName;
Expand All @@ -948,10 +950,14 @@ wxFileName wxReadLink(const wxFileName& filename)
#endif
}

wxString CLRealPath(const wxString& filepath) // This is readlink on steroids: it also makes-absolute, and dereferences
wxString CLRealPath(const wxString& filepath, bool force) // This is readlink on steroids: it also makes-absolute, and dereferences
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably move this logic into FileUtils

// any symlinked dirs in the path
{
return FileUtils::RealPath(filepath);
if (force || pEnv_CL_RealPath) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making this a static variable inside FileUtils makes more sense

return FileUtils::RealPath(filepath);
} else {
return filepath;
}
}

int wxStringToInt(const wxString& str, int defval, int minval, int maxval)
Expand Down
2 changes: 1 addition & 1 deletion Plugin/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ WXDLLIMPEXP_SDK wxFileName wxReadLink(const wxFileName& filename);
/**
* @brief makes-absolute filepath, and dereferences it and any symlinked dirs in the path
*/
WXDLLIMPEXP_SDK wxString CLRealPath(const wxString& filepath);
WXDLLIMPEXP_SDK wxString CLRealPath(const wxString& filepath, bool force=false);

/**
* @brief convert string to integer using range validation and default value
Expand Down
Loading