Skip to content

Verify path mappings when using server containers #55

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

Open
wants to merge 5 commits 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
2 changes: 2 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ lsp:
# (selected by a server id specified above) in stdio mode
# Note: launch_command is not used with container subtype servers
# as a command is embedded in a container itself and serves as an entrypoint
# Note: config path mappings are compared with an actual container (with container subtype servers):
# container mappings must contain all the config mappings (destination paths inside containers have to be absolute)
mappings:
- source: "/your/host/source/path"
destination: "/your/local/path/inside/a/container"
Expand Down
55 changes: 43 additions & 12 deletions lsp-docker.el
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,35 @@ the docker container to run the language server."
(f-same? (f-canonical (car it)) (f-canonical (lsp-workspace-root))))
path-mappings))

(defun lsp-docker-verify-path-mappings-against-container (path-mappings container-name)
"Verify that specified path mappings are all included in container's path mappings"
(--all? (let ((source (car it))
(destination (cdr it)))
(-any? (lambda (mapping)
(and (f-same? source (car mapping))
(equal destination (cdr mapping))))
(lsp-docker-get-path-mappings-from-container container-name)))
path-mappings))

(defun lsp-docker-get-path-mappings-from-container (container-name)
"Get path mappings from a container"
(-let ((
(inspection-command-program . inspection-command-arguments)
(--map-when
(equal it "'{{.Mounts}}'")
"'{{json .Mounts}}'"
(s-split " " (format "%s container inspect -f '{{.Mounts}}' %s" lsp-docker-command container-name)))))
(-let (((exit-code . raw-output) (with-temp-buffer
(cons
(apply #'call-process inspection-command-program nil (current-buffer) nil inspection-command-arguments)
(buffer-string)))))
(if (equal exit-code 0)
(let* ((output (s-chop-prefix "'" (s-chop-suffix "'" (s-chomp raw-output))))
(raw-mappings (append (json-parse-string output) nil)) ; using append to convert a vector to a list
(bind-mappings (--filter (and (equal (gethash "Type" it) "bind") (equal (gethash "RW" it) t)) raw-mappings)))
(--map (cons (f-canonical (gethash "Source" it)) (f-canonical (gethash "Destination" it))) bind-mappings))
(user-error "Cannot analyze the following container: %s, exit code: %d" container-name exit-code)))))

(defun lsp-docker-launch-existing-container (docker-container-name &rest _unused)
"Return the docker command to be executed on host.
Argument DOCKER-CONTAINER-NAME name to use for container."
Expand Down Expand Up @@ -416,18 +445,20 @@ Argument DOCKER-CONTAINER-NAME name to use for container."
:priority lsp-docker-default-priority
:server-command server-launch-command
:launch-server-cmd-fn #'lsp-docker-launch-new-container))
('container (lsp-docker-register-client-with-activation-fn
:server-id regular-server-id
:docker-server-id server-id
:path-mappings path-mappings
:docker-image-id nil
:docker-container-name server-container-name
:docker-container-name-suffix nil
:activation-fn (lsp-docker-create-activation-function-by-project-dir (lsp-workspace-root))
:priority lsp-docker-default-priority
:server-command server-launch-command
:launch-server-cmd-fn #'lsp-docker-launch-existing-container))))))
(user-error "Invalid LSP docker config: unsupported server type and/or subtype")))
('container (if (lsp-docker-verify-path-mappings-against-container path-mappings server-container-name)
(lsp-docker-register-client-with-activation-fn
:server-id regular-server-id
:docker-server-id server-id
:path-mappings path-mappings
:docker-image-id nil
:docker-container-name server-container-name
:docker-container-name-suffix nil
:activation-fn (lsp-docker-create-activation-function-by-project-dir (lsp-workspace-root))
:priority lsp-docker-default-priority
:server-command server-launch-command
:launch-server-cmd-fn #'lsp-docker-launch-existing-container)
(user-error "Container path mappings don't match the config ones!")))))))
(user-error "Invalid LSP docker config: unsupported server type and/or subtype or malformed mappings!")))
(user-error (format "Current file: %s is not in a registered project!" (buffer-file-name)))))

(defun lsp-docker-start ()
Expand Down