all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Eli Zaretskii <eliz@gnu.org>
To: Harm Van der Vegt <harmvegt@gmail.com>
Cc: 72919@debbugs.gnu.org
Subject: bug#72919: 29.1; chart-space-usage in chart.el does not work correctly on windows
Date: Sun, 01 Sep 2024 11:13:40 +0300	[thread overview]
Message-ID: <86seujaj0r.fsf@gnu.org> (raw)
In-Reply-To: <CAPdXVSy_HfiuWHNPM-wCFx4yz8sTPZeh2LN1gLyz95PCKZirWQ@mail.gmail.com> (message from Harm Van der Vegt on Sat, 31 Aug 2024 20:52:41 +0200)

> From: Harm Van der Vegt <harmvegt@gmail.com>
> Date: Sat, 31 Aug 2024 20:52:41 +0200
> 
> Load the builtin chart package. When chart-space-usage is run, targeting
> any directory, chart fails to find any files and therefore can't create
> the chart. The expected behavior is that a bar chart is shown, ranking
> the files of the directory by size.
> 
> This only fails on my Windows machine, it works on my Ubuntu
> installation.
> 
> The output as shown in *Messages* is as follows:
> 
> Collecting statistics...
> Running ‘cd g:/Shakespeare/;du -sk *’...
> Scanning output ...
> chart-space-usage: No files found!

Yes, the current implementation is not portable.

> chart-space-usage makes use of the du (disk usage) utility, which might
> not be present on all machines. In my case I have du installed, but
> chart-space-usage still failed to find any files.
> 
> I have patched chart-space-usage to remove the dependency on du and make
> it OS agnostic and attached the patch to this email.

Thanks.  However, I think your changes are not entirely correct: they
fail to account for space usage of files inside subdirectories of the
directory which the user types at the prompt, whereas the
implementation with "du" does account for that.  In addition, I think
if someone has 'du' on Windows, it should be used.

So I came up with the following changes instead.  Could you please try
them, both with and without du.exe on PATH?  If these changes give
good results, I will install them.

diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el
index da61e45..03dbe33 100644
--- a/lisp/emacs-lisp/chart.el
+++ b/lisp/emacs-lisp/chart.el
@@ -641,27 +641,63 @@ chart-file-count
 		       (lambda (a b) (> (cdr a) (cdr b))))
     ))
 
+;; This assumes 4KB blocks
+(defun chart--file-size (size)
+  (* (/ (+ size 4095) 4096) 4096))
+
+(defun chart--directory-size (dir)
+  "Compute total size of files in directory DIR and its subdirectories.
+DIR is assumed to be a directory, verified by the caller."
+  (let ((size 0))
+    (dolist (file (directory-files-recursively dir "." t))
+      (let ((fsize (nth 7 (file-attributes file))))
+        (if (> fsize 0)
+            (setq size
+                  (+ size (chart--file-size fsize))))))
+    size))
+
 (defun chart-space-usage (d)
   "Display a top usage chart for directory D."
   (interactive "DDirectory: ")
   (message "Collecting statistics...")
   (let ((nmlst nil)
 	(cntlst nil)
-	(b (get-buffer-create " *du-tmp*")))
-    (set-buffer b)
-    (erase-buffer)
-    (insert "cd " d ";du -sk * \n")
-    (message "Running `cd %s;du -sk *'..." d)
-    (call-process-region (point-min) (point-max) shell-file-name t
-			 (current-buffer) nil)
-    (goto-char (point-min))
-    (message "Scanning output ...")
-    (while (re-search-forward "^\\([0-9]+\\)[ \t]+\\([^ \n]+\\)$" nil t)
-      (let* ((nam (buffer-substring (match-beginning 2) (match-end 2)))
-	     (num (buffer-substring (match-beginning 1) (match-end 1))))
-	(setq nmlst (cons nam nmlst)
-	      ;; * 1000 to put it into bytes
-	      cntlst (cons (* (string-to-number num) 1000) cntlst))))
+        b)
+    (if (executable-find "du")
+        (progn
+	  (setq b (get-buffer-create " *du-tmp*"))
+          (set-buffer b)
+          (erase-buffer)
+          (if (and (memq system-type '(windows-nt ms-dos))
+                   (fboundp 'w32-shell-dos-semantics)
+                   (w32-shell-dos-semantics))
+              (progn
+                ;; With Windows shells, 'cd' does not change the drive,
+                ;; and ';' is not reliable for running multiple
+                ;; commands, so use alternatives.  We quote the
+                ;; directory because otherwise pushd will barf on a
+                ;; directory with forward slashes.
+                (insert "pushd \"" d "\" && du -sk * \n")
+                (message "Running `pushd \"%s\" && du -sk *'..." d))
+            (insert "cd " d ";du -sk * \n")
+            (message "Running `cd %s;du -sk *'..." d))
+          (call-process-region (point-min) (point-max) shell-file-name t
+			       (current-buffer) nil)
+          (goto-char (point-min))
+          (message "Scanning output ...")
+          (while (re-search-forward "^\\([0-9]+\\)[ \t]+\\([^ \n]+\\)$" nil t)
+            (let* ((nam (buffer-substring (match-beginning 2) (match-end 2)))
+	           (num (buffer-substring (match-beginning 1) (match-end 1))))
+	      (setq nmlst (cons nam nmlst)
+	            ;; * 1000 to put it into bytes
+	            cntlst (cons (* (string-to-number num) 1000) cntlst)))))
+      (dolist (file (directory-files d t directory-files-no-dot-files-regexp))
+        (setq nmlst (cons (file-name-nondirectory file) nmlst))
+        (if (file-regular-p file)
+            (setq cntlst (cons (chart--file-size
+                                (nth 7 (file-attributes file)))
+                               cntlst))
+          (setq cntlst (cons (chart--directory-size file) cntlst)))))
     (if (not nmlst)
 	(error "No files found!"))
     (chart-bar-quickie 'vertical (format "Largest files in %s" d)





  reply	other threads:[~2024-09-01  8:13 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-31 18:52 bug#72919: 29.1; chart-space-usage in chart.el does not work correctly on windows Harm Van der Vegt
2024-09-01  8:13 ` Eli Zaretskii [this message]
     [not found]   ` <CAPdXVSxuhccEEYSLH+WR57irNYn4OrWWhmPPcCY5GjPa-RTnHQ@mail.gmail.com>
2024-09-01 18:16     ` bug#72919: Fwd: " Harm Van der Vegt
2024-09-01 18:35     ` Eli Zaretskii
2024-09-01 19:06       ` Harm Van der Vegt
2024-09-07  9:24       ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86seujaj0r.fsf@gnu.org \
    --to=eliz@gnu.org \
    --cc=72919@debbugs.gnu.org \
    --cc=harmvegt@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.