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

Translate docker paths when cider-docker-translations alist is set #2606

Merged
merged 1 commit into from
Oct 6, 2019

Conversation

dpsutton
Copy link
Contributor

@dpsutton dpsutton commented Mar 19, 2019

If you connect to a running docker image, often the source is mounted
in the docker image. This breaks navigation as rather than navigating
to "/home/me/projects/foo/src/ns.clj" it believes the file is
"/src/ns.clj". This allows rewriting of these prefixes so the
locations can map back to the local filesystem.

  • The commits are consistent with our contribution guidelines
  • You've added tests (if possible) to cover your change(s)
  • All tests are passing (make test)
  • All code passes the linter (make lint) which is based on elisp-lint and includes
  • You've updated the changelog (if adding/changing user-visible functionality)
  • You've updated the user manual (if adding/changing user-visible functionality)

@dpsutton dpsutton force-pushed the translate-docker-paths branch 2 times, most recently from 1affa8c to fdfb430 Compare March 19, 2019 04:30
@dpsutton
Copy link
Contributor Author

At work we have four projects that are run inside of docker container. The local source and m2 directories are mounted inside so navigation is broken in almost all files as the source directory is reported to be the mounted directories inside of the docker container.

Please let me know if i've poorly reinvented TRAMP as I don't know how to use it to connect to the docker container, but it seemed straight forward to swap the prefixes on filenames from docker to host so navigation works again. Evaluation and navigation are about 98% of my CIDER workflow so this works well for me.

@bbatsov
Copy link
Member

bbatsov commented Mar 19, 2019

I'll have to think a bit about this. I agree we need some solution, but I wonder if we can come up with something more generic.

@dpsutton
Copy link
Contributor Author

I appreciate your thoughts @bbatsov . I actually have limited docker experience and this was born out of frustration at the new job. I can keep prototyping other things as well. I am not married to this implementation, this just helped me get back to working.

@bbatsov
Copy link
Member

bbatsov commented Mar 20, 2019

Understood. I've never used docker containers for development, so I can't really provide any insight (I've used them only for deployment and testing purposes). I do think that maybe we can have some list of functions for the filename translation, instead of hardcoding all sorts of possible behaviours, as we currently have been doing. Maybe we can just have some list where people can add more functions and they would be looped over until some match is found. Sounds like something reasonable to me.

cider-common.el Outdated
:group 'cider
:package-version '(cider . "0.22.0"))

(defun cider--translate-docker (path translations)
Copy link
Member

Choose a reason for hiding this comment

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

If this function is going to be called translate-docker then I think it doesn't need the second argument, and it can just use the cider-docker-translations variable directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree and originally wrote it that way. The reason I changed is because the tests. Buttercup does not allow let bindings to span multiple expect forms it seems so i just made it an argument to aid in testing.

(let [cider-docker-translations ((...)))
  (expect ..
  (expect ..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or perhaps it forms. It would work when interactively evaluating the buttercup tests but make test would not work correctly.

to the oringal location. If your project is located at \"~/projects/foo\"
and the src directory of foo is mounted at \"/src\" in the docker
container, the alist would be `((\"/src\" \"~/projects/foo/src\"))"
:type '(alist :key-type string :value-type string)
Copy link
Member

Choose a reason for hiding this comment

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

:value-type directory (or was it dir?) might be a little more appropriate. :key-type probably should stay as string since it's not an actual directory in the user's system.

cider-common.el Outdated
Looks at `cider-docker-translations' for (docker . host) alist of path
prefixes. TRANSLATIONS is an alist of docker prefix to host prefix."
(seq-some (lambda (translation)
(when (string-prefix-p (car translation) path)
Copy link
Member

Choose a reason for hiding this comment

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

file-in-directory-p is probably what you're looking for.

cider-common.el Outdated
(when (string-prefix-p (car translation) path)
(replace-regexp-in-string (format "^%s" (file-name-as-directory (car translation)))
(file-name-as-directory (cdr translation))
path)))
Copy link
Member

Choose a reason for hiding this comment

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

do we know that translation and path are in the same format? For instance, one might be written as ~/project and the other as /home/project. If that's the case, expand-file-name might be more appropriate than file-name-as-directory.

cider-common.el Outdated
prefixes. TRANSLATIONS is an alist of docker prefix to host prefix."
(seq-some (lambda (translation)
(when (string-prefix-p (car translation) path)
(replace-regexp-in-string (format "^%s" (file-name-as-directory (car translation)))
Copy link
Member

Choose a reason for hiding this comment

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

Don't forget to regexp-quote :-)

@Malabarba
Copy link
Member

I left a few comments on the elisp code, but now I wonder if can't make this feature a little more generic. Maybe there are other situations in which the server's code path is different from the code path that emacs is editing.

It probably wouldn't require any other code changes, just change the variable and function name from "docker translation" to "path translation".

@stale
Copy link

stale bot commented May 8, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution and understanding!

@stale stale bot added the stale label May 8, 2019
@stale stale bot removed the stale label May 10, 2019
@bbatsov
Copy link
Member

bbatsov commented May 16, 2019

It probably wouldn't require any other code changes, just change the variable and function name from "docker translation" to "path translation".

My point exactly. @alexander-yakushev also reminded me today that SLIME has a very similar generic feature named slime-filename-translations. I thought we had this already, but it seems we don't.

@dpsutton dpsutton force-pushed the translate-docker-paths branch 2 times, most recently from b082a03 to 43cb75a Compare June 24, 2019 13:04
@dpsutton dpsutton force-pushed the translate-docker-paths branch 2 times, most recently from 13e7524 to 152bafa Compare August 23, 2019 16:51
@wandersoncferreira
Copy link

hi, only to ease the life of other people running around solutions to this problem, I just used the following code (compilation of this PR) to solve this problem at my local config.

(eval-after-load "cider"
  '(progn
     (defcustom cider-docker-translations nil
       "Translate docker endpoints to home dirs."
       :type '(alist :key-type string :value-type string)
       :group 'cider)

     (defun cider--translate-docker (path)
       "Attempt to translate the PATH.
Looks at `cider-docker-translations' for (docker . host) alist of path
prefixes.  TRANSLATIONS is an alist of docker prefix to host prefix."
       (hack-dir-local-variables)
       (seq-some (lambda (translation)
                   (when (string-prefix-p (car translation) path)
                     (replace-regexp-in-string (format "^%s" (file-name-as-directory (car translation)))
                                               (file-name-as-directory (cdr translation))
                                               path)))
                 cider-docker-translations))

     (defun cider--file-path (path)
       "Return PATH's local or tramp path using `cider-prefer-local-resources'.
If no local or remote file exists, return nil."
       (let* ((local-path (funcall cider-from-nrepl-filename-function path))
              (tramp-path (and local-path (cider--client-tramp-filename local-path)))
              (reverse-docker-path (cider--translate-docker local-path)))
         (cond ((equal local-path "") "")
               ((and reverse-docker-path (file-exists-p reverse-docker-path)) reverse-docker-path)
               ((and cider-prefer-local-resources (file-exists-p local-path))
                local-path)
               ((and tramp-path (file-exists-p tramp-path))
                tramp-path)
               ((and local-path (file-exists-p local-path))
                local-path))))))

Inside the folder of each project I have a .dir-locals.el file with the following content:

((nil (cider-docker-translations ("/app/src" . "/home/wand/platform/register/src"))))

Where /app/src is the volume mapped in my docker container and /home/wand/platform/register/src/ happens to be my pwd path inside the directory of the project at my machine.

It's not clear to me which points do we need to work on to proceed with this PR, could you help me on this?

@bbatsov
Copy link
Member

bbatsov commented Sep 14, 2019

@dpsutton What's the state of this PR? I see you're rebasing it from time to time, but I don't see changes to the original code.

@dpsutton
Copy link
Contributor Author

@bbatsov no changes, i just rebase it onto master when i pull CIDER on my work machine. I just got back from strange loop and will finish this this week

@bbatsov
Copy link
Member

bbatsov commented Sep 21, 2019

@dpsutton Great! It always feels good to wrap a long running PR. :-)

@dpsutton
Copy link
Contributor Author

dpsutton commented Oct 1, 2019

test failing due to melpa issues but i'll kick them off again in a bit

  - Installing [ 3/11] spinner (1.7)... not available
  - Installing [ 4/11] queue (0.2)... not available

@bbatsov
Copy link
Member

bbatsov commented Oct 2, 2019

@dpsutton Seems you forgot to update the docs.

@@ -78,6 +78,26 @@ To prefer local resources to remote resources (tramp) when both are available:
(setq cider-prefer-local-resources t)
```

## Source path translations
Copy link
Member

Choose a reason for hiding this comment

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

Just noticed you've added this to wrong manual. See the folder name. ;-) The real one is under doc.

@bbatsov
Copy link
Member

bbatsov commented Oct 3, 2019

You'll also have to rebase due to some conflicts in the changelog.

@dpsutton dpsutton force-pushed the translate-docker-paths branch 2 times, most recently from 3854a80 to 5306132 Compare October 4, 2019 15:24
@bbatsov
Copy link
Member

bbatsov commented Oct 5, 2019

@dpsutton I plan to release the next CIDER on Monday. I hope we'll manage to squeeze this PR there.

I'm just summarize here was needs to be done:

  • rebase on master (this should fix the broken build)
  • Move the documentation to the new AsciiDoc manual

If you connect to a running docker image, often the source is mounted
in the docker image. This breaks navigation as rather than navigating
to "/home/me/projects/foo/src/ns.clj" it believes the file is
"/src/ns.clj". This allows rewriting of these prefixes so the
locations can map back to the local filesystem.
@dpsutton
Copy link
Contributor Author

dpsutton commented Oct 5, 2019

Ok i think docs and rebasing should be fixed. I'm getting several failed tests relating to the figwheel-main init form unfortunately. I'll see what i can get done.

@bbatsov bbatsov merged commit 0cb5daa into clojure-emacs:master Oct 6, 2019
@bbatsov
Copy link
Member

bbatsov commented Oct 6, 2019

It seems the other failure is unrelated, although I'm curious where this breakage originated. Likely something to do with #2698.

@dpsutton dpsutton deleted the translate-docker-paths branch October 26, 2019 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants