As I dedicate myself to Eshell more, especially on this Macbook which violates all my muscle memory in Terminal.app, a few tweaks are needed to be able to find all my commands:

(defun mak::flatten-list (l)
  (apply #'append l))

(defun mak::locally-installed-programs ()
  (mak::flatten-list
   (mapcar
    (lambda (d) (list (concat d "/bin")
                      (concat d "/sbin")))
    (directory-files "~/local" t directory-files-no-dot-files-regexp))))

(defun mak::generate-path-env-var ()
  (interactive)
  ;; The order of this list is critical:
  ;; 1) Scripts I wrote myself
  ;; 2) Programs installed privately (source)
  ;; 3) Programs installed privately (golang)
  ;; 4) Programs installed system-wide
  ;; 5) Stock OS commands
  (mapcar #'expand-file-name
         (mak::flatten-list
          `(("~/bin")
            ,(mak::locally-installed-programs)
            ("~/go/bin")
            ("/usr/local/bin" "/usr/local/sbin")
            ("/usr/bin" "/usr/sbin" "/bin" "/sbin")))))

Let's use IELM to test those functions, since we've not used it before and it's neat to see.

ELISP> (mak::flatten-list '((a) (b c) (d e f) (g (h) i)))
(a b c d e f g
   (h)
   i)

ELISP> (mak::locally-installed-programs)
("/Users/mak/local/emacs/bin" "/Users/mak/local/emacs/sbin")

ELISP> (mak::generate-path-env-var)
("/Users/mak/bin" "/Users/mak/local/emacs/bin" "/Users/mak/local/emacs/sbin" ...)

You'll notice that flatten only goes one level deep. I'm okay with that for now, but I anticipate Future Me hating Present Me for this.

(defun mak::set-path-env-var ()
  (interactive)
  (setenv "PATH"
          (string-join (mak::generate-path-env-var) ":")))

(add-hook 'eshell-mode-hook 'mak::set-path-env-var)

And there we have it! Eshell will now generate and set the appropriate $PATH variable when it starts.