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

Modify package info to return remote path #1100

Open
wants to merge 21 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
10 changes: 9 additions & 1 deletion lisp/ess-inf.el
Original file line number Diff line number Diff line change
Expand Up @@ -2918,7 +2918,15 @@ path), in such a way that the host and connection information (if
any) in OLD is retained in the NEW path. NEW must be an absolute
path, and can be a remote path"
(concat (file-remote-p old)
(or (file-remote-p new 'localname) new)))
(ess--path-get-local-portion new)))

(defun ess--path-get-local-portion (path)
"Obtain the local portion of a (possibly remote) path.
If the string PATH is determined to be a local path, then the
value of PATH is returned unchanged. Otherwise, the portion of
the string in PATH that represents the local portion of the path
is returned."
(or (file-remote-p path 'localname) path))

;; search path
(defun ess--mark-search-list-as-changed ()
Expand Down
16 changes: 8 additions & 8 deletions lisp/ess-r-package.el
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,9 @@ efficiency reasons."
(let* ((path (ess-r-package--find-package-path (or dir default-directory)))
(name (when path
(ess-r-package--find-package-name path)))
(local (if (and path (file-remote-p path))
(tramp-file-name-localname (tramp-dissect-file-name path))
path))
(info (if name
(list :name name
:root local)
:root path)
'(nil))))
;; If DIR was supplied we cannot cache in the current buffer.
(if dir
Expand Down Expand Up @@ -219,9 +216,11 @@ DIR defaults to the current buffer's file name (if non-nil) or
"Set process directory to current package directory."
(interactive)
(let ((pkg-root (plist-get (ess-r-package-info) :root)))
(if pkg-root
(ess-set-working-directory (abbreviate-file-name pkg-root))
(user-error "Not in a project"))))
(unless pkg-root
(user-error "Not in a project"))
(let* ((lpath (ess--path-get-local-portion pkg-root))
(lpath-abbreviated (abbreviate-file-name lpath)))
(ess-set-working-directory lpath-abbreviated))))


;;;*;;; Evaluation
Expand Down Expand Up @@ -262,7 +261,8 @@ arguments, or expressions which return R arguments."
(ess-project-save-buffers)
(message msg (plist-get pkg-info :name))
(display-buffer (ess-get-process-buffer))
(let ((pkg-path (concat "'" (abbreviate-file-name (plist-get pkg-info :root)) "'")))
(let* ((lpath (ess--path-get-local-portion (plist-get pkg-info :root)))
(pkg-path (concat "'" (abbreviate-file-name lpath) "'")))
(ess-eval-linewise (format command (concat pkg-path args))))))

(defun ess-r-command--build-args (ix &optional actions)
Expand Down
6 changes: 5 additions & 1 deletion test/ess-test-inf.el
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ some. text
(should (cl-every #'string= (ess-get-words-from-vector "c('aaa','bbb\"ccc', 'dddd')\n")
'("aaa" "bbb\\\"ccc" "dddd")))))

(ert-deftest ess--derive-connection-path ()
(ert-deftest ess--derive-connection-path-test ()
(let* ((old-localname "/path/to/file")
(new-localname "/home/username/projects")
(connection-basic "/ssh:melancholia.danann.net:")
Expand Down Expand Up @@ -424,6 +424,10 @@ some. text
(should (funcall check-new-remotepath ""))
(should (funcall check-new-remotepath connection-basic))))

(ert-deftest ess--path-get-local-portion-test ()
(should (string= "/path/to/file" (ess--path-get-local-portion "/path/to/file")))
(should (string= "/some/file" (ess--path-get-local-portion "/ssh:melancholia.danann.net:/some/file"))))

;; Test runners

;; Note that we add R-3.2.1 to continuous integration via a symlink to
Expand Down
139 changes: 139 additions & 0 deletions test/ess-test-r-package.el
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
(require 'ert)
(require 'ess-r-mode)
(require 'ess-r-package)
(require 'ess-r-flymake)
(require 'ess-test-r-utils)

;;; Code:
Expand Down Expand Up @@ -102,12 +103,150 @@
(should (string= (plist-get pkg-info :name) "foo"))
(should (string-match-p "dummy-pkg$" (plist-get pkg-info :root)))
(kill-buffer)))
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/R/test.R")
(let ((pkg-info (ess-r-package-info)))
(should (string= (plist-get pkg-info :name) "foo"))
(should (string-match-p "^/mock:.*dummy-pkg$" (plist-get pkg-info :root)))
(kill-buffer)))
(with-ess-test-c-file "dummy-pkg/src/test.c"
(let ((pkg-info (ess-r-package-info)))
(should (string= (plist-get pkg-info :name) "foo"))
(should (string-match-p "dummy-pkg$" (plist-get pkg-info :root)))
(kill-buffer)))))

(ert-deftest ess-r-package-project-test ()
(with-ess-test-r-file "dummy-pkg/R/test.R"
(let ((project-info (ess-r-package-project)))
(should (equal 'ess-r-package (car project-info)))
(should (string-match-p "dummy-pkg$" (cdr project-info)))
(kill-buffer)))
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/R/test.R")
(let ((project-info (ess-r-package-project)))
(should (equal 'ess-r-package (car project-info)))
(should (string-match-p "^/mock:.*dummy-pkg$" (cdr project-info)))
(kill-buffer))))

(ert-deftest ess-r-package-use-dir-test ()
(with-ess-test-r-file "dummy-pkg/R/test.R"
(with-r-running (current-buffer)
(ess-set-working-directory "/")
(ess-wait-for-process)
(should (string= (ess-get-working-directory) "/"))
(ess-r-package-use-dir)
(ess-wait-for-process)
(should (string-match-p "dummy-pkg$" (ess-get-working-directory))))
(kill-buffer))
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/R/test.R")
(with-r-running (current-buffer)
(should (string-match-p "/mock:.*/dummy-pkg/R/test.R" buffer-file-name))
(ess-set-working-directory "/")
(ess-wait-for-process)
(should (string= (ess-get-working-directory) "/"))
(ess-r-package-use-dir)
(ess-wait-for-process)
(should (string-match-p "dummy-pkg$" (ess-get-working-directory)))
(kill-buffer))))

;; Return DIR unless both (i) DIR is the path of package root directory and (ii)
;; the buffer file name is in the tests/ package directory. When both (i) and
;; (ii) hold then return the path corresponding to tests/.
(ert-deftest inferior-ess-r--adjust-startup-directory-test ()
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/tests/example.R")
(let* ((pkg-dir (plist-get (ess-r-package-info) :root))
(inst-dir (expand-file-name "inst" pkg-dir))) ;; arbitrary non-package root directory choice
(should (string-match-p "^/mock:.*/dummy-pkg/tests/$" default-directory))
(should (string-match-p "^/mock:.*/dummy-pkg$" pkg-dir))
(should (string= inst-dir
(inferior-ess-r--adjust-startup-directory inst-dir "R")))
(should (string= default-directory
(inferior-ess-r--adjust-startup-directory pkg-dir "R"))))
(kill-buffer)))

(ert-deftest ess-r-package-source-dirs-test ()
(with-ess-test-r-file "dummy-pkg/R/test.R"
(let ((source-dirs (ess-r-package-source-dirs)))
(should (string-match-p ".*/dummy-pkg/R$" (car source-dirs)))
(should (string-match-p ".*/dummy-pkg/src$" (car (cdr source-dirs))))
(should (null (cdr (cdr source-dirs))))
(kill-buffer)))
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/R/test.R")
(let ((source-dirs (ess-r-package-source-dirs)))
(should (string-match-p "^/mock:.*/dummy-pkg/R$" (car source-dirs)))
(should (string-match-p "^/mock:.*/dummy-pkg/src$" (car (cdr source-dirs))))
(should (null (cdr (cdr source-dirs))))
(kill-buffer))))

(ert-deftest ess-r-package-save-buffers-test ()
;; modify a file within an R package and try to save it
(with-ess-test-r-file "dummy-pkg/R/test.R"
(let ((new-path (expand-file-name "tmp.R")))
(write-region "" nil new-path)
(find-file new-path)
(should (string-match-p ".*/dummy-pkg/R/tmp.R$" buffer-file-name))
(should (not (buffer-modified-p)))
(insert "# buffer update")
(should (buffer-modified-p))
(let ((ess-save-silently t))
(ess-project-save-buffers)
(should (string-match-p ".*/dummy-pkg/R/tmp.R$" buffer-file-name))
(should (not (buffer-modified-p))))
(kill-buffer "test.R")
(kill-buffer "tmp.R")
(delete-file new-path)))
;; modify a file within an R package with a remote path and try to save it
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/R/test.R")
(let ((new-path (expand-file-name "tmp.R")))
(write-region "" nil new-path)
(find-file new-path)
(should (string-match-p "^/mock:.*/dummy-pkg/R/tmp.R$" buffer-file-name))
(should (not (buffer-modified-p)))
(insert "# buffer update")
(should (buffer-modified-p))
(let ((ess-save-silently t))
(ess-project-save-buffers)
(should (string-match-p "^/mock:.*/dummy-pkg/R/tmp.R$" buffer-file-name))
(should (not (buffer-modified-p))))
(kill-buffer "test.R")
(kill-buffer "tmp.R")
(delete-file new-path))))

(ert-deftest ess-r-package-eval-linewise-test ()
(let ((output-regex "^# '.*/dummy-pkg'$"))
;; Test with an R package on a local filesystem
(with-ess-test-r-file "dummy-pkg/R/test.R"
(with-r-running (current-buffer)
(let ((actual (output (ess-r-package-eval-linewise "# %s"))))
(should (string-match-p output-regex actual))))
(kill-buffer))
;; Test with an R package on a remote filesystem. The remote prefix portion
;; of the package location should be stripped from the command.
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/R/test.R")
(with-r-running (current-buffer)
(should (string-match-p "^/mock:.*/dummy-pkg/R/test.R$" buffer-file-name))
(let ((actual (output (ess-r-package-eval-linewise "# %s"))))
(should (string-match-p output-regex actual))
(should (not (string-match-p "/mock:" actual)))))
(kill-buffer))))

(ert-deftest ess-r--flymake-parse-output-test ()
(with-ess-test-r-file (ess-test-create-remote-path "dummy-pkg/R/test.R")
(let ((ess-proj-file (expand-file-name "../.lintr"))
(cur-dir-file (expand-file-name ".lintr")))
;; no .lintr file
(should (null (ess-r--find-lintr-file)))
;; .lintr file in the package directory
(write-region "" nil ess-proj-file)
(let ((actual (ess-r--find-lintr-file)))
(should (string-match-p "^/mock:.*/dummy-pkg/\\.lintr$" actual)))
;; .lintr file in the current directory takes precedence over any other
;; locations
(write-region "" nil cur-dir-file)
(let ((actual (ess-r--find-lintr-file)))
(should (string-match-p "^/mock:.*/dummy-pkg/R/\\.lintr$" actual)))
;; clean up created files
(delete-file ess-proj-file)
(delete-file cur-dir-file))))

(provide 'ess-test-r-package)

;;; ess-test-r-package.el ends here
20 changes: 20 additions & 0 deletions test/ess-test-r-utils.el
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
(require 'ert)
(require 'etest)
(require 'ess-r-mode)
(require 'tramp)

(defvar ess-test-fixtures-directory
(expand-file-name "fixtures"
Expand Down Expand Up @@ -304,6 +305,25 @@ representative to the common interactive use with tracebug on."
(eval . (ess-test-r-set-local-process)))
,@body)))

;; Define a mock TRAMP method to use for testing. This code is taken from
;; `tramp-tests.el'.
(add-to-list
'tramp-methods
'("mock"
(tramp-login-program "sh")
(tramp-login-args (("-i")))
(tramp-direct-async-args (("-c")))
(tramp-remote-shell "/bin/sh")
(tramp-remote-shell-args ("-c"))
(tramp-connection-timeout 10)))

(defun ess-test-create-remote-path (path)
"Construct a remote path using the 'mock' TRAMP method.
Take a string PATH representing a local path, and construct a
remote path that uses the 'mock' TRAMP method."
(let ((full-path (abbreviate-file-name (expand-file-name path))))
(concat "/mock::" full-path)))

(provide 'ess-test-r-utils)

;;; ess-test-r-utils.el ends here