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

Improve CodeLite symlink handling #3572

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions CodeLite/cl_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class WXDLLIMPEXP_CL clConfigItem
#define kConfigWorkspaceTabSashPosition "WorkspaceTabSashPosition"
#define kConfigTabsPaneSortAlphabetically "TabsPaneSortAlphabetically"
#define kConfigFileExplorerBookmarks "FileExplorerBookmarks"
#define kRealPathResolveSymlinks "RealPathResolveSymlinks"

class WXDLLIMPEXP_CL clConfig
{
Expand Down
25 changes: 19 additions & 6 deletions CodeLite/fileutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
#include <memory>
#include <wx/filename.h>

static bool bRealPathModeResolveSymlinks = true;
UffeJakobsen marked this conversation as resolved.
Show resolved Hide resolved

thread_local std::unordered_set<wxChar> VALID_CHARS = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
Expand Down Expand Up @@ -212,7 +214,9 @@ void FileUtils::OpenFileExplorerAndSelect(const wxFileName& filename)
#endif
}

void FileUtils::OSXOpenDebuggerTerminalAndGetTTY(const wxString& path, const wxString& appname, wxString& tty,
void FileUtils::OSXOpenDebuggerTerminalAndGetTTY(const wxString& path,
const wxString& appname,
wxString& tty,
long& pid)
{
tty.Clear();
Expand Down Expand Up @@ -274,7 +278,9 @@ void FileUtils::OSXOpenDebuggerTerminalAndGetTTY(const wxString& path, const wxS
clDEBUG() << "TTY is:" << tty;
}

void FileUtils::OpenSSHTerminal(const wxString& sshClient, const wxString& connectString, const wxString& password,
void FileUtils::OpenSSHTerminal(const wxString& sshClient,
const wxString& connectString,
const wxString& password,
int port)
{
clConsoleBase::Ptr_t console = clConsoleBase::GetTerminal();
Expand Down Expand Up @@ -595,10 +601,10 @@ unsigned int FileUtils::UTF8Length(const wchar_t* uptr, unsigned int tlen)
}

// This is readlink on steroids: it also makes-absolute, and dereferences any symlinked dirs in the path
wxString FileUtils::RealPath(const wxString& filepath)
wxString FileUtils::RealPath(const wxString& filepath, bool forced)
{
#if defined(__WXGTK__) || defined(__WXOSX__)
if (!filepath.empty()) {
if (!filepath.empty() && (forced || bRealPathModeResolveSymlinks)) {
#if defined(__FreeBSD__) || defined(__WXOSX__)
wxStructStat stbuff;
if ((::wxLstat(filepath, &stbuff) != 0) || !S_ISLNK(stbuff.st_mode)) {
Expand All @@ -617,6 +623,10 @@ wxString FileUtils::RealPath(const wxString& filepath)
return filepath;
}

bool FileUtils::RealPathGetModeResolveSymlinks() { return bRealPathModeResolveSymlinks; }

void FileUtils::RealPathSetModeResolveSymlinks(bool resolveSymlinks) { bRealPathModeResolveSymlinks = resolveSymlinks; }

std::string FileUtils::ToStdString(const wxString& str) { return StringUtils::ToStdString(str); }

bool FileUtils::ReadBufferFromFile(const wxFileName& fn, wxString& data, size_t bufferSize)
Expand Down Expand Up @@ -741,7 +751,9 @@ bool DoFindExe(const wxString& name, wxFileName& exepath, const wxArrayString& h
}
} // namespace

bool FileUtils::FindExe(const wxString& name, wxFileName& exepath, const wxArrayString& hint,
bool FileUtils::FindExe(const wxString& name,
wxFileName& exepath,
const wxArrayString& hint,
const wxArrayString& suffix_list)
{
wxArrayString possible_suffix;
Expand Down Expand Up @@ -780,7 +792,8 @@ wxFileName FileUtils::CreateTempFileName(const wxString& folder, const wxString&
return wxFileName(folder, full_name);
}

size_t FileUtils::FindSimilar(const wxFileName& filename, const std::vector<wxString>& extensions,
size_t FileUtils::FindSimilar(const wxFileName& filename,
const std::vector<wxString>& extensions,
std::vector<wxFileName>& vout)
{
wxFileName fn(filename);
Expand Down
4 changes: 3 additions & 1 deletion CodeLite/fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ class WXDLLIMPEXP_CL FileUtils
/**
* @brief (on Linux) makes-absolute filepath, and dereferences it and any symlinked dirs in the path
*/
static wxString RealPath(const wxString& filepath);
static wxString RealPath(const wxString& filepath, bool forced=false);
static bool RealPathGetModeResolveSymlinks();
static void RealPathSetModeResolveSymlinks(bool resolveSymlinks);

/**
* @brief convert string into std::string
Expand Down
5 changes: 4 additions & 1 deletion LiteEditor/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@ bool CodeLiteApp::OnInit()
// If running under Cygwin terminal, adjust the environment variables
AdjustPathForMSYSIfNeeded();

// Ensure that FileUtils::RealPath handling is setup according to config
FileUtils::RealPathSetModeResolveSymlinks(clConfig::Get().Read(kRealPathResolveSymlinks, true));

// Make sure that the colours and fonts manager is instantiated
ColoursAndFontsManager::Get().Load();

Expand Down Expand Up @@ -1152,4 +1155,4 @@ void CodeLiteApp::FinalizeShutdown()
// Delete the temp folder
wxFileName::Rmdir(clStandardPaths::Get().GetTempDir(), wxPATH_RMDIR_RECURSIVE);
clDEBUG() << "Finalizing shutdown...success" << endl;
}
}
12 changes: 11 additions & 1 deletion LiteEditor/editorsettingsmiscpanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,17 @@ EditorSettingsMiscPanel::EditorSettingsMiscPanel(wxWindow* parent, OptionsConfig
#endif
AddProperty(_("Frame title"), clConfig::Get().Read(kConfigFrameTitlePattern, wxString("$workspace $fullpath")),
UPDATE_CLCONFIG_TEXT_CB(kConfigFrameTitlePattern));

AddHeader(_("File path handling"));
AddProperty(_("Resolve symlinks in file paths"),
clConfig::Get().Read(kRealPathResolveSymlinks, true),
[](const wxString& label, const wxAny& value) {
wxUnusedVar(label);
bool value_bool = true;
if (value.GetAs(&value_bool)) {
clConfig::Get().Write(kRealPathResolveSymlinks, value_bool);
}
FileUtils::RealPathSetModeResolveSymlinks(value_bool);
});
AddHeader(_("Startup"));
AddProperty(_("Check for new version on startup"), clConfig::Get().Read(kConfigCheckForNewVersion, true),
UPDATE_CLCONFIG_BOOL_CB(kConfigCheckForNewVersion));
Expand Down
35 changes: 22 additions & 13 deletions LiteEditor/mainbook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ void MainBook::OnProjectFileAdded(clCommandEvent& e)
for (size_t i = 0; i < files.GetCount(); i++) {
clEditor* editor = FindEditor(files.Item(i));
if (editor) {
wxString fileName = CLRealPath(editor->GetFileName().GetFullPath());
wxString fileName = FileUtils::RealPath(editor->GetFileName().GetFullPath());
if (files.Index(fileName) != wxNOT_FOUND) {
editor->SetProject(ManagerST::Get()->GetProjectNameByFile(fileName));
}
Expand All @@ -272,7 +272,7 @@ void MainBook::OnProjectFileRemoved(clCommandEvent& e)
const wxArrayString& files = e.GetStrings();
for (size_t i = 0; i < files.GetCount(); ++i) {
clEditor* editor = FindEditor(files.Item(i));
if (editor && files.Index(CLRealPath(editor->GetFileName().GetFullPath())) != wxNOT_FOUND) {
if (editor && files.Index(FileUtils::RealPath(editor->GetFileName().GetFullPath())) != wxNOT_FOUND) {
editor->SetProject(wxEmptyString);
}
}
Expand Down Expand Up @@ -451,7 +451,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 = FileUtils::RealPath(fullpath, true);
#endif

for (size_t i = 0; i < m_book->GetPageCount(); ++i) {
Expand All @@ -465,7 +465,7 @@ int MainBook::FindEditorIndexByFullPath(const wxString& fullpath)
}
} else {
// local path
wxString unixStyleFile(CLRealPath(editor->GetFileName().GetFullPath()));
wxString unixStyleFile(FileUtils::RealPath(editor->GetFileName().GetFullPath()));
wxString nativeFile(unixStyleFile);
#ifdef __WXMSW__
unixStyleFile.Replace(wxT("\\"), wxT("/"));
Expand All @@ -485,7 +485,7 @@ int MainBook::FindEditorIndexByFullPath(const wxString& fullpath)

#if defined(__WXGTK__)
// Try again, dereferencing the editor fpath
wxString editorDest = CLRealPath(unixStyleFile);
wxString editorDest = FileUtils::RealPath(unixStyleFile, true);
if (editorDest.Cmp(fullpath) == 0 || editorDest.Cmp(fileNameDest) == 0) {
return i;
}
Expand All @@ -509,12 +509,13 @@ wxWindow* MainBook::FindPage(const wxString& text)
{
for (size_t i = 0; i < m_book->GetPageCount(); i++) {
clEditor* editor = dynamic_cast<clEditor*>(m_book->GetPage(i));
if (editor && CLRealPath(editor->GetFileName().GetFullPath()).CmpNoCase(text) == 0) {
if (editor && FileUtils::RealPath(editor->GetFileName().GetFullPath()).CmpNoCase(text) == 0) {
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 @@ -620,7 +621,14 @@ clEditor* MainBook::OpenFile(const wxString& file_name,
int bmp /*= wxNullBitmap*/,
const wxString& tooltip /* wxEmptyString */)
{
wxFileName fileName(CLRealPath(file_name));
wxFileName fileName(FileUtils::RealPath(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 @@ -1220,7 +1228,7 @@ bool MainBook::DoSelectPage(wxWindow* win)

} else {
wxCommandEvent event(wxEVT_ACTIVE_EDITOR_CHANGED);
event.SetString(CLRealPath(editor->GetFileName().GetFullPath()));
event.SetString(FileUtils::RealPath(editor->GetFileName().GetFullPath()));
EventNotifier::Get()->AddPendingEvent(event);
}
return true;
Expand Down Expand Up @@ -1737,7 +1745,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 = FileUtils::RealPath(file_name, true);
auto editor = FindEditor(real_path);
if (editor) {
push_callback(std::move(callback), real_path);
Expand All @@ -1748,7 +1756,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 @@ -1813,11 +1821,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(FileUtils::RealPath(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(); }

2 changes: 1 addition & 1 deletion Plugin/globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,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(FileUtils::RealPath(filename.GetFullPath(), true));

#else // OSX
wxFileName realFileName;
Expand Down
Loading