File: CodeLiteRemoteHelper.cpp

package info (click to toggle)
codelite 17.0.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 136,204 kB
  • sloc: cpp: 491,547; ansic: 280,393; php: 10,259; sh: 8,930; lisp: 7,664; vhdl: 6,518; python: 6,020; lex: 4,920; yacc: 3,123; perl: 2,385; javascript: 1,715; cs: 1,193; xml: 1,110; makefile: 804; cobol: 741; sql: 709; ruby: 620; f90: 566; ada: 534; asm: 464; fortran: 350; objc: 289; tcl: 258; java: 157; erlang: 61; pascal: 51; ml: 49; awk: 44; haskell: 36
file content (164 lines) | stat: -rw-r--r-- 5,536 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "CodeLiteRemoteHelper.hpp"

#include "Platform.hpp"
#include "StringUtils.h"
#include "clWorkspaceManager.h"
#include "codelite_events.h"
#include "event_notifier.h"
#include "globals.h"
#include "macromanager.h"

#if USE_SFTP
#include "clSFTPManager.hpp"
#endif

thread_local wxString m_codeliteRemoteJSONContent;

CodeLiteRemoteHelper::CodeLiteRemoteHelper()
{
    Bind(wxEVT_WORKSPACE_LOADED, &CodeLiteRemoteHelper::OnWorkspaceLoaded, this);
    Bind(wxEVT_WORKSPACE_CLOSED, &CodeLiteRemoteHelper::OnWorkspaceClosed, this);
    if(ThePlatform->Which("ssh", &m_ssh_exe)) {
        ::WrapWithQuotes(m_ssh_exe);
    }
}

CodeLiteRemoteHelper::~CodeLiteRemoteHelper()
{
    Unbind(wxEVT_WORKSPACE_LOADED, &CodeLiteRemoteHelper::OnWorkspaceLoaded, this);
    Unbind(wxEVT_WORKSPACE_CLOSED, &CodeLiteRemoteHelper::OnWorkspaceClosed, this);
}

void CodeLiteRemoteHelper::OnWorkspaceLoaded(clWorkspaceEvent& event)
{
    event.Skip();
    Clear();
    m_isRemoteLoaded = event.IsRemote();

    if(m_isRemoteLoaded) {
        wxString path = event.GetFileName();
        path.Replace("\\", "/");
        path = path.BeforeLast('/');
        m_workspacePath = path;
    } else {
        m_workspacePath = wxFileName(event.GetFileName()).GetPath();
    }
    m_remoteAccount = event.GetRemoteAccount();

    if(m_isRemoteLoaded && m_codeliteRemoteJSONContent.empty()) {
        // load codelite-remote.json file
        wxString codelite_remote_json_path = m_workspacePath + "/.codelite/codelite-remote.json";
#if USE_SFTP
        wxMemoryBuffer membuf;
        if(clSFTPManager::Get().AwaitReadFile(codelite_remote_json_path, m_remoteAccount, &membuf)) {
            wxString content((const char*)membuf.GetData(), wxConvUTF8, membuf.GetDataLen());
            m_codeliteRemoteJSONContent.swap(content);
            ProcessCodeLiteRemoteJSON(codelite_remote_json_path);
        }
#endif
    }
}

void CodeLiteRemoteHelper::OnWorkspaceClosed(clWorkspaceEvent& event)
{
    event.Skip();
    Clear();
}

JSON* CodeLiteRemoteHelper::GetPluginConfig(const wxString& plugin_name) const
{
    if(m_plugins_configs.count(plugin_name) == 0) {
        return nullptr;
    }
    return m_plugins_configs.find(plugin_name)->second;
}

bool CodeLiteRemoteHelper::IsRemoteWorkspaceOpened() const { return m_isRemoteLoaded; }

void CodeLiteRemoteHelper::Clear()
{
    m_isRemoteLoaded = false;
    m_workspacePath.clear();
    m_remoteAccount.clear();
    m_codeliteRemoteJSONContent.clear();
    for(auto& vt : m_plugins_configs) {
        wxDELETE(vt.second);
    }
    m_plugins_configs.clear();
}

bool CodeLiteRemoteHelper::BuildRemoteCommand(const wxString& command, const clEnvList_t& envlist,
                                              const wxString& remote_wd, wxString* out_cmmand) const
{
    if(m_ssh_exe.empty()) {
        return false;
    }

    // build the enviroment string
    wxString envstr;
    if(!envlist.empty()) {
        for(const auto& p : envlist) {
            envstr << p.first << "=" << p.second << " ";
        }
    }
    wxString ssh_command = m_ssh_exe;
    ssh_command << " -o ServerAliveInterval=10 -o StrictHostKeyChecking=no";

    wxString cmd;
    wxString wd = remote_wd.empty() ? "$(WorkspacePath)" : remote_wd;
    cmd << ssh_command << " $(SSH_User)@$(SSH_Host) \"cd " << wd << " && " << envstr << command << "\"";
    *out_cmmand = MacroManager::Instance()->Expand(cmd, clGetManager(), wxEmptyString);
    return true;
}

#if USE_SFTP
namespace
{
void add_formatter_tool(JSONItem& tools_arr, const wxString& name, const wxString& command, const wxString& wd)
{
    auto tool = JSONItem::createObject();
    tool.addProperty("name", name);
    tool.addProperty("command", command);
    tool.addProperty("working_directory", wd);
    tools_arr.arrayAppend(tool);
}
} // namespace

void CodeLiteRemoteHelper::ProcessCodeLiteRemoteJSON(const wxString& filepath)
{
    JSON root(m_codeliteRemoteJSONContent);
    if(!root.isOk()) {
        return;
    }

    auto json = root.toElement();
    {
        // upgrade code: ensure that source code formatter
        // entries exist
        if(!json.hasNamedObject("Source Code Formatter")) {
            // missing the newly added "Source Code Formatter" section
            // add the default entry
            auto json_code_formatter = json.AddObject("Source Code Formatter");
            auto tools_arr = json_code_formatter.AddArray("tools");
            add_formatter_tool(tools_arr, "jq", "jq . -S $(CurrentFileRelPath)", "$(WorkspacePath)");
            add_formatter_tool(tools_arr, "yq", "yq . $(CurrentFileRelPath)", "$(WorkspacePath)");
            add_formatter_tool(tools_arr, "clang-format", "clang-format $(CurrentFileRelPath)", "$(WorkspacePath)");
            add_formatter_tool(tools_arr, "xmllint", "xmllint --format $(CurrentFileRelPath)", "$(WorkspacePath)");
            add_formatter_tool(tools_arr, "rustfmt", "rustfmt --edition 2021 $(CurrentFileRelPath)",
                               "$(WorkspacePath)");
            add_formatter_tool(tools_arr, "black", "black --line-length 80 $(CurrentFileRelPath)", "$(WorkspacePath)");

            // store the file
            clSFTPManager::Get().AsyncWriteFile(json.format(), filepath, m_remoteAccount);
        }
    }

    auto child = json.firstChild();
    while(child.isOk()) {
        wxString plugin_name = child.getName();
        auto p = new JSON(child.format(false));
        m_plugins_configs.insert({ plugin_name, p });
        child = json.nextChild();
    }
}
#endif