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

Copy directory recursively #27

Open
noloop opened this issue Feb 10, 2019 · 6 comments
Open

Copy directory recursively #27

noloop opened this issue Feb 10, 2019 · 6 comments

Comments

@noloop
Copy link

noloop commented Feb 10, 2019

I implemented a function using some of the functions of cl-fad, the function is called copy-directory-recursive, as the name says, it recursively copies a directory, I missed a function like that in cl-fad, it's here:

(defun copy-directory-recursive (origin destination &key (overwrite nil))
  (let ((list-dir (cl-fad:list-directory origin)))
    (ensure-directories-exist destination)
    (dolist (path list-dir)
      (cond ((cl-fad:directory-exists-p path)
             (progn (ensure-directories-exist (merge-directory-with-subtract-path path origin destination))
                    (copy-directory-recursive path
                                              (merge-directory-with-subtract-path path origin destination)
                                              :overwrite t)))
             ((pathname-is-file path)
              (cl-fad:copy-file path (merge-file-with-subtract-path path origin destination)
                                :overwrite overwrite))))))

(defun merge-directory-with-subtract-path (path origin destination)
  (cl-fad:merge-pathnames-as-directory destination (pathname-subtract origin path)))

(defun merge-file-with-subtract-path (path origin destination)
  (cl-fad:merge-pathnames-as-file
   (cl-fad:merge-pathnames-as-file destination (pathname-subtract origin path))
   (concatenate 'string (pathname-name path) (if (pathname-type path) ".") (pathname-type path))))

(defun pathname-subtract (path-1 path-2)
  "Compare path-1 with path-2, and return new pathname with rest of path-2 at the point where it differentiated."
  (let* ((list-path-1 (pathname-directory path-1))
         (list-path-2 (pathname-directory path-2))
         (new-list (list-subtract list-path-1 list-path-2))
         (new-path "/"))
    (dolist (el new-list)
      (setf new-path (cl-fad:merge-pathnames-as-directory new-path
                                            (concatenate 'string el "/"))))
    (pathname (subseq (namestring new-path) 1))))

(defun list-subtract (list-1 list-2)
  "Compare elements of list-1 with elements of list-2, return new list with elements of list-2 not contained in list-1. Return immediately for elements differents, the comparison follow order of elements."
;;; Example:
;;; (list-subtract '("home" "you" "lisp")' ("home" "new" "you" "lisp" "child-dir" "you"))
  (do ((c 0 (incf c))
       (i list-1 (cdr i))
       (j list-2 (cdr j))
       (new-list list-2
                 (if (string= (car i)
                              (car j))
                     (progn (pop new-list)
                            new-list)
                     (return new-list))))
      ((>= c (length list-1)) new-list)))

I also have the test for her. But I will not extend too much here. If you want to add it, tell me how to proceed to integrate it into cl-fad, which I will refactor it and do whatever has to be done.

@stassats
Copy link
Member

how does it deal with symlinks?

@noloop
Copy link
Author

noloop commented Feb 10, 2019

I did not care about symbolic links, but it would be a good, how should I deal with them? copy or not the symbolic link content?

@stassats
Copy link
Member

I'm not following why it needs a new package. The non-surprising default behavior is to copy the link, not the file.

@noloop
Copy link
Author

noloop commented Feb 10, 2019

I tested here, the current behavior is to receive an error when there are symbolic links, since it is searching for the actual file, and getting in the way of creating pathname. I do not know very well how to do just to copy the symbolic link, if you have any idea, it would be a help to advance, but I will search here anyway.

@stassats
Copy link
Member

There's no portable interface for handling symlinks.

@noloop
Copy link
Author

noloop commented Feb 10, 2019

Okay, so I'll just :follow-symlinks nil in list-directory.

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

No branches or pull requests

2 participants