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

Empty directories remain after jpm uninstall #83

Open
sogaiu opened this issue Aug 21, 2023 · 3 comments
Open

Empty directories remain after jpm uninstall #83

sogaiu opened this issue Aug 21, 2023 · 3 comments

Comments

@sogaiu
Copy link

sogaiu commented Aug 21, 2023

For the following two repositories / projects, performing jpm uninstall here after an installation, leaves behind empty directories in the package cache:

Sample session:

$ git clone https://github.com/ianthehenry/jimmy && cd jimmy
Cloning into 'jimmy'...
remote: Enumerating objects: 125, done.
remote: Counting objects: 100% (125/125), done.
remote: Compressing objects: 100% (76/76), done.
remote: Total 125 (delta 63), reused 103 (delta 41), pack-reused 0
Receiving objects: 100% (125/125), 32.63 KiB | 32.63 MiB/s, done.
Resolving deltas: 100% (63/63), done.

$ jpm install
generating /home/user/.local/lib/janet/.manifests/jimmy.jdn...
Installed as 'jimmy'.
copying build/jimmy/native.so to /home/user/.local/lib/janet/jimmy...
copying build/jimmy/native.meta.janet to /home/user/.local/lib/janet/jimmy...
copying build/jimmy/native.a to /home/user/.local/lib/janet/jimmy...
copying src/set.janet to /home/user/.local/lib/janet/jimmy...
copying src/map.janet to /home/user/.local/lib/janet/jimmy...
copying src/vec.janet to /home/user/.local/lib/janet/jimmy...
copying src/util.janet to /home/user/.local/lib/janet/jimmy...
copying src/init.janet to /home/user/.local/lib/janet/jimmy...

$ ls -a ~/.local/lib/janet/jimmy/
.   init.janet  native.a           native.so  util.janet
..  map.janet   native.meta.janet  set.janet  vec.janet

$ jpm uninstall
removing /home/user/.local/lib/janet/jimmy/native.so
removing /home/user/.local/lib/janet/jimmy/native.meta.janet
removing /home/user/.local/lib/janet/jimmy/native.a
removing /home/user/.local/lib/janet/jimmy/set.janet
removing /home/user/.local/lib/janet/jimmy/map.janet
removing /home/user/.local/lib/janet/jimmy/vec.janet
removing /home/user/.local/lib/janet/jimmy/util.janet
removing /home/user/.local/lib/janet/jimmy/init.janet
removing manifest /home/user/.local/lib/janet/.manifests/jimmy.jdn
Uninstalled.

$ ls -a ~/.local/lib/janet/jimmy/
.  ..

Perhaps it has something to do with the use of :prefix in declare-source?

Lines from project.janet from jimmy:

(declare-source
  :source [
    "src/set.janet"
    "src/map.janet"
    "src/vec.janet"
    "src/util.janet"
    "src/init.janet"
  ]
  :prefix "jimmy")

Lines from project.janet from stx:

(declare-source
 :source ["src/init.janet"]
 :prefix "stx")

Janet: 1.30.0-2ac36a05
JPM: 65e218e
OS: Ubuntu Linux 22.0.x

@sogaiu
Copy link
Author

sogaiu commented Aug 6, 2024

At least in stx's case, there does not appear to be any mention of the stx directory itself in the manifest:

{:tag "eb6bedd643ad47caa9d3c0630c1679ca49484fdc"
 :paths @["/home/user/.local/lib/janet/stx/native.so"
          "/home/user/.local/lib/janet/stx/native.meta.janet"
          "/home/user/.local/lib/janet/stx/native.a"
          "/home/user/.local/lib/janet/stx/init.janet"]
  :type :git
  :url "https://github.com/ml-2/stx"
  :version "0.0.0" 
  :dependencies @[]}

Currently, it seems that uninstall leads to this code (slightly edited):

(defn uninstall
  "Uninstall bundle named name"
  [name]
  (def manifest (find-manifest name))
  (when-with [f (file/open manifest)]
    (def man (parse (:read f :all)))
    (each path (get man :paths [])
      (def path1 (string (dyn :dest-dir "") path))
      (print "removing " path1)
      (rm path1))
    (print "removing manifest " manifest)
    (:close f) # <censored (^^;>
    (rm manifest)
    (print "Uninstalled.")))

So, IIUC, things that are not explicitly mentioned in the manifest are not removed [1].

Does that seem right?


[1] Thanks to pyrmont for the pointer.

@pyrmont
Copy link
Contributor

pyrmont commented Aug 6, 2024

In my opinion there are three ways to deal with this problem.

  1. Keep the status quo. Leave things as they are and only delete files that are in the manifest.

  2. Record directory creation. If the manifest recorded the directories it created, it could also remove them.

  3. Auto-delete empty directories. After deleting each path, check if the parent is empty and if it is, delete it, too.

My suggestion would be to adopt Option 3. Option 2 could lead to JPM deleting user data that is saved into a directory. Option 3 will only delete directories that are empty.

@sogaiu
Copy link
Author

sogaiu commented Aug 6, 2024

I think a slight variation on option 2 could be doable too, i.e. only remove recorded directories if they become empty...error otherwise.

Or, check whether there is anything in the relevant directories other than what's recorded in the manifest before removing anything? This way one doesn't end up with a partial installation perhaps.

I'm not coming up with a scenario of there being post-installation-user-created data under syspath, but that might just be my limited imagination (^^;

Not necessarily saying that I think an option 2-ish thing is better, just observing here.

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