From: Andreas Gerler Date: Sun, 26 Apr 2026 17:45:45 +0000 (+0200) Subject: update docker X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=5df72af92d27a565541b9950abe56499e61ac83b;p=emacsconfig.git update docker --- diff --git a/elpa/docker-20251028.1026/docker-autoloads.el b/elpa/docker-20251028.1026/docker-autoloads.el deleted file mode 100644 index 1375b084..00000000 --- a/elpa/docker-20251028.1026/docker-autoloads.el +++ /dev/null @@ -1,86 +0,0 @@ -;;; docker-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*- -;; Generated by the `loaddefs-generate' function. - -;; This file is part of GNU Emacs. - -;;; Code: - -(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path))) - - - -;;; Generated autoloads from docker-compose.el - - (autoload 'docker-compose "docker-compose" nil t) -(register-definition-prefixes "docker-compose" '("docker-compose-")) - - -;;; Generated autoloads from docker-container.el - - (autoload 'docker-container-eshell "docker-container" nil t) - (autoload 'docker-container-find-directory "docker-container" nil t) - (autoload 'docker-container-find-file "docker-container" nil t) - (autoload 'docker-container-shell "docker-container" nil t) - (autoload 'docker-container-shell-env "docker-container" nil t) - (autoload 'docker-container-vterm "docker-container" nil t) - (autoload 'docker-container-vterm-env "docker-container" nil t) - (autoload 'docker-container-eat "docker-container" nil t) - (autoload 'docker-container-eat-env "docker-container" nil t) - (autoload 'docker-containers "docker-container" nil t) -(register-definition-prefixes "docker-container" '("docker-container-")) - - -;;; Generated autoloads from docker-context.el - - (autoload 'docker-contexts "docker-context" nil t) -(register-definition-prefixes "docker-context" '("docker-context-")) - - -;;; Generated autoloads from docker-core.el - - (autoload 'docker "docker" nil t) -(register-definition-prefixes "docker-core" '("docker-")) - - -;;; Generated autoloads from docker-image.el - - (autoload 'docker-image-pull-one "docker-image" nil t) - (autoload 'docker-images "docker-image" nil t) -(register-definition-prefixes "docker-image" '("docker-")) - - -;;; Generated autoloads from docker-network.el - - (autoload 'docker-networks "docker-network" nil t) -(register-definition-prefixes "docker-network" '("docker-network-")) - - -;;; Generated autoloads from docker-process.el - -(register-definition-prefixes "docker-process" '("docker-")) - - -;;; Generated autoloads from docker-utils.el - -(register-definition-prefixes "docker-utils" '("docker-")) - - -;;; Generated autoloads from docker-volume.el - - (autoload 'docker-volume-dired "docker-volume" nil t) - (autoload 'docker-volumes "docker-volume" nil t) -(register-definition-prefixes "docker-volume" '("docker-volume-")) - -;;; End of scraped data - -(provide 'docker-autoloads) - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; no-native-compile: t -;; coding: utf-8-emacs-unix -;; End: - -;;; docker-autoloads.el ends here diff --git a/elpa/docker-20251028.1026/docker-compose.el b/elpa/docker-20251028.1026/docker-compose.el deleted file mode 100644 index 924c6779..00000000 --- a/elpa/docker-20251028.1026/docker-compose.el +++ /dev/null @@ -1,339 +0,0 @@ -;;; docker-compose.el --- Interface to docker-compose -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) -(require 'transient) - -(require 'docker-group) -(require 'docker-utils) -(require 'docker-process) - -(defgroup docker-compose nil - "Docker compose customization group." - :group 'docker) - -(defcustom docker-compose-command "docker compose" - "The `docker-compose' binary." - :group 'docker-compose - :type 'string) - -(defun docker-compose-run-docker-compose-async (action &rest args) - "Execute \"`docker-compose-command' ACTION ARGS\" and return a promise with the results." - (apply #'docker-run-async docker-compose-command (docker-compose-arguments) action args)) - -(defun docker-compose-run-docker-compose-async-with-buffer (action &rest args) - "Execute \"`docker-compose-command' ACTION ARGS\" and display output in a new buffer." - (apply #'docker-run-async-with-buffer docker-compose-command (docker-compose-arguments) action args)) - -(aio-defun docker-compose-services () - "Return the list of services." - (s-split "\n" (aio-await (docker-compose-run-docker-compose-async "config" "--services" "2>/dev/null")) t)) - -(aio-defun docker-compose-read-services-names () - "Read the services names." - (completing-read-multiple "Services: " (aio-await (docker-compose-services)))) - -(aio-defun docker-compose-read-service-name () - "Read one service name." - (completing-read "Service: " (aio-await (docker-compose-services)))) - -(defun docker-compose-read-project (prompt &rest _args) - "Read the `docker-compose' project forwarding PROMPT." - (completing-read - prompt - ;; in docker compose v2, we can obtain the list of - ;; projects with 'ls' argument - (if (string-match-p "*?docker compose*?" docker-compose-command) - (split-string - (shell-command-to-string - (concat docker-compose-command " ls" " --all" " -q")) - "\n" - t)))) - -(defun docker-compose-read-log-level (prompt &rest _args) - "Read the `docker-compose' log level forwarding PROMPT." - (completing-read prompt '(DEBUG INFO WARNING ERROR CRITICAL))) - -(defun docker-compose-read-directory (prompt &optional initial-input _history) - "Wrapper around `read-directory-name' forwarding PROMPT and INITIAL-INPUT." - (read-directory-name prompt nil nil t initial-input)) - -(defun docker-compose-read-environment-file (prompt &optional initial-input _history) - "Wrapper around `read-file-name' forwarding PROMPT and INITIAL-INPUT." - (read-file-name prompt nil nil t initial-input)) - -(defun docker-compose-read-compose-file (prompt &optional initial-input _history) - "Wrapper around `read-file-name' forwarding PROMPT and INITIAL-INPUT." - (read-file-name prompt nil nil t initial-input (apply-partially 'string-match ".*\\.yml\\|.*\\.yaml"))) - -(aio-defun docker-compose-run-action-for-one-service (action args services) - "Run \"docker-compose ACTION ARGS SERVICES\"." - (interactive (list - (-last-item (s-split "-" (symbol-name transient-current-command))) - (transient-args transient-current-command) - nil)) - (setq services (aio-await (docker-compose-read-services-names))) - (docker-compose-run-docker-compose-async-with-buffer action args services)) - -(defun docker-compose-run-action-for-all-services (action args) - "Run \"docker-compose ACTION ARGS\"." - (interactive (list - (-last-item (s-split "-" (symbol-name transient-current-command))) - (transient-args transient-current-command))) - (docker-compose-run-docker-compose-async-with-buffer action args)) - -(aio-defun docker-compose-run-action-with-command (action args service command) - "Run \"docker-compose ACTION ARGS SERVICE COMMAND\"." - (interactive (list - (-last-item (s-split "-" (symbol-name transient-current-command))) - (transient-args transient-current-command) - nil - (read-string "Command: "))) - (setq service (aio-await (docker-compose-read-service-name))) - (docker-compose-run-docker-compose-async-with-buffer action args service command)) - -(transient-define-prefix docker-compose-build () - "Transient for \"docker-compose build\"." - :man-page "docker-compose build" - ["Arguments" - ("b" "Build argument" "--build-arg " read-string) - ("c" "Compress build context" "--compress") - ("f" "Always remove intermediate containers" "--force-rm") - ("m" "Memory limit" "--memory " transient-read-number-N0) - ("n" "Do not use cache" "--no-cache") - ("p" "Attempt to pull a newer version of the image" "--pull") - ("r" "Build images in parallel" "--parallel")] - ["Actions" - ("B" "Build" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-config () - "Transient for \"docker-compose config\"." - :man-page "docker-compose config" - ["Arguments" - - ("r" "Pin image tags to digests" "--resolve-image-digests") - ("s" "Print the service names" "--services") - ("v" "Print the volume names" "--volumes")] - ["Actions" - ("V" "Config" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-create () - "Transient for \"docker-compose create\"." - :man-page "docker-compose create" - ["Arguments" - ("b" "Build" "--build") - ("f" "Force recreate" "--force-recreate") - ("n" "No recreate" "--no-recreate")] - ["Actions" - ("C" "Create" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-down () - "Transient for \"docker-compose down\"." - :man-page "docker-compose down" - ["Arguments" - ("o" "Remove orphans" "--remove-orphans") - ("t" "Timeout" "--timeout " transient-read-number-N0) - ("v" "Remove volumes" "--volumes")] - ["Actions" - ("W" "Down" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-exec () - "Transient for \"docker-compose exec\"." - :man-page "docker-compose exec" - ["Arguments" - ("P" "Privileged" "--privileged") - ("T" "Disable pseudo-tty" "-T") - ("d" "Detach" "-d") - ("e" "Env KEY=VAL" "-e " read-string) - ("u" "User " "--user " read-string) - ("w" "Workdir" "--workdir " read-string)] - ["Actions" - ("E" "Exec" docker-compose-run-action-with-command)]) - -(transient-define-prefix docker-compose-logs () - "Transient for \"docker-compose logs\"." - :man-page "docker-compose logs" - ["Arguments" - ("T" "Tail" "--tail " read-string) - ("f" "Follow" "--follow") - ("n" "No color" "--no-color") - ("t" "Timestamps" "--timestamps")] - ["Actions" - ("L" "Logs" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-pull () - "Transient for \"docker-compose pull\"." - :man-page "docker-compose pull" - ["Arguments" - ("d" "Include dependencies" "--include-deps") - ("i" "Ignore pull failures" "--ignore-pull-failures") - ("n" "No parallel" "--no-parallel")] - ["Actions" - ("F" "Pull" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-push () - "Transient for \"docker-compose push\"." - :man-page "docker-compose push" - ["Arguments" - ("i" "Ignore push failures" "--ignore-push-failures")] - ["Actions" - ("P" "Push" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-restart () - "Transient for \"docker-compose restart\"." - :man-page "docker-compose restart" - ["Arguments" - ("t" "Timeout" "--timeout " transient-read-number-N0)] - ["Actions" - ("T" "Restart" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-rm () - "Transient for \"docker-compose rm\"." - :man-page "docker-compose rm" - ["Arguments" - ("f" "Force" "--force") - ("s" "Stop" "--stop") - ("v" "Remove anonymous volumes" "-v")] - ["Actions" - ("D" "Remove" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-run () - "Transient for \"docker-compose run\"." - :man-page "docker-compose run" - :value '("--rm") - ["Arguments" - ("E" "Entrypoint" "--entrypoint " read-string) - ("N" "Name" "--name " read-string) - ("T" "Disable pseudo-tty" "-T") - ("d" "Detach" "-d") - ("e" "Env KEY=VAL" "-e " read-string) - ("l" "Label" "--label " read-string) - ("n" "No deps" "--no-deps") - ("r" "Remove container when it exits" "--rm") - ("s" "Enable services ports" "--service-ports") - ("u" "User " "--user " read-string) - ("w" "Workdir" "--workdir " read-string)] - ["Actions" - ("R" "Run" docker-compose-run-action-with-command)]) - -(transient-define-prefix docker-compose-start () - "Transient for \"docker-compose start\"." - :man-page "docker-compose start" - ["Actions" - ("S" "Start" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-stop () - "Transient for \"docker-compose stop\"." - :man-page "docker-compose stop" - ["Arguments" - ("t" "Timeout" "--timeout " transient-read-number-N0)] - ["Actions" - ("O" "Stop" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-up () - "Transient for \"docker-compose up\"." - :man-page "docker-compose up" - ["Arguments" - ("b" "Build" "--build") - ("c" "Scale" "--scale " transient-read-number-N0) - ("d" "Detach" "-d") - ("f" "Force recreate" "--force-recreate") - ("n" "No deps" "--no-deps") - ("q" "Quiet pull" "--quiet-pull") - ("r" "Remove orphans" "--remove-orphans") - ("t" "Timeout" "--timeout " transient-read-number-N0)] - ["Actions" - ("U" "Up" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-pause () - "Transient for \"docker-compose pause\"." - :man-page "docker-compose pause" - ["Actions" - ("Z" "Pause" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(transient-define-prefix docker-compose-unpause () - "Transient for \"docker-compose unpause\"." - :man-page "docker-compose unpause" - ["Actions" - ("N" "Unpause" docker-compose-run-action-for-one-service) - ("A" "All services" docker-compose-run-action-for-all-services)]) - -(docker-utils-define-transient-arguments docker-compose) - -;;;###autoload (autoload 'docker-compose "docker-compose" nil t) -(transient-define-prefix docker-compose () - "Transient for docker-compose." - :man-page "docker-compose" - ["Arguments" - ("a" "No ANSI" "--no-ansi") - ("c" "Compatibility" "--compatibility") - ("d" "Project directory" "--project-directory " docker-compose-read-directory) - ("e" "Environment file" "--env-file " docker-compose-read-environment-file) - ("f" "Compose file" "--file " docker-compose-read-compose-file) - ("h" "Host" "--host " read-string) - ("l" "Log level" "--log-level " docker-compose-read-log-level) - ("p" "Project name" "--project-name " docker-compose-read-project) - ("r" "Profile" "--profile " read-string) - ("v" "Verbose" "--verbose")] - [["Images" - ("B" "Build" docker-compose-build) - ("F" "Pull" docker-compose-pull) - ("P" "Push" docker-compose-push)] - ["Containers" - ("C" "Create" docker-compose-create) - ("D" "Remove" docker-compose-rm) - ("Z" "Pause" docker-compose-pause) - ("N" "Unpause" docker-compose-unpause) - ("U" "Up" docker-compose-up) - ("W" "Down" docker-compose-down)] - ["State" - ("O" "Stop" docker-compose-stop) - ("S" "Start" docker-compose-start) - ("T" "Restart" docker-compose-restart)] - ["Other" - ("E" "Exec" docker-compose-exec) - ("L" "Logs" docker-compose-logs) - ("R" "Run" docker-compose-run) - ("V" "Config" docker-compose-config)]]) - -(provide 'docker-compose) - -;;; docker-compose.el ends here diff --git a/elpa/docker-20251028.1026/docker-container.el b/elpa/docker-20251028.1026/docker-container.el deleted file mode 100644 index 48423c1b..00000000 --- a/elpa/docker-20251028.1026/docker-container.el +++ /dev/null @@ -1,603 +0,0 @@ -;;; docker-container.el --- Interface to docker-container -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher -;; Yuki Inoue - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) -(require 'json) -(require 'tablist) -(require 'transient) - -(require 'docker-core) -(require 'docker-faces) -(require 'docker-utils) - -(defgroup docker-container nil - "Docker container customization group." - :group 'docker) - -(defconst docker-container-id-template - "{{ json .Names }}" - "This Go template extracts the container id which will be passed to transient commands.") - -(defcustom docker-container-shell-file-name "/bin/sh" - "Shell to use when entering containers." - :group 'docker-container - :type 'string) - -(defcustom docker-container-tramp-method "docker" - "TRAMP method to use for connecting to Docker containers." - :group 'docker-container - :type 'string) - -(defcustom docker-container-default-sort-key '("Image" . nil) - "Sort key for docker containers. - -This should be a cons cell (NAME . FLIP) where -NAME is a string matching one of the column names -and FLIP is a boolean to specify the sort order." - :group 'docker-container - :type '(cons (string :tag "Column Name" - :validate (lambda (widget) - (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-container-columns) - (widget-put widget :error "Default Sort Key must match a column name") - widget))) - (choice (const :tag "Ascending" nil) - (const :tag "Descending" t)))) - -(defcustom docker-container-columns - '((:name "Id" :width 16 :template "{{ json .ID }}" :sort nil :format nil) - (:name "Image" :width 15 :template "{{ json .Image }}" :sort nil :format nil) - (:name "Command" :width 30 :template "{{ json .Command }}" :sort nil :format nil) - (:name "Created" :width 23 :template "{{ json .CreatedAt }}" :sort nil :format (lambda (x) (format-time-string "%F %T" (date-to-time x)))) - (:name "Status" :width 20 :template "{{ json .Status }}" :sort nil :format nil) - (:name "Ports" :width 10 :template "{{ json .Ports }}" :sort nil :format nil) - (:name "Names" :width 10 :template "{{ json .Names }}" :sort nil :format nil)) - "Column specification for docker containers. - -The order of entries defines the displayed column order. 'Template' is -the Go template passed to `docker-container-ls' to create the column data. -It should return a string delimited with double quotes. 'Sort function' is -a binary predicate that should return true when the first argument should be -sorted before the second. 'Format function' is a function from string to -string that transforms the displayed values in the column." - :group 'docker-container - :set 'docker-utils-columns-setter - :get 'docker-utils-columns-getter - :type '(repeat (list :tag "Column" - (string :tag "Name") - (integer :tag "Width") - (string :tag "Template") - (sexp :tag "Sort function") - (sexp :tag "Format function")))) - -(defalias 'docker-container-inspect 'docker-inspect) - -(defun docker-container--read-shell (&optional read-shell-name) - "Return `docker-container-shell-file-name' or read a shell name if READ-SHELL-NAME is truthy." - (if read-shell-name (read-shell-command "Shell: ") docker-container-shell-file-name)) - -(defun docker-container-status-face (status) - "Return the correct face according to STATUS." - (cond - ((s-starts-with? "Up" status) - 'docker-face-status-up) - ((s-starts-with? "Exited" status) - 'docker-face-status-down) - (t - 'docker-face-status-other))) - -(aio-defun docker-container-entries (&rest args) - "Return the docker containers data for `tabulated-list-entries'." - (let* ((fmt (docker-utils-make-format-string docker-container-id-template docker-container-columns)) - (data (aio-await (docker-run-docker-async "container" "ls" args (format "--format=\"%s\"" fmt)))) - (lines (s-split "\n" data t))) - (-map (-partial #'docker-utils-parse docker-container-columns) lines))) - -(aio-defun docker-container-entries-propertized (&rest args) - "Return the propertized docker containers data for `tabulated-list-entries'." - (let ((entries (aio-await (docker-container-entries args)))) - (-map #'docker-container-propertize-entry entries))) - -(defun docker-container-propertize-entry (entry) - "Propertize ENTRY." - (let* ((index (--find-index (string-equal "Status" (plist-get it :name)) docker-container-columns)) - (data (cadr entry)) - (status (aref data index))) - (aset data index (propertize status 'font-lock-face (docker-container-status-face status))) - entry)) - -(aio-defun docker-container-update-status-async () - "Write the status to `docker-status-strings'." - (plist-put docker-status-strings :containers "Containers") - (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) - (let* ((entries (aio-await (docker-container-entries-propertized (docker-container-ls-arguments)))) - (index (--find-index (string-equal "Status" (plist-get it :name)) docker-container-columns)) - (statuses (--map (aref (cadr it) index) entries)) - (faces (--map (get-text-property 0 'font-lock-face it) statuses)) - (all (length faces)) - (up (-count (-partial #'equal 'docker-face-status-up) faces)) - (down (-count (-partial #'equal 'docker-face-status-down) faces)) - (other (- all up down))) - (plist-put docker-status-strings - :containers - (format "Containers (%s total, %s up, %s down, %s other)" - all - (propertize (number-to-string up) 'face 'docker-face-status-up) - (propertize (number-to-string down) 'face 'docker-face-status-down) - (propertize (number-to-string other) 'face 'docker-face-status-other))) - (transient--redisplay)))) - -(add-hook 'docker-open-hook #'docker-container-update-status-async) - -(aio-defun docker-container-refresh () - "Refresh the containers list." - (docker-utils-refresh-entries - (docker-container-entries-propertized (docker-container-ls-arguments)))) - -(defun docker-container-read-name () - "Read an container name." - (completing-read "Container: " (-map #'car (aio-wait-for (docker-container-entries))))) - -(defvar eshell-buffer-name) - -;;;###autoload (autoload 'docker-container-eshell "docker-container" nil t) -(defun docker-container-eshell (container) - "Open `eshell' in CONTAINER." - (interactive (list (docker-container-read-name))) - (let* ((container-address (format "%s:%s:/" docker-container-tramp-method container)) - (file-prefix (let ((prefix (file-remote-p default-directory))) - (if prefix - (format "%s|" (s-chop-suffix ":" prefix)) - "/"))) - (default-directory (format "%s%s" file-prefix container-address)) - (eshell-buffer-name (docker-utils-generate-new-buffer-name "docker" "eshell:" default-directory))) - (eshell))) - -(defun docker-container-assert-tramp-docker () - "Assert tramp docker support is available." - (unless (or (docker-utils-package-p 'docker-container) - (docker-utils-package-p 'docker-tramp)) - (error "Tramp docker support was not detected, try installing docker-tramp"))) - -;;;###autoload (autoload 'docker-container-find-directory "docker-container" nil t) -(defun docker-container-find-directory (container directory) - "Inside CONTAINER open DIRECTORY." - (interactive - (let* ((container-name (docker-container-read-name)) - (tramp-filename (read-directory-name "Directory: " (format "/%s:%s:/" docker-container-tramp-method container-name)))) - (with-parsed-tramp-file-name tramp-filename nil - (list host localname)))) - (docker-container-assert-tramp-docker) - (dired (format "/%s:%s:%s" docker-container-tramp-method container directory))) - -(defalias 'docker-container-dired 'docker-container-find-directory) - -;;;###autoload (autoload 'docker-container-find-file "docker-container" nil t) -(defun docker-container-find-file (container file) - "Open FILE inside CONTAINER." - (interactive - (let* ((container-name (docker-container-read-name)) - (tramp-filename (read-file-name "File: " (format "/%s:%s:/" docker-container-tramp-method container-name)))) - (with-parsed-tramp-file-name tramp-filename nil - (list host localname)))) - (docker-container-assert-tramp-docker) - (find-file (format "/%s:%s:%s" docker-container-tramp-method container file))) - -;;;###autoload (autoload 'docker-container-shell "docker-container" nil t) -(defun docker-container-shell (container &optional read-shell) - "Open `shell' in CONTAINER. When READ-SHELL is not nil, ask the user for it." - (interactive (list - (docker-container-read-name) - current-prefix-arg)) - (let* ((shell-file-name (docker-container--read-shell read-shell)) - (container-address (format "%s:%s:/" docker-container-tramp-method container)) - (file-prefix (let ((prefix (file-remote-p default-directory))) - (if prefix - (format "%s|" (s-chop-suffix ":" prefix)) - "/"))) - (default-directory (format "%s%s" file-prefix container-address))) - (shell (docker-utils-generate-new-buffer "docker" "shell:" default-directory)))) - -;;;###autoload (autoload 'docker-container-shell-env "docker-container" nil t) -(aio-defun docker-container-shell-env (container &optional read-shell) - "Open `shell' in CONTAINER with the environment variable set -and default directory set to workdir. When READ-SHELL is not -nil, ask the user for it." - (interactive (list - (docker-container-read-name) - current-prefix-arg)) - (docker-container-assert-tramp-docker) - (let* ((shell-file-name (docker-container--read-shell read-shell)) - (container-address (format "%s:%s:" docker-container-tramp-method container)) - (file-prefix (let ((prefix (file-remote-p default-directory))) - (if prefix - (format "%s|" (s-chop-suffix ":" prefix)) - "/"))) - (container-config (cdr (assq 'Config (aref (json-read-from-string (aio-await (docker-run-docker-async "inspect" container))) 0)))) - (container-workdir (cdr (assq 'WorkingDir container-config))) - (container-env (cdr (assq 'Env container-config))) - (default-directory (format "%s%s%s" file-prefix container-address container-workdir)) - ;; process-environment doesn't work with tramp if you call this function more than one per emacs session - (tramp-remote-process-environment (append container-env nil))) - (shell (docker-utils-generate-new-buffer "docker" "shell-env:" default-directory)))) - -;;;###autoload (autoload 'docker-container-vterm "docker-container" nil t) -(defun docker-container-vterm (container) - "Open `vterm' in CONTAINER." - (interactive (list (docker-container-read-name))) - (if (fboundp 'vterm-other-window) - (let* ((container-address (format "%s:%s:/" docker-container-tramp-method container)) - (file-prefix (let ((prefix (file-remote-p default-directory))) - (if prefix - (format "%s|" (s-chop-suffix ":" prefix)) - "/"))) - (default-directory (format "%s%s" file-prefix container-address))) - (vterm-other-window (docker-utils-generate-new-buffer-name "docker" "vterm:" default-directory))) - (error "The vterm package is not installed"))) - -;;;###autoload (autoload 'docker-container-vterm-env "docker-container" nil t) -(aio-defun docker-container-vterm-env (container) - "Open `vterm' in CONTAINER with the environment variable set and -default directory set to workdir." - (interactive (list - (docker-container-read-name))) - (docker-container-assert-tramp-docker) - (let* ((container-address (format "%s:%s:" docker-container-tramp-method container)) - (file-prefix (let ((prefix (file-remote-p default-directory))) - (if prefix - (format "%s|" (s-chop-suffix ":" prefix)) - "/"))) - (container-config (cdr (assq 'Config (aref (json-read-from-string (aio-await (docker-run-docker-async "inspect" container))) 0)))) - (container-workdir (cdr (assq 'WorkingDir container-config))) - (container-env (cdr (assq 'Env container-config))) - (default-directory (format "%s%s%s" file-prefix container-address container-workdir)) - ;; process-environment doesn't work with tramp if you call this function more than one per emacs session - (tramp-remote-process-environment (append container-env nil))) - (if (fboundp 'vterm-other-window) - (vterm-other-window (docker-utils-generate-new-buffer-name "docker" "vterm-env:" default-directory)) - (error "The vterm package is not installed")))) - -(defvar eat-buffer-name) - -;;;###autoload (autoload 'docker-container-eat "docker-container" nil t) -(defun docker-container-eat (container) - "Open `eat' in CONTAINER." - (interactive (list (docker-container-read-name))) - (if (fboundp 'eat-other-window) - (let* ((container-address (format "%s:%s:/" docker-container-tramp-method container)) - (file-prefix (let ((prefix (file-remote-p default-directory))) - (if prefix - (format "%s|" (s-chop-suffix ":" prefix)) - "/"))) - (default-directory (format "%s%s" file-prefix container-address)) - (eat-buffer-name (format "*eat:%s" default-directory))) - (eat-other-window)) - (error "The eat package is not installed"))) - -;;;###autoload (autoload 'docker-container-eat-env "docker-container" nil t) -(aio-defun docker-container-eat-env (container) - "Open `eat' in CONTAINER with the environment variable set and -default directory set to workdir." - (interactive (list - (docker-container-read-name))) - (docker-container-assert-tramp-docker) - (let* ((container-address (format "%s:%s:" docker-container-tramp-method container)) - (file-prefix (let ((prefix (file-remote-p default-directory))) - (if prefix - (format "%s|" (s-chop-suffix ":" prefix)) - "/"))) - (container-config (cdr (assq 'Config (aref (json-read-from-string (aio-await (docker-run-docker-async "inspect" container))) 0)))) - (container-workdir (cdr (assq 'WorkingDir container-config))) - (container-env (cdr (assq 'Env container-config))) - (default-directory (format "%s%s%s" file-prefix container-address container-workdir)) - ;; process-environment doesn't work with tramp if you call this function more than one per emacs session - (tramp-remote-process-environment (append container-env nil)) - (eat-buffer-name (format "*eat-env:%s" default-directory))) - (if (fboundp 'eat-other-window) - (eat-other-window) - (error "The eat package is not installed")))) - -(defun docker-container-cp-from-selection (container-path host-path) - "Run \"docker cp\" from CONTAINER-PATH to HOST-PATH for selected container." - (interactive "sContainer path: \nFHost path: ") - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-run-docker-async "cp" (concat it ":" container-path) host-path))) - -(defun docker-container-cp-to-selection (host-path container-path) - "Run \"docker cp\" from HOST-PATH to CONTAINER-PATH for selected containers." - (interactive "fHost path: \nsContainer path: ") - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-run-docker-async "cp" host-path (concat it ":" container-path)))) - -(defun docker-container-eshell-selection () - "Run `docker-container-eshell' on the containers selection." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-eshell it))) - -(defun docker-container-find-directory-selection (path) - "Run `docker-container-find-directory' for PATH on the containers selection." - (interactive "sPath: ") - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-find-directory it path))) - -(defun docker-container-find-file-selection (path) - "Run `docker-container-find-file' for PATH on the containers selection." - (interactive "sPath: ") - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-find-file it path))) - -(aio-defun docker-container-rename-selection () - "Rename containers." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (aio-await (docker-run-docker-async "rename" it (read-string (format "Rename \"%s\" to: " it))))) - (tablist-revert)) - -(defun docker-container-shell-selection (prefix) - "Run `docker-container-shell' on the containers selection forwarding PREFIX." - (interactive "P") - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-shell it prefix))) - -(defun docker-container-shell-env-selection (prefix) - "Run `docker-container-shell-env' on the containers selection forwarding PREFIX." - (interactive "P") - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-shell-env it prefix))) - -(defun docker-container-vterm-selection () - "Run `docker-container-vterm' on the containers selection." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-vterm it))) - -(defun docker-container-vterm-env-selection () - "Run `docker-container-vterm-env' on the containers selection." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-vterm-env it))) - -(defun docker-container-shell-command (container) - "Run exec of a CONTAINER." - (interactive (list (docker-container-read-name))) - (shell-command (read-shell-command "Run: " (format "docker exec %s " container)))) - -(defun docker-container-shell-command-selection () - "Run `docker exec' on the containers selection." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-shell-command it))) - -(defun docker-container-eat-selection () - "Run `docker-container-eat' on the containers selection." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-eat it))) - -(defun docker-container-eat-env-selection () - "Run `docker-container-eat-env' on the containers selection." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-container-eat-env it))) - -(docker-utils-transient-define-prefix docker-container-attach () - "Transient for attaching to containers." - :man-page "docker-container-attach" - ["Arguments" - ("n" "No STDIN" "--no-stdin") - ("d" "Key sequence for detaching" "--detach-keys " read-string)] - [:description docker-generic-action-description - ("a" "Attach" docker-generic-action-with-buffer)]) - -(docker-utils-transient-define-prefix docker-container-cp () - "Transient for copying files from/to containers." - :man-page "docker-container-cp" - [:description docker-generic-action-description - ("f" "Copy From" docker-container-cp-from-selection) - ("t" "Copy To" docker-container-cp-to-selection)]) - -(docker-utils-transient-define-prefix docker-container-diff () - "Transient for showing containers diffs." - :man-page "docker-container-diff" - [:description docker-generic-action-description - ("d" "Diff" docker-generic-action-with-buffer)]) - -(docker-utils-transient-define-prefix docker-container-open () - "Transient for opening containers files." - [:description docker-generic-action-description - ("d" "Open directory" docker-container-find-directory-selection) - ("f" "Open file" docker-container-find-file-selection)]) - -(docker-utils-transient-define-prefix docker-container-kill () - "Transient for kill signaling containers" - :man-page "docker-container-kill" - ["Arguments" - ("s" "Signal" "-s " read-string)] - [:description docker-generic-action-description - ("K" "Kill" docker-generic-action-multiple-ids)]) - -(docker-utils-transient-define-prefix docker-container-logs () - "Transient for showing containers logs." - :man-page "docker-container-logs" - ["Arguments" - ("f" "Follow" "-f") - ("s" "Since" "--since " read-string) - ("t" "Tail" "--tail " read-string) - ("u" "Until" "--until " read-string)] - [:description docker-generic-action-description - ("L" "Logs" docker-generic-action-with-buffer)]) - -(docker-utils-define-transient-arguments docker-container-ls) - -(transient-define-prefix docker-container-ls () - "Transient for listing containers." - :man-page "docker-container-ls" - :value '("--all") - ["Arguments" - ("N" "Last" "--last " transient-read-number-N0) - ("a" "All" "--all") - ("e" "Exited containers" "--filter status=exited") - ("f" "Filter" "--filter " read-string) - ("n" "Don't truncate" "--no-trunc")] - ["Actions" - ("l" "List" tablist-revert)]) - -(docker-utils-transient-define-prefix docker-container-pause () - "Transient for pausing containers." - :man-page "docker-container-pause" - [:description docker-generic-action-description - ("P" "Pause" docker-generic-action-multiple-ids)]) - -(docker-utils-transient-define-prefix docker-container-unpause () - "Transient for pausing containers." - :man-page "docker-container-unpause" - [:description docker-generic-action-description - ("N" "Unpause" docker-generic-action-multiple-ids)]) - -(docker-utils-transient-define-prefix docker-container-restart () - "Transient for restarting containers." - :man-page "docker-container-restart" - ["Arguments" - ("t" "Timeout" "-t " transient-read-number-N0)] - [:description docker-generic-action-description - ("R" "Restart" docker-generic-action-multiple-ids)]) - -(docker-utils-transient-define-prefix docker-container-rm () - "Transient for removing containers." - :man-page "docker-container-rm" - ["Arguments" - ("f" "Force" "-f") - ("v" "Volumes" "-v")] - [:description docker-generic-action-description - ("D" "Remove" docker-generic-action-multiple-ids)]) - -(docker-utils-transient-define-prefix docker-container-shells () - "Transient for using shells on containers." - [:description docker-generic-action-description - ("!" "Shell command" docker-container-shell-command-selection) - ("b" "Shell" docker-container-shell-selection) - ("B" "Shell with env" docker-container-shell-env-selection) - ("e" "Eshell" docker-container-eshell-selection) - ("v" "Vterm" docker-container-vterm-selection) - ("V" "Vterm with env" docker-container-vterm-env-selection) - ("a" "Eat" docker-container-eat-selection) - ("A" "Eat with env" docker-container-eat-env-selection)]) - -(docker-utils-transient-define-prefix docker-container-start () - "Transient for starting containers." - :man-page "docker-container-start" - [:description docker-generic-action-description - ("S" "Start" docker-generic-action-multiple-ids)]) - -(docker-utils-transient-define-prefix docker-container-stop () - "Transient for stoping containers." - :man-page "docker-container-stop" - ["Arguments" - ("t" "Timeout" "-t " transient-read-number-N0)] - [:description docker-generic-action-description - ("O" "Stop" docker-generic-action-multiple-ids)]) - -(transient-define-prefix docker-container-help () - "Help transient for docker containers." - ["Docker Containers" - ["Lifecycle" - ("K" "Kill" docker-container-kill) - ("O" "Stop" docker-container-stop) - ("N" "Unpause" docker-container-unpause) - ("P" "Pause" docker-container-pause) - ("R" "Restart" docker-container-restart) - ("S" "Start" docker-container-start)] - ["Admin" - ("C" "Copy" docker-container-cp) - ("D" "Remove" docker-container-rm) - ("I" "Inspect" docker-container-inspect) - ("L" "Logs" docker-container-logs) - ("a" "Attach" docker-container-attach) - ("b" "Shell" docker-container-shells) - ("d" "Diff" docker-container-diff) - ("f" "Find file" docker-container-open) - ("l" "List" docker-container-ls) - ("r" "Rename" docker-container-rename-selection)]]) - -(defvar docker-container-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "?" 'docker-container-help) - (define-key map "C" 'docker-container-cp) - (define-key map "D" 'docker-container-rm) - (define-key map "I" 'docker-container-inspect) - (define-key map "K" 'docker-container-kill) - (define-key map "L" 'docker-container-logs) - (define-key map "O" 'docker-container-stop) - (define-key map "N" 'docker-container-unpause) - (define-key map "P" 'docker-container-pause) - (define-key map "R" 'docker-container-restart) - (define-key map "S" 'docker-container-start) - (define-key map "a" 'docker-container-attach) - (define-key map "b" 'docker-container-shells) - (define-key map "d" 'docker-container-diff) - (define-key map "f" 'docker-container-open) - (define-key map "l" 'docker-container-ls) - (define-key map "r" 'docker-container-rename-selection) - map) - "Keymap for `docker-container-mode'.") - -;;;###autoload (autoload 'docker-containers "docker-container" nil t) -(defun docker-containers () - "List docker containers." - (interactive) - (docker-utils-pop-to-buffer "*docker-containers*") - (docker-container-mode) - (tablist-revert)) - -(define-derived-mode docker-container-mode tabulated-list-mode "Containers Menu" - "Major mode for handling a list of docker containers." - (setq tabulated-list-format (docker-utils-columns-list-format docker-container-columns)) - (setq tabulated-list-padding 2) - (setq tabulated-list-sort-key docker-container-default-sort-key) - (add-hook 'tabulated-list-revert-hook 'docker-container-refresh nil t) - (tabulated-list-init-header) - (tablist-minor-mode)) - -(provide 'docker-container) - -;;; docker-container.el ends here diff --git a/elpa/docker-20251028.1026/docker-context.el b/elpa/docker-20251028.1026/docker-context.el deleted file mode 100644 index 46c0e20b..00000000 --- a/elpa/docker-20251028.1026/docker-context.el +++ /dev/null @@ -1,186 +0,0 @@ -;;; docker-context.el --- Interface to docker-context -*- lexical-binding: t -*- - -;; Author: Pablo González Carrizo - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) -(require 'json) -(require 'tablist) -(require 'transient) - -(require 'docker-core) -(require 'docker-faces) -(require 'docker-utils) - -(defgroup docker-context nil - "Docker context customization group." - :group 'docker) - -(defconst docker-context-id-template - "{{ json .Name }}" - "This Go template extracts the context id which will be passed to transient commands.") - -(defcustom docker-context-default-sort-key '("Name" . nil) - "Sort key for docker contexts. - -This should be a cons cell (NAME . FLIP) where -NAME is a string matching one of the column names -and FLIP is a boolean to specify the sort order." - :group 'docker-context - :type '(cons (string :tag "Column Name" - :validate (lambda (widget) - (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-context-columns) - (widget-put widget :error "Default Sort Key must match a column name") - widget))) - (choice (const :tag "Ascending" nil) - (const :tag "Descending" t)))) - -(defcustom docker-context-columns - '((:name "Name" :width 40 :template "{{ json .Name }}" :sort nil :format nil) - (:name "Description" :width 40 :template "{{ json .Description }}" :sort nil :format nil) - (:name "Endpoint" :width 40 :template "{{ json .DockerEndpoint }}" :sort nil :format nil)) - "Column specification for docker contexts. - -The order of entries defines the displayed column order. -'Template' is the Go template passed to `docker-context-ls' to create the column -data. It should return a string delimited with double quotes. -'Sort function' is a binary predicate that should return true when the first -argument should be sorted before the second. -'Format function' is a function from string to string that transforms the -displayed values in the column." - :group 'docker-context - :set 'docker-utils-columns-setter - :get 'docker-utils-columns-getter - :type '(repeat (list :tag "Column" - (string :tag "Name") - (integer :tag "Width") - (string :tag "Template") - (sexp :tag "Sort function") - (sexp :tag "Format function")))) - -(aio-defun docker-context-inspect () - "Run \"`docker-command' context inspect\" on the selected items." - (interactive) - (docker-inspect "context")) - -(aio-defun docker-context-entries (&rest args) - "Return the docker contexts data for `tabulated-list-entries'." - (let* ((fmt (docker-utils-make-format-string docker-context-id-template docker-context-columns)) - (data (aio-await (docker-run-docker-async "context" "ls" args (format "--format=\"%s\"" fmt)))) - (lines (s-split "\n" data t))) - (-map (-partial #'docker-utils-parse docker-context-columns) lines))) - -(aio-defun docker-context-active-name (&rest args) - (let* ((fmt "{{ json .Current }} {{ json .Name }}") - (data (aio-await (docker-run-docker-async "context" "ls" args (format "--format=\"%s\"" fmt)))) - (lines (s-split "\n" data t)) - (active-line (-first (lambda (line) (string-match-p "true" (car (s-split " " line)))) lines))) - (when active-line - (cadr (split-string active-line "\""))))) - -(aio-defun docker-context-entries-propertized (&rest args) - "Return the propertized docker contexts data for `tabulated-list-entries'." - (let ((entries (aio-await (docker-context-entries args))) - (active (aio-await (docker-context-active-name args)))) - (--map-when (string= active (car it)) (docker-context-entry-set-active it) entries))) - -(defun docker-context-entry-set-active (entry) - "Mark ENTRY (output of `docker-context-entries') as active. - -The result is the tabulated list id for an entry is propertized with -'docker-context-active and the entry is fontified with 'docker-face-active." - (list (propertize (car entry) 'docker-context-active t) - (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-active) (cadr entry))))) - - -(aio-defun docker-context-update-status-async () - "Write the status to `docker-status-strings'." - (plist-put docker-status-strings :contexts "Contexts") - (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) - (let* ((entries (aio-await (docker-context-entries-propertized (docker-context-ls-arguments))))) - (plist-put docker-status-strings - :contexts - (format "Context (%s total)" (number-to-string (length entries)))) - (transient--redisplay)))) - -(add-hook 'docker-open-hook #'docker-context-update-status-async) - -(aio-defun docker-context-refresh () - "Refresh the contexts list." - (docker-utils-refresh-entries - (docker-context-entries-propertized (docker-context-ls-arguments)))) - -(docker-utils-define-transient-arguments docker-context-ls) - -(docker-utils-transient-define-prefix docker-context-rm () - "Transient for removing contexts." - :man-page "docker-context-rm" - [:description docker-generic-action-description - ("D" "Remove" docker-generic-action-multiple-ids)]) - -(docker-utils-transient-define-prefix docker-context-use () - "Transient for using contexts." - :man-page "docker-context-use" - [:description docker-generic-action-description - ("X" "Use" docker-generic-action)]) - -(transient-define-prefix docker-context-help () - "Help transient for docker contexts." - ["Docker contexts help" - ("D" "Remove" docker-context-rm) - ("I" "Inspect" docker-context-inspect) - ("X" "Use" docker-context-use)]) - -(defvar docker-context-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "?" 'docker-context-help) - (define-key map "D" 'docker-context-rm) - (define-key map "I" 'docker-context-inspect) - (define-key map "X" 'docker-context-use) - map) - "Keymap for `docker-context-mode'.") - -;;;###autoload (autoload 'docker-contexts "docker-context" nil t) -(defun docker-contexts () - "List docker contexts." - (interactive) - (docker-utils-pop-to-buffer "*docker-contexts*") - (docker-context-mode) - (tablist-revert)) - -(define-derived-mode docker-context-mode tabulated-list-mode "Contexts Menu" - "Major mode for handling a list of docker contexts." - (setq tabulated-list-format (docker-utils-columns-list-format docker-context-columns)) - (setq tabulated-list-padding 2) - (setq tabulated-list-sort-key docker-context-default-sort-key) - (add-hook 'tabulated-list-revert-hook 'docker-context-refresh nil t) - (tabulated-list-init-header) - (tablist-minor-mode)) - -(provide 'docker-context) - -;;; docker-context.el ends here diff --git a/elpa/docker-20251028.1026/docker-core.el b/elpa/docker-20251028.1026/docker-core.el deleted file mode 100644 index 27621292..00000000 --- a/elpa/docker-20251028.1026/docker-core.el +++ /dev/null @@ -1,149 +0,0 @@ -;;; docker-core.el --- Docker core -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 'aio) -(require 'transient) - -(require 'docker-group) -(require 'docker-utils) -(require 'docker-process) - -(defcustom docker-command "docker" - "The docker binary." - :group 'docker - :type 'string) - -(defvar docker-open-hook () - "Called when `docker' transient is opened.") - -(defvar docker-status-strings '(:containers "" :images "" :networks "" :volumes "" :contexts "") - "Plist of statuses for `docker' transient.") - -(defcustom docker-show-status 'local-only - "Whether to display docker status in the main transient buffer." - :group 'docker - :type '(choice - (const :tag "Always" t) - (const :tag "Local Only" local-only) - (const :tag "Never" nil))) - -(defcustom docker-inspect-view-mode (if (fboundp 'json-mode) 'json-mode 'js-mode) - "Major mode used in `docker inspect' buffers." - :group 'docker - :type 'symbol) - -(defun docker-run-docker-async (&rest args) - "Execute \"`docker-command' ARGS\" and return a promise with the results." - (apply #'docker-run-async docker-command (docker-arguments) args)) - -(defun docker-run-docker-async-with-buffer (&rest args) - "Execute \"`docker-command' ARGS\" and display the results in a buffer." - (apply #'docker-run-async-with-buffer docker-command (docker-arguments) args)) - -(defun docker-get-transient-action () - "Extract the action out of `transient-current-command'." - (s-replace "-" " " (s-chop-prefix "docker-" (symbol-name transient-current-command)))) - -(defun docker-generic-action-description () - "Make the actions description for the selected items." - (let ((items (s-join ", " (docker-utils-get-marked-items-ids)))) - (format "%s %s" - (propertize "Actions on" 'face 'transient-heading) - (propertize items 'face 'transient-value)))) - -(aio-defun docker-generic-action (action args) - "Run \"`docker-command' ACTION ARGS\" on each of the selected items." - (interactive (list (docker-get-transient-action) - (transient-args transient-current-command))) - (let* ((ids (docker-utils-get-marked-items-ids)) - (promises (--map (docker-run-docker-async action args it) ids))) - (aio-await (aio-all promises)) - (tablist-revert))) - -(aio-defun docker-generic-action-multiple-ids (action args) - "Same as `docker-generic-action', but group selection ids into a single command." - (interactive (list (docker-get-transient-action) - (transient-args transient-current-command))) - (aio-await (docker-run-docker-async action args (docker-utils-get-marked-items-ids))) - (tablist-revert)) - -(defun docker-generic-action-with-buffer (action args) - "Run \"`docker-command' ACTION ARGS\" and print output to a new buffer." - (interactive (list (docker-get-transient-action) - (transient-args transient-current-command))) - (--each (docker-utils-get-marked-items-ids) - (docker-run-docker-async-with-buffer (s-split " " action) args it))) - -(aio-defun docker-inspect (&optional subcmd) - "Run \"`docker-command' inspect\" on the selected items." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (let* ((id it) - (data (aio-await (docker-run-docker-async (concat (or subcmd "") " inspect") id)))) - (docker-utils-with-buffer (format "inspect %s" id) - (insert data) - (funcall docker-inspect-view-mode) - (view-mode))))) - -(defun docker-read-log-level (prompt &rest _args) - "Read the docker log level using PROMPT." - (completing-read prompt '(debug info warn error fatal))) - -(defun docker-read-certificate (prompt &optional initial-input _history) - "Wrapper around `read-file-name' forwarding PROMPT and INITIAL-INPUT." - (read-file-name prompt nil nil t initial-input (apply-partially 'string-match ".*\\.pem"))) - -(docker-utils-define-transient-arguments docker) - -;;;###autoload (autoload 'docker "docker" nil t) -(transient-define-prefix docker () - "Transient for docker." - :man-page "docker" - ["Arguments" - (5 "H" "Host" "--host " read-string) - (5 "Tt" "TLS" "--tls") - (5 "Tv" "TLS verify remote" "--tlsverify") - (5 "Ta" "TLS CA" "--tlscacert" docker-read-certificate) - (5 "Tc" "TLS certificate" "--tlscert" docker-read-certificate) - (5 "Tk" "TLS key" "--tlskey" docker-read-certificate) - (5 "l" "Log level" "--log-level " docker-read-log-level)] - ["Docker" - ("c" (lambda ()(plist-get docker-status-strings :containers)) docker-containers) - ("i" (lambda ()(plist-get docker-status-strings :images)) docker-images) - ("n" (lambda ()(plist-get docker-status-strings :networks)) docker-networks) - ("v" (lambda ()(plist-get docker-status-strings :volumes)) docker-volumes) - ("x" (lambda ()(plist-get docker-status-strings :contexts)) docker-contexts)] - ["Other" - ("C" "Compose" docker-compose)] - (interactive) - (run-hooks 'docker-open-hook) - (transient-setup 'docker)) - -(provide 'docker-core) - -;;; docker-core.el ends here diff --git a/elpa/docker-20251028.1026/docker-faces.el b/elpa/docker-20251028.1026/docker-faces.el deleted file mode 100644 index c4e8aeee..00000000 --- a/elpa/docker-20251028.1026/docker-faces.el +++ /dev/null @@ -1,65 +0,0 @@ -;;; docker-faces.el --- Docker faces -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'dash) - -(require 'docker-core) - -(defgroup docker-faces nil - "Docker faces customization group." - :group 'docker - :group 'faces) - -(defface docker-face-status-up - '((t :inherit success)) - "Face used when the status is up." - :group 'docker-faces) - -(defface docker-face-status-down - '((t :inherit error)) - "Face used when the status is down." - :group 'docker-faces) - -(defface docker-face-status-other - '((t :inherit warning)) - "Face used when the status is not up/down." - :group 'docker-faces) - -(defface docker-face-dangling - '((t :inherit shadow)) - "Face for dangling items." - :group 'docker-faces) - -(defface docker-face-active - '((t :inherit bold)) - "Face for active items." - :group 'docker-faces) - -(provide 'docker-faces) - -;;; docker-faces.el ends here diff --git a/elpa/docker-20251028.1026/docker-group.el b/elpa/docker-20251028.1026/docker-group.el deleted file mode 100644 index fc76e629..00000000 --- a/elpa/docker-20251028.1026/docker-group.el +++ /dev/null @@ -1,34 +0,0 @@ -;;; docker-group.el --- Docker group -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(defgroup docker nil - "Docker customization group." - :group 'convenience) - -(provide 'docker-group) - -;;; docker-group.el ends here diff --git a/elpa/docker-20251028.1026/docker-image.el b/elpa/docker-20251028.1026/docker-image.el deleted file mode 100644 index 6ebe8474..00000000 --- a/elpa/docker-20251028.1026/docker-image.el +++ /dev/null @@ -1,339 +0,0 @@ -;;; docker-image.el --- Interface to docker-image -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) -(require 'json) -(require 'tablist) -(require 'transient) - -(require 'docker-core) -(require 'docker-faces) -(require 'docker-utils) - -(defgroup docker-image nil - "Docker images customization group." - :group 'docker) - -(defconst docker-image-id-template - "[{{ json .Repository }},{{ json .Tag }},{{ json .ID }}]" - "This Go template defines what will be passed to transient commands. - -This value is processed by `docker-image-make-id'.") - -(defcustom docker-image-default-sort-key '("Repository" . nil) - "Sort key for docker images. - -This should be a cons cell (NAME . FLIP) where -NAME is a string matching one of the column names -and FLIP is a boolean to specify the sort order." - :group 'docker-image - :type '(cons (string :tag "Column Name" - :validate (lambda (widget) - (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-image-columns) - (widget-put widget :error "Default Sort Key must match a column name") - widget))) - (choice (const :tag "Ascending" nil) - (const :tag "Descending" t)))) - -(defcustom docker-image-columns - '((:name "Repository" :width 30 :template "{{ json .Repository }}" :sort nil :format nil) - (:name "Tag" :width 20 :template "{{ json .Tag }}" :sort nil :format nil) - (:name "Id" :width 16 :template "{{ json .ID }}" :sort nil :format nil) - (:name "Created" :width 24 :template "{{ json .CreatedAt }}" :sort nil :format (lambda (x) (format-time-string "%F %T" (date-to-time x)))) - (:name "Size" :width 10 :template "{{ json .Size }}" :sort docker-utils-human-size-predicate :format nil)) - "Column specification for docker images. - -The order of entries defines the displayed column order. -'Template' is the Go template passed to `docker-image-ls' to create the column -data. It should return a string delimited with double quotes. -'Sort function' is a binary predicate that should return true when the first -argument should be sorted before the second. -'Format function' is a function from string to string that transforms the -displayed values in the column." - :group 'docker-image - :set 'docker-utils-columns-setter - :get 'docker-utils-columns-getter - :type '(repeat (list :tag "Column" - (string :tag "Name") - (integer :tag "Width") - (string :tag "Template") - (sexp :tag "Sort function") - (sexp :tag "Format function")))) - -(defcustom docker-image-run-default-args - '("-i" "-t" "--rm") - "Default infix args used when docker run is invoked. - -Note this can be overriden for specific images using -`docker-image-run-custom-args'." - :group 'docker-image - :type '(repeat string)) - -(make-obsolete-variable 'docker-run-default-args 'docker-image-run-default-args "Docker 2.1.0") - -(defcustom docker-image-run-custom-args - nil - "List which can be used to customize the default arguments for docker run. - -Its elements should be of the form (REGEX ARGS) where -REGEX is a (string) regular expression and ARGS is a list of strings -corresponding to arguments. - -Also note if you do not specify `docker-run-default-args', they will be ignored." - :type '(repeat (list string (repeat string)))) - -(defalias 'docker-image-inspect 'docker-inspect) - -(defun docker-image-make-id (parsed-line) - "Fix the id string of the entry and return the fixed entry. - -PARSED-LINE is the output of `docker-utils-parse', the car is expected to -be the list (repository tag id). See `docker-image-id-template'." - ;; This could be written as a complex go template, - ;; however the literal '' causes havoc in the windows shell. - (-let* ((([repo tag id] rest) parsed-line) - (new-id (if (or (equal repo "") (equal tag "")) - id - (format "%s:%s" repo tag)))) - (list new-id rest))) - -(aio-defun docker-image-entries (&rest args) - "Return the docker images data for `tabulated-list-entries'." - (let* ((fmt (docker-utils-make-format-string docker-image-id-template docker-image-columns)) - (data (aio-await (docker-run-docker-async "image" "ls" args (format "--format=\"%s\"" fmt)))) - (lines (s-split "\n" data t))) - (--map (docker-image-make-id (docker-utils-parse docker-image-columns it)) lines))) - -(aio-defun docker-image-entries-propertized (&rest args) - "Return the propertized docker images data for `tabulated-list-entries'." - (let ((entries (aio-await (docker-image-entries args))) - (dangling (aio-await (docker-image-entries args "--filter dangling=true")))) - (--map-when (-contains? dangling it) (docker-image-entry-set-dangling it) entries))) - -(defun docker-image-dangling-p (entry-id) ; - "Predicate for if ENTRY-ID is dangling. - -For example (docker-image-dangling-p (tabulated-list-get-id)) is t when the entry under point is dangling." - (get-text-property 0 'docker-image-dangling entry-id)) - -(defun docker-image-entry-set-dangling (entry) - "Mark ENTRY (output of `docker-image-entries') as dangling. - -The result is the tabulated list id for an entry is propertized with -'docker-image-dangling and the entry is fontified with 'docker-face-dangling." - (list (propertize (car entry) 'docker-image-dangling t) - (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-dangling) (cadr entry))))) - -(aio-defun docker-image-update-status-async () - "Write the status to `docker-status-strings'." - (plist-put docker-status-strings :images "Images") - (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) - (let* ((entries (aio-await (docker-image-entries-propertized (docker-image-ls-arguments)))) - (dangling (--filter (docker-image-dangling-p (car it)) entries))) - (plist-put docker-status-strings - :images - (format "Images (%s total, %s dangling)" - (number-to-string (length entries)) - (propertize (number-to-string (length dangling)) 'face 'docker-face-dangling))) - (transient--redisplay)))) - -(add-hook 'docker-open-hook #'docker-image-update-status-async) - -(aio-defun docker-image-refresh () - "Refresh the images list." - (docker-utils-refresh-entries - (docker-image-entries-propertized (docker-image-ls-arguments)))) - -(defun docker-image-read-name () - "Read an image name." - (completing-read "Image: " (-map #'car (aio-wait-for (docker-image-entries))))) - -;;;###autoload (autoload 'docker-image-pull-one "docker-image" nil t) -(aio-defun docker-image-pull-one (name &optional all) - "Pull the image named NAME. If ALL is set, use \"-a\"." - (interactive (list (docker-image-read-name) current-prefix-arg)) - (aio-await (docker-run-docker-async "pull" (when all "-a") name)) - (tablist-revert)) - -(defun docker-image-run-selection (command) - "Run \"docker image run\" with COMMAND on the images selection." - (interactive "sCommand: ") - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-run-docker-async-with-buffer "container" "run" (transient-args 'docker-image-run) it command))) - -(aio-defun docker-image-tag-selection () - "Tag images." - (interactive) - (docker-utils-ensure-items) - (let* ((ids (docker-utils-get-marked-items-ids)) - (promises (--map (docker-run-docker-async "tag" it (read-string (format "Tag for %s: " it))) ids))) - (aio-await (aio-all promises)) - (tablist-revert))) - -(defun docker-image-mark-dangling () - "Mark only the dangling images listed in *docker-images*. - -This clears any user marks first and respects any tablist filters -applied to the buffer." - (interactive) - (switch-to-buffer "*docker-images*") - (tablist-unmark-all-marks) - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (when (docker-image-dangling-p (tabulated-list-get-id)) - (tablist-put-mark)) - (forward-line)))) - -(docker-utils-define-transient-arguments docker-image-ls) - -(transient-define-prefix docker-image-ls () - "Transient for listing images." - :man-page "docker-image-ls" - ["Arguments" - ("a" "All" "--all") - ("d" "Dangling" "--filter dangling=true") - ("f" "Filter" "--filter " read-string) - ("n" "Don't truncate" "--no-trunc")] - ["Actions" - ("l" "List" tablist-revert)]) - -(transient-define-prefix docker-image-pull () - "Transient for pulling images." - :man-page "docker-image-pull" - ["Arguments" - ("a" "All" "-a")] - [:description docker-generic-action-description - ("F" "Pull selection" docker-generic-action) - ("N" "Pull a new image" docker-image-pull-one)]) - -(docker-utils-transient-define-prefix docker-image-push () - "Transient for pushing images." - :man-page "docker-image-push" - [:description docker-generic-action-description - ("P" "Push" docker-generic-action)]) - -(docker-utils-transient-define-prefix docker-image-rm () - "Transient for removing images." - :man-page "docker-image-rm" - ["Arguments" - ("-f" "Force" "-f") - ("-n" "Don't prune" "--no-prune")] - [:description docker-generic-action-description - ("D" "Remove" docker-generic-action-multiple-ids)]) - -(defclass docker-run-prefix (transient-prefix) nil) - -(cl-defmethod transient-init-value ((obj docker-run-prefix)) - "Helper that modify OBJ DOCKER-RUN-PREFIX to handle `docker-image-run-custom-args'." - (oset obj value - (let* ((images (tablist-get-marked-items)) - (matched-args (let ((repo-name (caar images))) - (if repo-name - (--first (string-match (car it) repo-name) - docker-image-run-custom-args) - nil)))) - (if matched-args - (cadr matched-args) - docker-image-run-default-args)))) - -(docker-utils-transient-define-prefix docker-image-run () - "Transient for running images." - :man-page "docker-image-run" - :class 'docker-run-prefix - ["Arguments" - ("D" "With display" "-v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY") - ("M" "Mount volume" "--mount " read-string) - ("N" "Network" "--network " read-string) - ("P" "Privileged" "--privileged") - ("T" "Synchronize time" "-v /etc/localtime:/etc/localtime:ro") - ("W" "Web ports" "-p 80:80 -p 443:443 -p 8080:8080") - ("d" "Detach" "-d") - ("e" "Environment" "-e " read-string) - ("i" "Interactive" "-i") - ("l" "Link" "--link " read-string) - ("m" "Name" "--name " read-string) - ("n" "Entrypoint" "--entrypoint " read-string) - ("o" "Read only" "--read-only") - ("p" "Port" "-p " read-string) - ("r" "Remove container when it exits" "--rm") - ("t" "TTY" "-t") - ("u" "User" "-u " read-string) - ("v" "Volume" "-v " read-string) - ("w" "Workdir" "-w " read-string)] - [:description docker-generic-action-description - ("R" "Run" docker-image-run-selection)]) - -(transient-define-prefix docker-image-help () - "Help transient for docker images." - ["Docker images help" - ("D" "Remove" docker-image-rm) - ("F" "Pull" docker-image-pull) - ("I" "Inspect" docker-image-inspect) - ("P" "Push" docker-image-push) - ("R" "Run" docker-image-run) - ("T" "Tag" docker-image-tag-selection) - ("d" "Mark Dangling" docker-image-mark-dangling) - ("l" "List" docker-image-ls)]) - -(defvar docker-image-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "?" 'docker-image-help) - (define-key map "D" 'docker-image-rm) - (define-key map "F" 'docker-image-pull) - (define-key map "I" 'docker-image-inspect) - (define-key map "P" 'docker-image-push) - (define-key map "R" 'docker-image-run) - (define-key map "T" 'docker-image-tag-selection) - (define-key map "d" 'docker-image-mark-dangling) - (define-key map "l" 'docker-image-ls) - map) - "Keymap for `docker-image-mode'.") - -;;;###autoload (autoload 'docker-images "docker-image" nil t) -(defun docker-images () - "List docker images." - (interactive) - (docker-utils-pop-to-buffer "*docker-images*") - (docker-image-mode) - (tablist-revert)) - -(define-derived-mode docker-image-mode tabulated-list-mode "Images Menu" - "Major mode for handling a list of docker images." - (setq tabulated-list-format (docker-utils-columns-list-format docker-image-columns)) - (setq tabulated-list-padding 2) - (setq tabulated-list-sort-key docker-image-default-sort-key) - (add-hook 'tabulated-list-revert-hook 'docker-image-refresh nil t) - (tabulated-list-init-header) - (tablist-minor-mode)) - -(provide 'docker-image) - -;;; docker-image.el ends here diff --git a/elpa/docker-20251028.1026/docker-network.el b/elpa/docker-20251028.1026/docker-network.el deleted file mode 100644 index f835bd0b..00000000 --- a/elpa/docker-20251028.1026/docker-network.el +++ /dev/null @@ -1,209 +0,0 @@ -;;; docker-network.el --- Interface to docker-network -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) -(require 'json) -(require 'tablist) -(require 'transient) - -(require 'docker-core) -(require 'docker-faces) -(require 'docker-utils) - -(defgroup docker-network nil - "Docker network customization group." - :group 'docker) - -(defconst docker-network-id-template - "{{ json .ID }}" - "This Go template extracts the id which will be passed to transient commands.") - -(defcustom docker-network-default-sort-key '("Name" . nil) - "Sort key for docker networks. - -This should be a cons cell (NAME . FLIP) where -NAME is a string matching one of the column names -and FLIP is a boolean to specify the sort order." - :group 'docker-network - :type '(cons (string :tag "Column Name" - :validate (lambda (widget) - (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-network-columns) - (widget-put widget :error "Default Sort Key must match a column name") - widget))) - (choice (const :tag "Ascending" nil) - (const :tag "Descending" t)))) - -(defcustom docker-network-columns - '((:name "Network ID" :width 20 :template "{{ json .ID }}" :sort nil :format nil) - (:name "Name" :width 50 :template "{{ json .Name }}" :sort nil :format nil) - (:name "Driver" :width 10 :template "{{ json .Driver }}" :sort nil :format nil) - (:name "Scope" :width 10 :template "{{ json .Scope }}" :sort nil :format nil)) - "Column specification for docker networks. - -The order of entries defines the displayed column order. -'Template' is the Go template passed to `docker-network-ls' to create the column -data. It should return a string delimited with double quotes. -'Sort function' is a binary predicate that should return true when the first -argument should be sorted before the second. -'Format function' is a function from string to string that transforms the -displayed values in the column." - :group 'docker-network - :set 'docker-utils-columns-setter - :get 'docker-utils-columns-getter - :type '(repeat (list :tag "Column" - (string :tag "Name") - (integer :tag "Width") - (string :tag "Template") - (sexp :tag "Sort function") - (sexp :tag "Format function")))) - -(defalias 'docker-network-inspect 'docker-inspect) - -(aio-defun docker-network-entries (&rest args) - "Return the docker networks data for `tabulated-list-entries'." - (let* ((fmt (docker-utils-make-format-string docker-network-id-template docker-network-columns)) - (data (aio-await (docker-run-docker-async "network" "ls" args (format "--format=\"%s\"" fmt)))) - (lines (s-split "\n" data t))) - (-map (-partial #'docker-utils-parse docker-network-columns) lines))) - -(aio-defun docker-network-entries-propertized (&rest args) - "Return the propertized docker networks data for `tabulated-list-entries'." - (let ((entries (aio-await (docker-network-entries args))) - (dangling (aio-await (docker-network-entries args "--filter dangling=true")))) - (--map-when (-contains? dangling it) (docker-network-entry-set-dangling it) entries))) - -(defun docker-network-dangling-p (entry-id) - "Predicate for if ENTRY-ID is dangling. - -For example (docker-network-dangling-p (tabulated-list-get-id)) is t when the entry under point is dangling." - (get-text-property 0 'docker-network-dangling entry-id)) - -(defun docker-network-entry-set-dangling (entry) - "Mark ENTRY (output of `docker-network-entries') as dangling. - -The result is the tabulated list id for an entry is propertized with -'docker-network-dangling and the entry is fontified with 'docker-face-dangling." - (list (propertize (car entry) 'docker-network-dangling t) - (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-dangling) (cadr entry))))) - -(aio-defun docker-network-update-status-async () - "Write the status to `docker-status-strings'." - (plist-put docker-status-strings :networks "Networks") - (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) - (let* ((entries (aio-await (docker-network-entries-propertized (docker-network-ls-arguments)))) - (dangling (--filter (docker-network-dangling-p (car it)) entries))) - (plist-put docker-status-strings - :networks - (format "Networks (%s total, %s dangling)" - (number-to-string (length entries)) - (propertize (number-to-string (length dangling)) 'face 'docker-face-dangling))) - (transient--redisplay)))) - -(add-hook 'docker-open-hook #'docker-network-update-status-async) - -(aio-defun docker-network-refresh () - "Refresh the networks list." - (docker-utils-refresh-entries - (docker-network-entries-propertized (docker-network-ls-arguments)))) - -(defun docker-network-read-name () - "Read a network name." - (completing-read "Network: " (-map #'car (aio-wait-for (docker-network-entries))))) - -(defun docker-network-mark-dangling () - "Mark only the dangling networks listed in *docker-networks*. - -This clears any user marks first and respects any tablist filters -applied to the buffer." - (interactive) - (switch-to-buffer "*docker-networks*") - (tablist-unmark-all-marks) - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (when (docker-network-dangling-p (tabulated-list-get-id)) - (tablist-put-mark)) - (forward-line)))) - -(docker-utils-define-transient-arguments docker-network-ls) - -(transient-define-prefix docker-network-ls () - "Transient for listing networks." - :man-page "docker-network-ls" - ["Arguments" - ("d" "Dangling" "--filter dangling=true") - ("f" "Filter" "--filter " read-string) - ("n" "Don't truncate" "--no-trunc")] - ["Actions" - ("l" "List" tablist-revert)]) - -(docker-utils-transient-define-prefix docker-network-rm () - "Transient for removing networks." - :man-page "docker-network-rm" - [:description docker-generic-action-description - ("D" "Remove" docker-generic-action-multiple-ids)]) - -(transient-define-prefix docker-network-help () - "Help transient for docker networks." - ["Docker networks help" - ("D" "Remove" docker-network-rm) - ("I" "Inspect" docker-network-inspect) - ("d" "Mark Dangling" docker-network-mark-dangling) - ("l" "List" docker-network-ls)]) - -(defvar docker-network-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "?" 'docker-network-help) - (define-key map "D" 'docker-network-rm) - (define-key map "I" 'docker-network-inspect) - (define-key map "d" 'docker-network-mark-dangling) - (define-key map "l" 'docker-network-ls) - map) - "Keymap for `docker-network-mode'.") - -;;;###autoload (autoload 'docker-networks "docker-network" nil t) -(defun docker-networks () - "List docker networks." - (interactive) - (docker-utils-pop-to-buffer "*docker-networks*") - (docker-network-mode) - (tablist-revert)) - -(define-derived-mode docker-network-mode tabulated-list-mode "Networks Menu" - "Major mode for handling a list of docker networks." - (setq tabulated-list-format (docker-utils-columns-list-format docker-network-columns)) - (setq tabulated-list-padding 2) - (setq tabulated-list-sort-key docker-network-default-sort-key) - (add-hook 'tabulated-list-revert-hook 'docker-network-refresh nil t) - (tabulated-list-init-header) - (tablist-minor-mode)) - -(provide 'docker-network) - -;;; docker-network.el ends here diff --git a/elpa/docker-20251028.1026/docker-pkg.el b/elpa/docker-20251028.1026/docker-pkg.el deleted file mode 100644 index 44e0c1c3..00000000 --- a/elpa/docker-20251028.1026/docker-pkg.el +++ /dev/null @@ -1,15 +0,0 @@ -;; -*- no-byte-compile: t; lexical-binding: nil -*- -(define-package "docker" "20251028.1026" - "Interface to Docker." - '((aio "1.0") - (dash "2.19.1") - (emacs "28.1") - (s "1.13.0") - (tablist "1.1") - (transient "0.4.3")) - :url "https://github.com/Silex/docker.el" - :commit "375e0ed45bb1edc655d9ae2943a09864bec1fcba" - :revdesc "375e0ed45bb1" - :keywords '("filename" "convenience") - :authors '(("Philippe Vaucher" . "philippe.vaucher@gmail.com")) - :maintainers '(("Philippe Vaucher" . "philippe.vaucher@gmail.com"))) diff --git a/elpa/docker-20251028.1026/docker-process.el b/elpa/docker-20251028.1026/docker-process.el deleted file mode 100644 index d929923c..00000000 --- a/elpa/docker-20251028.1026/docker-process.el +++ /dev/null @@ -1,119 +0,0 @@ -;;; docker-process.el --- Docker process -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) - -(require 'docker-group) -(require 'docker-utils) - -(defcustom docker-run-as-root nil - "Run docker as root." - :group 'docker - :type 'boolean) - -(defcustom docker-show-messages t - "If non-nil `message' docker commands which are run." - :group 'docker - :type 'boolean) - -(defcustom docker-run-async-with-buffer-function (if (featurep 'vterm) - 'docker-run-async-with-buffer-vterm - 'docker-run-async-with-buffer-shell) - "Function used to run a program with a live buffer attached to it." - :group 'docker - :type 'symbol) - - -(defmacro docker-with-sudo (&rest body) - "Ensure `default-directory' is set correctly according to `docker-run-as-root' then execute BODY." - (declare (indent defun)) - `(let ((default-directory (if (and docker-run-as-root (not (file-remote-p default-directory))) - "/sudo::" - default-directory))) - ,@body)) - -(defun docker-run-start-file-process-shell-command (program &rest args) - "Execute \"PROGRAM ARGS\" and return the process." - (docker-with-sudo - (let* ((process-args (-remove 's-blank? (-flatten args))) - (command (s-join " " (-insert-at 0 program process-args)))) - (when docker-show-messages (message "Running: %s" command)) - (start-file-process-shell-command command (apply #'docker-utils-generate-new-buffer-name program process-args) command)))) - -(defun docker-run-async (program &rest args) - "Execute \"PROGRAM ARGS\" and return a promise with the results." - (let* ((process (apply #'docker-run-start-file-process-shell-command program args)) - (promise (aio-promise))) - (set-process-query-on-exit-flag process nil) - (set-process-sentinel process (-partial #'docker-process-sentinel promise)) - promise)) - -(defun docker-run-async-with-buffer (program &rest args) - "Execute \"PROGRAM ARGS\" and display output in a new buffer." - (apply docker-run-async-with-buffer-function program args)) - -(defun docker-run-async-with-buffer-shell (program &rest args) - "Execute \"PROGRAM ARGS\" and display output in a new `shell' buffer." - (let* ((process (apply #'docker-run-start-file-process-shell-command program args)) - (buffer (process-buffer process))) - (set-process-query-on-exit-flag process nil) - (with-current-buffer buffer (shell-mode)) - (set-process-filter process 'comint-output-filter) - (switch-to-buffer-other-window buffer))) - -(defun docker-run-async-with-buffer-vterm (program &rest args) - "Execute \"PROGRAM ARGS\" and display output in a new `vterm' buffer." - (defvar vterm-kill-buffer-on-exit) - (defvar vterm-shell) - (if (fboundp 'vterm-other-window) - (let* ((process-args (-remove 's-blank? (-flatten args))) - (vterm-shell (s-join " " (-insert-at 0 program process-args))) - (vterm-kill-buffer-on-exit nil)) - (vterm-other-window - (apply #'docker-utils-generate-new-buffer-name program process-args))) - (error "The vterm package is not installed"))) - -(defun docker-process-sentinel (promise process event) - "Sentinel that resolves the PROMISE using PROCESS and EVENT." - (when (memq (process-status process) '(exit signal)) - (setq event (substring event 0 -1)) - (if (not (string-equal event "finished")) - (error "Error running: \"%s\" (%s)" (process-name process) event) - (aio-resolve promise - (lambda () - (when docker-show-messages - (message "Finished: %s" (process-name process))) - (run-with-timer 2 nil (lambda () (message nil))) - (with-current-buffer (process-buffer process) - (prog1 (buffer-substring-no-properties (point-min) (point-max)) - (kill-buffer)))))))) - -(provide 'docker-process) - -;;; docker-process.el ends here diff --git a/elpa/docker-20251028.1026/docker-utils.el b/elpa/docker-20251028.1026/docker-utils.el deleted file mode 100644 index 0f178667..00000000 --- a/elpa/docker-20251028.1026/docker-utils.el +++ /dev/null @@ -1,187 +0,0 @@ -;;; docker-utils.el --- Random utilities -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) -(require 'json) -(require 'tramp) -(require 'tablist) -(require 'transient) - -(defun docker-utils-get-marked-items-ids () - "Get the id part of `tablist-get-marked-items'." - (-map #'car (tablist-get-marked-items))) - -(defun docker-utils-ensure-items () - "Ensure at least one item is selected." - (when (null (docker-utils-get-marked-items-ids)) - (user-error "This action cannot be used in an empty list"))) - -(defun docker-utils-generate-new-buffer-name (program &rest args) - "Wrapper around `generate-new-buffer-name' using PROGRAM and ARGS." - (generate-new-buffer-name (format "* %s %s *" program (s-join " " args)))) - -(defun docker-utils-generate-new-buffer (program &rest args) - "Wrapper around `generate-new-buffer' using PROGRAM and ARGS." - (generate-new-buffer (apply #'docker-utils-generate-new-buffer-name program args))) - -(defmacro docker-utils-with-buffer (name &rest body) - "Wrapper around `with-current-buffer'. -Execute BODY in a buffer named with the help of NAME." - (declare (indent defun)) - `(with-current-buffer (docker-utils-generate-new-buffer "docker" ,name) - (setq buffer-read-only nil) - (erase-buffer) - ,@body - (setq buffer-read-only t) - (goto-char (point-min)) - (pop-to-buffer (current-buffer)))) - -(defmacro docker-utils-transient-define-prefix (name arglist &rest args) - "Wrapper around `transient-define-prefix' forwarding NAME, ARGLIST and ARGS and calling `docker-utils-ensure-items'." - `(transient-define-prefix ,name ,arglist - ,@args - (interactive) - (docker-utils-ensure-items) - (transient-setup ',name))) - -(defmacro docker-utils-define-transient-arguments (name) - "Define the transient arguments function using NAME that return the latest transient value or its default." - `(defun ,(intern (format "%s-arguments" name)) () - ,(format "Return the latest used arguments in the `%s' transient." name) - (let ((history (alist-get ',name transient-history)) - (default (transient-default-value (get ',name 'transient--prefix)))) - (if (equal 0 (length history)) - (car default) - (car history))))) - -(defmacro docker-utils-refresh-entries (promise) - "Update the current buffer with the results of PROMISE." - `(let ((buffer (current-buffer)) - (entries (aio-await ,promise))) - (with-current-buffer buffer - (setq tabulated-list-entries entries) - (tabulated-list-print t)))) - -(defvar docker-pop-to-buffer-action nil - "Action to use internally when `docker-utils-pop-to-buffer' calls `pop-to-buffer'.") - -(defun docker-utils-pop-to-buffer (name) - "Like `pop-to-buffer', but suffix NAME with the host if on a remote host." - (pop-to-buffer - (if (file-remote-p default-directory) - (with-parsed-tramp-file-name default-directory nil (concat name " - " host)) - name) - docker-pop-to-buffer-action)) - -(defun docker-utils-unit-multiplier (str) - "Return the correct multiplier for STR." - (expt 1024 (-elem-index (upcase str) '("B" "KB" "MB" "GB" "TB" "PB" "EB")))) - -(defun docker-utils-human-size-to-bytes (str) - "Parse STR and return size in bytes." - (let* ((parts (s-match "^\\([0-9\\.]+\\)\\([A-Z]+\\)?$" str)) - (value (string-to-number (-second-item parts))) - (multiplier (docker-utils-unit-multiplier (-third-item parts)))) - (* value multiplier))) - -(defun docker-utils-human-size-predicate (a b) - "Sort A and B by image size." - (< (docker-utils-human-size-to-bytes a) (docker-utils-human-size-to-bytes b))) - -(defun docker-utils-columns-list-format (columns-spec) - "Convert COLUMNS-SPEC (a list of plists) to 'tabulated-list-format', i.e. a vector of (name width sort-fn)." - (apply 'vector - (--map-indexed - (-let* (((&plist :name name :width width :sort sort-fn-inner) it) - (sort-fn (if sort-fn-inner - (let ((idx it-index)) ;; Rebind the closure var! - ;; Sort fn is called with (id [entries..]) - ;; Extract the column value and pass to inner function - (-on sort-fn-inner (lambda (x) (elt (cadr x) idx)))) - t))) - (list name width sort-fn)) - columns-spec))) - -(defun docker-utils-make-format-string (id-template column-spec) - "Make the format string to pass to docker-ls commands. - -ID-TEMPLATE is the Go template used to extract the property that -identifies the object (usually its id). -COLUMN-SPEC is the value of docker-X-columns." - (let* ((templates (--map (plist-get it :template) column-spec)) - (delimited (string-join templates ","))) - (format "[%s,%s]" id-template delimited))) - -(defun docker-utils-parse (column-specs line) - "Convert a LINE from \"docker ls\" to a `tabulated-list-entries' entry. - -LINE is expected to be a JSON formatted array, and COLUMN-SPECS is the relevant -defcustom (e.g. `docker-image-columns`) used to apply any custom format functions." - (condition-case nil - (let* ((data (json-read-from-string line))) - ;; apply format function, if any - (--each-indexed - column-specs - (let ((fmt-fn (plist-get it :format)) - (data-index (+ it-index 1))) - (when fmt-fn (aset data data-index (apply fmt-fn (list (aref data data-index))))))) - - (list (aref data 0) (seq-drop data 1))) - (json-readtable-error - (error "Could not read following string as json:\n%s" line)))) - -(defun docker-utils-columns-setter (sym new-value) - "Convert NEW-VALUE into a list of plists, then assign to SYM. - -If NEW-VALUE already looks like a list of plists, no conversion is performed and - NEW-VALUE is assigned to SYM unchanged. This is expected to be used as the -value of :set in a defcustom." - (let ((is-plist (plist-member (car new-value) :name)) - (new-value-plist (--map - (-interleave '(:name :width :template :sort :format) it) - new-value))) - (set sym (if is-plist new-value new-value-plist)))) - -(defun docker-utils-columns-getter (sym) - "Convert the value of SYM for displaying in the customization menu. - -Just strips the plist symbols and returns only values. -This has no effect on the actual value of the variable." - (--map - (-map (-partial #'plist-get it) '(:name :width :template :sort :format)) - (symbol-value sym))) - -(defun docker-utils-package-p (package) - "Check if PACKAGE is available." - (or (featurep package) - (ignore-errors (require package)))) - -(provide 'docker-utils) - -;;; docker-utils.el ends here diff --git a/elpa/docker-20251028.1026/docker-volume.el b/elpa/docker-20251028.1026/docker-volume.el deleted file mode 100644 index 27887364..00000000 --- a/elpa/docker-20251028.1026/docker-volume.el +++ /dev/null @@ -1,222 +0,0 @@ -;;; docker-volume.el --- Interface to docker-volume -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 's) -(require 'aio) -(require 'dash) -(require 'json) -(require 'tablist) -(require 'transient) - -(require 'docker-core) -(require 'docker-faces) -(require 'docker-utils) - -(defgroup docker-volume nil - "Docker volume customization group." - :group 'docker) - -(defconst docker-volume-id-template - "{{ json .Name }}" - "This Go template extracts the volume id which will be passed to transient commands.") - -(defcustom docker-volume-default-sort-key '("Driver" . nil) - "Sort key for docker volumes. - -This should be a cons cell (NAME . FLIP) where -NAME is a string matching one of the column names -and FLIP is a boolean to specify the sort order." - :group 'docker-volume - :type '(cons (string :tag "Column Name" - :validate (lambda (widget) - (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-volume-columns) - (widget-put widget :error "Default Sort Key must match a column name") - widget))) - (choice (const :tag "Ascending" nil) - (const :tag "Descending" t)))) - -(defcustom docker-volume-columns - '((:name "Driver" :width 10 :template "{{ json .Driver }}" :sort nil :format nil) - (:name "Name" :width 40 :template "{{ json .Name }}" :sort nil :format nil)) - "Column specification for docker volumes. - -The order of entries defines the displayed column order. -'Template' is the Go template passed to `docker-volume-ls' to create the column -data. It should return a string delimited with double quotes. -'Sort function' is a binary predicate that should return true when the first -argument should be sorted before the second. -'Format function' is a function from string to string that transforms the -displayed values in the column." - :group 'docker-volume - :set 'docker-utils-columns-setter - :get 'docker-utils-columns-getter - :type '(repeat (list :tag "Column" - (string :tag "Name") - (integer :tag "Width") - (string :tag "Template") - (sexp :tag "Sort function") - (sexp :tag "Format function")))) - -(defalias 'docker-volume-inspect 'docker-inspect) - -(aio-defun docker-volume-entries (&rest args) - "Return the docker volumes data for `tabulated-list-entries'." - (let* ((fmt (docker-utils-make-format-string docker-volume-id-template docker-volume-columns)) - (data (aio-await (docker-run-docker-async "volume" "ls" args (format "--format=\"%s\"" fmt)))) - (lines (s-split "\n" data t))) - (-map (-partial #'docker-utils-parse docker-volume-columns) lines))) - -(aio-defun docker-volume-entries-propertized (&rest args) - "Return the propertized docker volumes data for `tabulated-list-entries'." - (let ((entries (aio-await (docker-volume-entries args))) - (dangling (aio-await (docker-volume-entries args "--filter dangling=true")))) - (--map-when (-contains? dangling it) (docker-volume-entry-set-dangling it) entries))) - -(defun docker-volume-dangling-p (entry-id) - "Predicate for if ENTRY-ID is dangling. - -For example (docker-volume-dangling-p (tabulated-list-get-id)) is t when the entry under point is dangling." - (get-text-property 0 'docker-volume-dangling entry-id)) - -(defun docker-volume-entry-set-dangling (entry) - "Mark ENTRY (output of `docker-volume-entries') as dangling. - -The result is the tabulated list id for an entry is propertized with -'docker-volume-dangling and the entry is fontified with 'docker-face-dangling." - (list (propertize (car entry) 'docker-volume-dangling t) - (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-dangling) (cadr entry))))) - -(aio-defun docker-volume-update-status-async () - "Write the status to `docker-status-strings'." - (plist-put docker-status-strings :volumes "Volumes") - (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) - (let* ((entries (aio-await (docker-volume-entries-propertized (docker-volume-ls-arguments)))) - (dangling (--filter (docker-volume-dangling-p (car it)) entries))) - (plist-put docker-status-strings - :volumes - (format "Volumes (%s total, %s dangling)" - (number-to-string (length entries)) - (propertize (number-to-string (length dangling)) 'face 'docker-face-dangling))) - (transient--redisplay)))) - -(add-hook 'docker-open-hook #'docker-volume-update-status-async) - -(aio-defun docker-volume-refresh () - "Refresh the volumes list." - (docker-utils-refresh-entries - (docker-volume-entries-propertized (docker-volume-ls-arguments)))) - -(defun docker-volume-read-name () - "Read a volume name." - (completing-read "Volume: " (-map #'car (aio-wait-for (docker-volume-entries))))) - -;;;###autoload (autoload 'docker-volume-dired "docker-volume" nil t) -(aio-defun docker-volume-dired (name) - "Enter `dired' in the volume named NAME." - (interactive (list (docker-volume-read-name))) - (let ((path (s-trim-right (aio-await (docker-run-docker-async "inspect" "-f" "\"{{ .Mountpoint }}\"" name))))) - (dired (format "/sudo::%s" path)))) - -(defun docker-volume-dired-selection () - "Run `docker-volume-dired' on the volumes selection." - (interactive) - (docker-utils-ensure-items) - (--each (docker-utils-get-marked-items-ids) - (docker-volume-dired it))) - -(defun docker-volume-mark-dangling () - "Mark only the dangling volumes listed in *docker-volumes*. - -This clears any user marks first and respects any tablist filters -applied to the buffer." - (interactive) - (switch-to-buffer "*docker-volumes*") - (tablist-unmark-all-marks) - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (when (docker-volume-dangling-p (tabulated-list-get-id)) - (tablist-put-mark)) - (forward-line)))) - -(docker-utils-define-transient-arguments docker-volume-ls) - -(transient-define-prefix docker-volume-ls () - "Transient for listing volumes." - :man-page "docker-volume-ls" - ["Arguments" - ("d" "Dangling" "--filter dangling=true") - ("f" "Filter" "--filter " read-string)] - ["Actions" - ("l" "List" tablist-revert)]) - -(docker-utils-transient-define-prefix docker-volume-rm () - "Transient for removing volumes." - :man-page "docker-volume-rm" - [:description docker-generic-action-description - ("D" "Remove" docker-generic-action-multiple-ids)]) - -(transient-define-prefix docker-volume-help () - "Help transient for docker volumes." - ["Docker volumes help" - ("D" "Remove" docker-volume-rm) - ("I" "Inspect" docker-volume-inspect) - ("d" "Mark Dangling" docker-volume-mark-dangling) - ("f" "Dired" docker-volume-dired-selection) - ("l" "List" docker-volume-ls)]) - -(defvar docker-volume-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "?" 'docker-volume-help) - (define-key map "D" 'docker-volume-rm) - (define-key map "I" 'docker-volume-inspect) - (define-key map "d" 'docker-volume-mark-dangling) - (define-key map "f" 'docker-volume-dired-selection) - (define-key map "l" 'docker-volume-ls) - map) - "Keymap for `docker-volume-mode'.") - -;;;###autoload (autoload 'docker-volumes "docker-volume" nil t) -(defun docker-volumes () - "List docker volumes." - (interactive) - (docker-utils-pop-to-buffer "*docker-volumes*") - (docker-volume-mode) - (tablist-revert)) - -(define-derived-mode docker-volume-mode tabulated-list-mode "Volumes Menu" - "Major mode for handling a list of docker volumes." - (setq tabulated-list-format (docker-utils-columns-list-format docker-volume-columns)) - (setq tabulated-list-padding 2) - (setq tabulated-list-sort-key docker-volume-default-sort-key) - (add-hook 'tabulated-list-revert-hook 'docker-volume-refresh nil t) - (tabulated-list-init-header) - (tablist-minor-mode)) - -(provide 'docker-volume) - -;;; docker-volume.el ends here diff --git a/elpa/docker-20251028.1026/docker.el b/elpa/docker-20251028.1026/docker.el deleted file mode 100644 index ad9ec741..00000000 --- a/elpa/docker-20251028.1026/docker.el +++ /dev/null @@ -1,44 +0,0 @@ -;;; docker.el --- Interface to Docker -*- lexical-binding: t -*- - -;; Author: Philippe Vaucher -;; URL: https://github.com/Silex/docker.el -;; Keywords: filename, convenience -;; Package-Version: 20251028.1026 -;; Package-Revision: 375e0ed45bb1 -;; Package-Requires: ((aio "1.0") (dash "2.19.1") (emacs "28.1") (s "1.13.0") (tablist "1.1") (transient "0.4.3")) - -;; This file is NOT part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;; This package allows you to manipulate docker images, containers & more from Emacs. - -;;; Code: -(eval-when-compile - (setq-local byte-compile-warnings '(not docstrings))) - -(require 'docker-compose) -(require 'docker-container) -(require 'docker-image) -(require 'docker-network) -(require 'docker-volume) -(require 'docker-context) - -(provide 'docker) - -;;; docker.el ends here diff --git a/elpa/docker-20260126.1212/README-elpa b/elpa/docker-20260126.1212/README-elpa new file mode 100644 index 00000000..55901186 --- /dev/null +++ b/elpa/docker-20260126.1212/README-elpa @@ -0,0 +1 @@ +This package allows you to manipulate docker images, containers & more from Emacs. diff --git a/elpa/docker-20260126.1212/docker-autoloads.el b/elpa/docker-20260126.1212/docker-autoloads.el new file mode 100644 index 00000000..1375b084 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-autoloads.el @@ -0,0 +1,86 @@ +;;; docker-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*- +;; Generated by the `loaddefs-generate' function. + +;; This file is part of GNU Emacs. + +;;; Code: + +(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path))) + + + +;;; Generated autoloads from docker-compose.el + + (autoload 'docker-compose "docker-compose" nil t) +(register-definition-prefixes "docker-compose" '("docker-compose-")) + + +;;; Generated autoloads from docker-container.el + + (autoload 'docker-container-eshell "docker-container" nil t) + (autoload 'docker-container-find-directory "docker-container" nil t) + (autoload 'docker-container-find-file "docker-container" nil t) + (autoload 'docker-container-shell "docker-container" nil t) + (autoload 'docker-container-shell-env "docker-container" nil t) + (autoload 'docker-container-vterm "docker-container" nil t) + (autoload 'docker-container-vterm-env "docker-container" nil t) + (autoload 'docker-container-eat "docker-container" nil t) + (autoload 'docker-container-eat-env "docker-container" nil t) + (autoload 'docker-containers "docker-container" nil t) +(register-definition-prefixes "docker-container" '("docker-container-")) + + +;;; Generated autoloads from docker-context.el + + (autoload 'docker-contexts "docker-context" nil t) +(register-definition-prefixes "docker-context" '("docker-context-")) + + +;;; Generated autoloads from docker-core.el + + (autoload 'docker "docker" nil t) +(register-definition-prefixes "docker-core" '("docker-")) + + +;;; Generated autoloads from docker-image.el + + (autoload 'docker-image-pull-one "docker-image" nil t) + (autoload 'docker-images "docker-image" nil t) +(register-definition-prefixes "docker-image" '("docker-")) + + +;;; Generated autoloads from docker-network.el + + (autoload 'docker-networks "docker-network" nil t) +(register-definition-prefixes "docker-network" '("docker-network-")) + + +;;; Generated autoloads from docker-process.el + +(register-definition-prefixes "docker-process" '("docker-")) + + +;;; Generated autoloads from docker-utils.el + +(register-definition-prefixes "docker-utils" '("docker-")) + + +;;; Generated autoloads from docker-volume.el + + (autoload 'docker-volume-dired "docker-volume" nil t) + (autoload 'docker-volumes "docker-volume" nil t) +(register-definition-prefixes "docker-volume" '("docker-volume-")) + +;;; End of scraped data + +(provide 'docker-autoloads) + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; no-native-compile: t +;; coding: utf-8-emacs-unix +;; End: + +;;; docker-autoloads.el ends here diff --git a/elpa/docker-20260126.1212/docker-compose.el b/elpa/docker-20260126.1212/docker-compose.el new file mode 100644 index 00000000..dd2e42b5 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-compose.el @@ -0,0 +1,339 @@ +;;; docker-compose.el --- Interface to docker-compose -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) +(require 'transient) + +(require 'docker-group) +(require 'docker-utils) +(require 'docker-process) + +(defgroup docker-compose nil + "Docker compose customization group." + :group 'docker) + +(defcustom docker-compose-command "docker compose" + "The `docker-compose' binary." + :group 'docker-compose + :type 'string) + +(defun docker-compose-run-docker-compose-async (action &rest args) + "Execute \"`docker-compose-command' ACTION ARGS\" and return a promise with the results." + (apply #'docker-run-async docker-compose-command (docker-compose-arguments) action args)) + +(defun docker-compose-run-docker-compose-async-with-buffer (action &rest args) + "Execute \"`docker-compose-command' ACTION ARGS\" and display output in a new buffer." + (apply #'docker-run-async-with-buffer-interactive docker-compose-command (docker-compose-arguments) action args)) + +(aio-defun docker-compose-services () + "Return the list of services." + (s-split "\n" (aio-await (docker-compose-run-docker-compose-async "config" "--services" "2>/dev/null")) t)) + +(aio-defun docker-compose-read-services-names () + "Read the services names." + (completing-read-multiple "Services: " (aio-await (docker-compose-services)))) + +(aio-defun docker-compose-read-service-name () + "Read one service name." + (completing-read "Service: " (aio-await (docker-compose-services)))) + +(defun docker-compose-read-project (prompt &rest _args) + "Read the `docker-compose' project forwarding PROMPT." + (completing-read + prompt + ;; in docker compose v2, we can obtain the list of + ;; projects with 'ls' argument + (if (string-match-p "\\bdocker\\s-+compose\\b" docker-compose-command) + (split-string + (shell-command-to-string + (concat docker-compose-command " ls" " --all" " -q")) + "\n" + t)))) + +(defun docker-compose-read-log-level (prompt &rest _args) + "Read the `docker-compose' log level forwarding PROMPT." + (completing-read prompt '(DEBUG INFO WARNING ERROR CRITICAL))) + +(defun docker-compose-read-directory (prompt &optional initial-input _history) + "Wrapper around `read-directory-name' forwarding PROMPT and INITIAL-INPUT." + (read-directory-name prompt nil nil t initial-input)) + +(defun docker-compose-read-environment-file (prompt &optional initial-input _history) + "Wrapper around `read-file-name' forwarding PROMPT and INITIAL-INPUT." + (read-file-name prompt nil nil t initial-input)) + +(defun docker-compose-read-compose-file (prompt &optional initial-input _history) + "Wrapper around `read-file-name' forwarding PROMPT and INITIAL-INPUT." + (read-file-name prompt nil nil t initial-input (apply-partially 'string-match ".*\\.yml\\|.*\\.yaml"))) + +(aio-defun docker-compose-run-action-for-one-service (action args services) + "Run \"docker-compose ACTION ARGS SERVICES\"." + (interactive (list + (-last-item (s-split "-" (symbol-name transient-current-command))) + (transient-args transient-current-command) + nil)) + (setq services (aio-await (docker-compose-read-services-names))) + (docker-compose-run-docker-compose-async-with-buffer action args services)) + +(defun docker-compose-run-action-for-all-services (action args) + "Run \"docker-compose ACTION ARGS\"." + (interactive (list + (-last-item (s-split "-" (symbol-name transient-current-command))) + (transient-args transient-current-command))) + (docker-compose-run-docker-compose-async-with-buffer action args)) + +(aio-defun docker-compose-run-action-with-command (action args service command) + "Run \"docker-compose ACTION ARGS SERVICE COMMAND\"." + (interactive (list + (-last-item (s-split "-" (symbol-name transient-current-command))) + (transient-args transient-current-command) + nil + (read-string "Command: "))) + (setq service (aio-await (docker-compose-read-service-name))) + (docker-compose-run-docker-compose-async-with-buffer action args service command)) + +(transient-define-prefix docker-compose-build () + "Transient for \"docker-compose build\"." + :man-page "docker-compose build" + ["Arguments" + ("b" "Build argument" "--build-arg " read-string) + ("c" "Compress build context" "--compress") + ("f" "Always remove intermediate containers" "--force-rm") + ("m" "Memory limit" "--memory " transient-read-number-N0) + ("n" "Do not use cache" "--no-cache") + ("p" "Attempt to pull a newer version of the image" "--pull") + ("r" "Build images in parallel" "--parallel")] + ["Actions" + ("B" "Build" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-config () + "Transient for \"docker-compose config\"." + :man-page "docker-compose config" + ["Arguments" + + ("r" "Pin image tags to digests" "--resolve-image-digests") + ("s" "Print the service names" "--services") + ("v" "Print the volume names" "--volumes")] + ["Actions" + ("V" "Config" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-create () + "Transient for \"docker-compose create\"." + :man-page "docker-compose create" + ["Arguments" + ("b" "Build" "--build") + ("f" "Force recreate" "--force-recreate") + ("n" "No recreate" "--no-recreate")] + ["Actions" + ("C" "Create" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-down () + "Transient for \"docker-compose down\"." + :man-page "docker-compose down" + ["Arguments" + ("o" "Remove orphans" "--remove-orphans") + ("t" "Timeout" "--timeout " transient-read-number-N0) + ("v" "Remove volumes" "--volumes")] + ["Actions" + ("W" "Down" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-exec () + "Transient for \"docker-compose exec\"." + :man-page "docker-compose exec" + ["Arguments" + ("P" "Privileged" "--privileged") + ("T" "Disable pseudo-tty" "-T") + ("d" "Detach" "-d") + ("e" "Env KEY=VAL" "-e " read-string) + ("u" "User " "--user " read-string) + ("w" "Workdir" "--workdir " read-string)] + ["Actions" + ("E" "Exec" docker-compose-run-action-with-command)]) + +(transient-define-prefix docker-compose-logs () + "Transient for \"docker-compose logs\"." + :man-page "docker-compose logs" + ["Arguments" + ("T" "Tail" "--tail " read-string) + ("f" "Follow" "--follow") + ("n" "No color" "--no-color") + ("t" "Timestamps" "--timestamps")] + ["Actions" + ("L" "Logs" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-pull () + "Transient for \"docker-compose pull\"." + :man-page "docker-compose pull" + ["Arguments" + ("d" "Include dependencies" "--include-deps") + ("i" "Ignore pull failures" "--ignore-pull-failures") + ("n" "No parallel" "--no-parallel")] + ["Actions" + ("F" "Pull" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-push () + "Transient for \"docker-compose push\"." + :man-page "docker-compose push" + ["Arguments" + ("i" "Ignore push failures" "--ignore-push-failures")] + ["Actions" + ("P" "Push" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-restart () + "Transient for \"docker-compose restart\"." + :man-page "docker-compose restart" + ["Arguments" + ("t" "Timeout" "--timeout " transient-read-number-N0)] + ["Actions" + ("T" "Restart" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-rm () + "Transient for \"docker-compose rm\"." + :man-page "docker-compose rm" + ["Arguments" + ("f" "Force" "--force") + ("s" "Stop" "--stop") + ("v" "Remove anonymous volumes" "-v")] + ["Actions" + ("D" "Remove" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-run () + "Transient for \"docker-compose run\"." + :man-page "docker-compose run" + :value '("--rm") + ["Arguments" + ("E" "Entrypoint" "--entrypoint " read-string) + ("N" "Name" "--name " read-string) + ("T" "Disable pseudo-tty" "-T") + ("d" "Detach" "-d") + ("e" "Env KEY=VAL" "-e " read-string) + ("l" "Label" "--label " read-string) + ("n" "No deps" "--no-deps") + ("r" "Remove container when it exits" "--rm") + ("s" "Enable services ports" "--service-ports") + ("u" "User " "--user " read-string) + ("w" "Workdir" "--workdir " read-string)] + ["Actions" + ("R" "Run" docker-compose-run-action-with-command)]) + +(transient-define-prefix docker-compose-start () + "Transient for \"docker-compose start\"." + :man-page "docker-compose start" + ["Actions" + ("S" "Start" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-stop () + "Transient for \"docker-compose stop\"." + :man-page "docker-compose stop" + ["Arguments" + ("t" "Timeout" "--timeout " transient-read-number-N0)] + ["Actions" + ("O" "Stop" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-up () + "Transient for \"docker-compose up\"." + :man-page "docker-compose up" + ["Arguments" + ("b" "Build" "--build") + ("c" "Scale" "--scale " transient-read-number-N0) + ("d" "Detach" "-d") + ("f" "Force recreate" "--force-recreate") + ("n" "No deps" "--no-deps") + ("q" "Quiet pull" "--quiet-pull") + ("r" "Remove orphans" "--remove-orphans") + ("t" "Timeout" "--timeout " transient-read-number-N0)] + ["Actions" + ("U" "Up" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-pause () + "Transient for \"docker-compose pause\"." + :man-page "docker-compose pause" + ["Actions" + ("Z" "Pause" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(transient-define-prefix docker-compose-unpause () + "Transient for \"docker-compose unpause\"." + :man-page "docker-compose unpause" + ["Actions" + ("N" "Unpause" docker-compose-run-action-for-one-service) + ("A" "All services" docker-compose-run-action-for-all-services)]) + +(docker-utils-define-transient-arguments docker-compose) + +;;;###autoload (autoload 'docker-compose "docker-compose" nil t) +(transient-define-prefix docker-compose () + "Transient for docker-compose." + :man-page "docker-compose" + ["Arguments" + ("a" "No ANSI" "--no-ansi") + ("c" "Compatibility" "--compatibility") + ("d" "Project directory" "--project-directory " docker-compose-read-directory) + ("e" "Environment file" "--env-file " docker-compose-read-environment-file) + ("f" "Compose file" "--file " docker-compose-read-compose-file) + ("h" "Host" "--host " read-string) + ("l" "Log level" "--log-level " docker-compose-read-log-level) + ("p" "Project name" "--project-name " docker-compose-read-project) + ("r" "Profile" "--profile " read-string) + ("v" "Verbose" "--verbose")] + [["Images" + ("B" "Build" docker-compose-build) + ("F" "Pull" docker-compose-pull) + ("P" "Push" docker-compose-push)] + ["Containers" + ("C" "Create" docker-compose-create) + ("D" "Remove" docker-compose-rm) + ("Z" "Pause" docker-compose-pause) + ("N" "Unpause" docker-compose-unpause) + ("U" "Up" docker-compose-up) + ("W" "Down" docker-compose-down)] + ["State" + ("O" "Stop" docker-compose-stop) + ("S" "Start" docker-compose-start) + ("T" "Restart" docker-compose-restart)] + ["Other" + ("E" "Exec" docker-compose-exec) + ("L" "Logs" docker-compose-logs) + ("R" "Run" docker-compose-run) + ("V" "Config" docker-compose-config)]]) + +(provide 'docker-compose) + +;;; docker-compose.el ends here diff --git a/elpa/docker-20260126.1212/docker-container.el b/elpa/docker-20260126.1212/docker-container.el new file mode 100644 index 00000000..c7cd9560 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-container.el @@ -0,0 +1,617 @@ +;;; docker-container.el --- Interface to docker-container -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher +;; Yuki Inoue + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) +(require 'json) +(require 'tablist) +(require 'transient) + +(require 'docker-core) +(require 'docker-faces) +(require 'docker-utils) + +(defgroup docker-container nil + "Docker container customization group." + :group 'docker) + +(defconst docker-container-id-template + "{{ json .Names }}" + "This Go template extracts the container id which will be passed to transient commands.") + +(defcustom docker-container-shell-file-name "/bin/sh" + "Shell to use when entering containers." + :group 'docker-container + :type 'string) + +(defcustom docker-container-tramp-method "docker" + "TRAMP method to use for connecting to Docker containers." + :group 'docker-container + :type 'string) + +(defcustom docker-container-default-sort-key '("Image" . nil) + "Sort key for docker containers. + +This should be a cons cell (NAME . FLIP) where +NAME is a string matching one of the column names +and FLIP is a boolean to specify the sort order." + :group 'docker-container + :type '(cons (string :tag "Column Name" + :validate (lambda (widget) + (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-container-columns) + (widget-put widget :error "Default Sort Key must match a column name") + widget))) + (choice (const :tag "Ascending" nil) + (const :tag "Descending" t)))) + +(defcustom docker-container-columns + '((:name "Id" :width 16 :template "{{ json .ID }}" :sort nil :format nil) + (:name "Image" :width 15 :template "{{ json .Image }}" :sort nil :format nil) + (:name "Command" :width 30 :template "{{ json .Command }}" :sort nil :format nil) + (:name "Created" :width 23 :template "{{ json .CreatedAt }}" :sort nil :format (lambda (x) (format-time-string "%F %T" (date-to-time x)))) + (:name "Status" :width 20 :template "{{ json .Status }}" :sort nil :format nil) + (:name "Ports" :width 10 :template "{{ json .Ports }}" :sort nil :format nil) + (:name "Names" :width 10 :template "{{ json .Names }}" :sort nil :format nil)) + "Column specification for docker containers. + +The order of entries defines the displayed column order. 'Template' is +the Go template passed to `docker-container-ls' to create the column data. +It should return a string delimited with double quotes. 'Sort function' is +a binary predicate that should return true when the first argument should be +sorted before the second. 'Format function' is a function from string to +string that transforms the displayed values in the column." + :group 'docker-container + :set 'docker-utils-columns-setter + :get 'docker-utils-columns-getter + :type '(repeat (list :tag "Column" + (string :tag "Name") + (integer :tag "Width") + (string :tag "Template") + (sexp :tag "Sort function") + (sexp :tag "Format function")))) + +(defalias 'docker-container-inspect 'docker-inspect) + +(defun docker-container--read-shell (&optional read-shell-name) + "Return `docker-container-shell-file-name' or read a shell name if READ-SHELL-NAME is truthy." + (if read-shell-name (read-shell-command "Shell: ") docker-container-shell-file-name)) + +(defun docker-container-status-face (status) + "Return the correct face according to STATUS." + (cond + ((s-starts-with? "Up" status) + 'docker-face-status-up) + ((s-starts-with? "Exited" status) + 'docker-face-status-down) + (t + 'docker-face-status-other))) + +(aio-defun docker-container-entries (&rest args) + "Return the docker containers data for `tabulated-list-entries'." + (let* ((fmt (docker-utils-make-format-string docker-container-id-template docker-container-columns)) + (data (aio-await (docker-run-docker-async "container" "ls" args (format "--format=\"%s\"" fmt)))) + (lines (s-split "\n" data t))) + (-map (-partial #'docker-utils-parse docker-container-columns) lines))) + +(aio-defun docker-container-entries-propertized (&rest args) + "Return the propertized docker containers data for `tabulated-list-entries'." + (let ((entries (aio-await (docker-container-entries args)))) + (-map #'docker-container-propertize-entry entries))) + +(defun docker-container-propertize-entry (entry) + "Propertize ENTRY." + (let* ((index (--find-index (string-equal "Status" (plist-get it :name)) docker-container-columns)) + (data (cadr entry)) + (status (aref data index))) + (aset data index (propertize status 'font-lock-face (docker-container-status-face status))) + entry)) + +(aio-defun docker-container-update-status-async () + "Write the status to `docker-status-strings'." + (plist-put docker-status-strings :containers "Containers") + (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) + (let* ((entries (aio-await (docker-container-entries-propertized (docker-container-ls-arguments)))) + (index (--find-index (string-equal "Status" (plist-get it :name)) docker-container-columns)) + (statuses (--map (aref (cadr it) index) entries)) + (faces (--map (get-text-property 0 'font-lock-face it) statuses)) + (all (length faces)) + (up (-count (-partial #'equal 'docker-face-status-up) faces)) + (down (-count (-partial #'equal 'docker-face-status-down) faces)) + (other (- all up down))) + (plist-put docker-status-strings + :containers + (format "Containers (%s total, %s up, %s down, %s other)" + all + (propertize (number-to-string up) 'face 'docker-face-status-up) + (propertize (number-to-string down) 'face 'docker-face-status-down) + (propertize (number-to-string other) 'face 'docker-face-status-other))) + (transient--redisplay)))) + +(add-hook 'docker-open-hook #'docker-container-update-status-async) + +(aio-defun docker-container-refresh () + "Refresh the containers list." + (docker-utils-refresh-entries + (docker-container-entries-propertized (docker-container-ls-arguments)))) + +(defun docker-container-read-name () + "Read an container name." + (completing-read "Container: " (-map #'car (aio-wait-for (docker-container-entries))))) + +(defvar eshell-buffer-name) + +;;;###autoload (autoload 'docker-container-eshell "docker-container" nil t) +(defun docker-container-eshell (container) + "Open `eshell' in CONTAINER." + (interactive (list (docker-container-read-name))) + (let* ((container-address (format "%s:%s:/" docker-container-tramp-method container)) + (file-prefix (let ((prefix (file-remote-p default-directory))) + (if prefix + (format "%s|" (s-chop-suffix ":" prefix)) + "/"))) + (default-directory (format "%s%s" file-prefix container-address)) + (eshell-buffer-name (docker-utils-generate-new-buffer-name "docker" "eshell:" default-directory))) + (eshell))) + +(defun docker-container-assert-tramp-docker () + "Assert tramp docker support is available." + (unless (or (assoc docker-container-tramp-method tramp-methods) + (docker-utils-package-p 'docker-tramp)) + (error "Tramp docker support was not detected, try installing docker-tramp"))) + +;;;###autoload (autoload 'docker-container-find-directory "docker-container" nil t) +(defun docker-container-find-directory (container directory) + "Inside CONTAINER open DIRECTORY." + (interactive + (let* ((container-name (docker-container-read-name)) + (tramp-filename (read-directory-name "Directory: " (format "/%s:%s:/" docker-container-tramp-method container-name)))) + (with-parsed-tramp-file-name tramp-filename nil + (list host localname)))) + (docker-container-assert-tramp-docker) + (dired (format "/%s:%s:%s" docker-container-tramp-method container directory))) + +(defalias 'docker-container-dired 'docker-container-find-directory) + +;;;###autoload (autoload 'docker-container-find-file "docker-container" nil t) +(defun docker-container-find-file (container file) + "Open FILE inside CONTAINER." + (interactive + (let* ((container-name (docker-container-read-name)) + (tramp-filename (read-file-name "File: " (format "/%s:%s:/" docker-container-tramp-method container-name)))) + (with-parsed-tramp-file-name tramp-filename nil + (list host localname)))) + (docker-container-assert-tramp-docker) + (find-file (format "/%s:%s:%s" docker-container-tramp-method container file))) + +;;;###autoload (autoload 'docker-container-shell "docker-container" nil t) +(defun docker-container-shell (container &optional read-shell) + "Open `shell' in CONTAINER. When READ-SHELL is not nil, ask the user for it." + (interactive (list + (docker-container-read-name) + current-prefix-arg)) + (let* ((shell-file-name (docker-container--read-shell read-shell)) + (container-address (format "%s:%s:/" docker-container-tramp-method container)) + (file-prefix (let ((prefix (file-remote-p default-directory))) + (if prefix + (format "%s|" (s-chop-suffix ":" prefix)) + "/"))) + (default-directory (format "%s%s" file-prefix container-address))) + (shell (docker-utils-generate-new-buffer "docker" "shell:" default-directory)))) + +;;;###autoload (autoload 'docker-container-shell-env "docker-container" nil t) +(aio-defun docker-container-shell-env (container &optional read-shell) + "Open `shell' in CONTAINER with the environment variable set +and default directory set to workdir. When READ-SHELL is not +nil, ask the user for it." + (interactive (list + (docker-container-read-name) + current-prefix-arg)) + (docker-container-assert-tramp-docker) + (let* ((shell-file-name (docker-container--read-shell read-shell)) + (container-address (format "%s:%s:" docker-container-tramp-method container)) + (file-prefix (let ((prefix (file-remote-p default-directory))) + (if prefix + (format "%s|" (s-chop-suffix ":" prefix)) + "/"))) + (container-config (cdr (assq 'Config (aref (json-read-from-string (aio-await (docker-run-docker-async "inspect" container))) 0)))) + (container-workdir (cdr (assq 'WorkingDir container-config))) + (container-env (cdr (assq 'Env container-config))) + (default-directory (format "%s%s%s" file-prefix container-address container-workdir)) + ;; process-environment doesn't work with tramp if you call this function more than one per emacs session + (tramp-remote-process-environment (append container-env nil))) + (shell (docker-utils-generate-new-buffer "docker" "shell-env:" default-directory)))) + +;;;###autoload (autoload 'docker-container-vterm "docker-container" nil t) +(defun docker-container-vterm (container) + "Open `vterm' in CONTAINER." + (interactive (list (docker-container-read-name))) + (if (fboundp 'vterm-other-window) + (let* ((container-address (format "%s:%s:/" docker-container-tramp-method container)) + (file-prefix (let ((prefix (file-remote-p default-directory))) + (if prefix + (format "%s|" (s-chop-suffix ":" prefix)) + "/"))) + (default-directory (format "%s%s" file-prefix container-address))) + (vterm-other-window (docker-utils-generate-new-buffer-name "docker" "vterm:" default-directory))) + (error "The vterm package is not installed"))) + +;;;###autoload (autoload 'docker-container-vterm-env "docker-container" nil t) +(aio-defun docker-container-vterm-env (container) + "Open `vterm' in CONTAINER with the environment variable set and +default directory set to workdir." + (interactive (list + (docker-container-read-name))) + (docker-container-assert-tramp-docker) + (let* ((container-address (format "%s:%s:" docker-container-tramp-method container)) + (file-prefix (let ((prefix (file-remote-p default-directory))) + (if prefix + (format "%s|" (s-chop-suffix ":" prefix)) + "/"))) + (container-config (cdr (assq 'Config (aref (json-read-from-string (aio-await (docker-run-docker-async "inspect" container))) 0)))) + (container-workdir (cdr (assq 'WorkingDir container-config))) + (container-env (cdr (assq 'Env container-config))) + (default-directory (format "%s%s%s" file-prefix container-address container-workdir)) + ;; process-environment doesn't work with tramp if you call this function more than one per emacs session + (tramp-remote-process-environment (append container-env nil))) + (if (fboundp 'vterm-other-window) + (vterm-other-window (docker-utils-generate-new-buffer-name "docker" "vterm-env:" default-directory)) + (error "The vterm package is not installed")))) + +(defvar eat-buffer-name) + +;;;###autoload (autoload 'docker-container-eat "docker-container" nil t) +(defun docker-container-eat (container) + "Open `eat' in CONTAINER." + (interactive (list (docker-container-read-name))) + (if (fboundp 'eat-other-window) + (let* ((container-address (format "%s:%s:/" docker-container-tramp-method container)) + (file-prefix (let ((prefix (file-remote-p default-directory))) + (if prefix + (format "%s|" (s-chop-suffix ":" prefix)) + "/"))) + (default-directory (format "%s%s" file-prefix container-address)) + (eat-buffer-name (format "*eat:%s" default-directory))) + (eat-other-window)) + (error "The eat package is not installed"))) + +;;;###autoload (autoload 'docker-container-eat-env "docker-container" nil t) +(aio-defun docker-container-eat-env (container) + "Open `eat' in CONTAINER with the environment variable set and +default directory set to workdir." + (interactive (list + (docker-container-read-name))) + (docker-container-assert-tramp-docker) + (let* ((container-address (format "%s:%s:" docker-container-tramp-method container)) + (file-prefix (let ((prefix (file-remote-p default-directory))) + (if prefix + (format "%s|" (s-chop-suffix ":" prefix)) + "/"))) + (container-config (cdr (assq 'Config (aref (json-read-from-string (aio-await (docker-run-docker-async "inspect" container))) 0)))) + (container-workdir (cdr (assq 'WorkingDir container-config))) + (container-env (cdr (assq 'Env container-config))) + (default-directory (format "%s%s%s" file-prefix container-address container-workdir)) + ;; process-environment doesn't work with tramp if you call this function more than one per emacs session + (tramp-remote-process-environment (append container-env nil)) + (eat-buffer-name (format "*eat-env:%s" default-directory))) + (if (fboundp 'eat-other-window) + (eat-other-window) + (error "The eat package is not installed")))) + +(defun docker-container-cp-from-selection (container-path host-path) + "Run \"docker cp\" from CONTAINER-PATH to HOST-PATH for selected container." + (interactive "sContainer path: \nFHost path: ") + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-run-docker-async "cp" (concat it ":" container-path) host-path))) + +(defun docker-container-cp-to-selection (host-path container-path) + "Run \"docker cp\" from HOST-PATH to CONTAINER-PATH for selected containers." + (interactive "fHost path: \nsContainer path: ") + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-run-docker-async "cp" host-path (concat it ":" container-path)))) + +(defun docker-container-eshell-selection () + "Run `docker-container-eshell' on the containers selection." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-eshell it))) + +(defun docker-container-find-directory-selection (path) + "Run `docker-container-find-directory' for PATH on the containers selection." + (interactive "sPath: ") + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-find-directory it path))) + +(defun docker-container-find-file-selection (path) + "Run `docker-container-find-file' for PATH on the containers selection." + (interactive "sPath: ") + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-find-file it path))) + +(aio-defun docker-container-rename-selection () + "Rename containers." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (aio-await (docker-run-docker-async "rename" it (read-string (format "Rename \"%s\" to: " it))))) + (tablist-revert)) + +(defun docker-container-shell-selection (prefix) + "Run `docker-container-shell' on the containers selection forwarding PREFIX." + (interactive "P") + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-shell it prefix))) + +(defun docker-container-shell-env-selection (prefix) + "Run `docker-container-shell-env' on the containers selection forwarding PREFIX." + (interactive "P") + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-shell-env it prefix))) + +(defun docker-container-vterm-selection () + "Run `docker-container-vterm' on the containers selection." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-vterm it))) + +(defun docker-container-vterm-env-selection () + "Run `docker-container-vterm-env' on the containers selection." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-vterm-env it))) + +(defun docker-container-shell-command (container) + "Run exec of a CONTAINER." + (interactive (list (docker-container-read-name))) + (let* ((default-command (string-join (append (list docker-command) + (docker-arguments) + (list "exec" container)) + " ")) + (command (read-shell-command "Run: " default-command))) + (shell-command command))) + +(defun docker-container-shell-command-selection () + "Run `docker exec' on the containers selection." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-shell-command it))) + +(defun docker-container-eat-selection () + "Run `docker-container-eat' on the containers selection." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-eat it))) + +(defun docker-container-eat-env-selection () + "Run `docker-container-eat-env' on the containers selection." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-container-eat-env it))) + +(docker-utils-transient-define-prefix docker-container-attach () + "Transient for attaching to containers." + :man-page "docker-container-attach" + ["Arguments" + ("n" "No STDIN" "--no-stdin") + ("d" "Key sequence for detaching" "--detach-keys " read-string)] + [:description docker-generic-action-description + ("a" "Attach" docker-generic-action-with-buffer-interactive)]) + +(docker-utils-transient-define-prefix docker-container-cp () + "Transient for copying files from/to containers." + :man-page "docker-container-cp" + [:description docker-generic-action-description + ("f" "Copy From" docker-container-cp-from-selection) + ("t" "Copy To" docker-container-cp-to-selection)]) + +(docker-utils-transient-define-prefix docker-container-diff () + "Transient for showing containers diffs." + :man-page "docker-container-diff" + [:description docker-generic-action-description + ("d" "Diff" docker-generic-action-with-buffer)]) + +(docker-utils-transient-define-prefix docker-container-open () + "Transient for opening containers files." + [:description docker-generic-action-description + ("d" "Open directory" docker-container-find-directory-selection) + ("f" "Open file" docker-container-find-file-selection)]) + +(docker-utils-transient-define-prefix docker-container-kill () + "Transient for kill signaling containers" + :man-page "docker-container-kill" + ["Arguments" + ("s" "Signal" "-s " read-string)] + [:description docker-generic-action-description + ("K" "Kill" docker-generic-action-multiple-ids)]) + +(defun docker-container-logs-action (action args) + "Show container logs, streaming if -f flag is present, otherwise collect then display. +ACTION is the docker action, ARGS are the transient arguments." + (interactive (list (docker-get-transient-action) + (transient-args transient-current-command))) + (if (member "-f" args) + (docker-generic-action-with-buffer-noninteractive action args) + (aio-wait-for (docker-generic-action-with-buffer action args)))) + +(docker-utils-transient-define-prefix docker-container-logs () + "Transient for showing containers logs." + :man-page "docker-container-logs" + ["Arguments" + ("f" "Follow" "-f") + ("s" "Since" "--since " read-string) + ("t" "Tail" "--tail " read-string) + ("u" "Until" "--until " read-string)] + [:description docker-generic-action-description + ("L" "Logs" docker-container-logs-action)]) + +(docker-utils-define-transient-arguments docker-container-ls) + +(transient-define-prefix docker-container-ls () + "Transient for listing containers." + :man-page "docker-container-ls" + :value '("--all") + ["Arguments" + ("N" "Last" "--last " transient-read-number-N0) + ("a" "All" "--all") + ("e" "Exited containers" "--filter status=exited") + ("f" "Filter" "--filter " read-string) + ("n" "Don't truncate" "--no-trunc")] + ["Actions" + ("l" "List" tablist-revert)]) + +(docker-utils-transient-define-prefix docker-container-pause () + "Transient for pausing containers." + :man-page "docker-container-pause" + [:description docker-generic-action-description + ("P" "Pause" docker-generic-action-multiple-ids)]) + +(docker-utils-transient-define-prefix docker-container-unpause () + "Transient for pausing containers." + :man-page "docker-container-unpause" + [:description docker-generic-action-description + ("N" "Unpause" docker-generic-action-multiple-ids)]) + +(docker-utils-transient-define-prefix docker-container-restart () + "Transient for restarting containers." + :man-page "docker-container-restart" + ["Arguments" + ("t" "Timeout" "-t " transient-read-number-N0)] + [:description docker-generic-action-description + ("R" "Restart" docker-generic-action-multiple-ids)]) + +(docker-utils-transient-define-prefix docker-container-rm () + "Transient for removing containers." + :man-page "docker-container-rm" + ["Arguments" + ("f" "Force" "-f") + ("v" "Volumes" "-v")] + [:description docker-generic-action-description + ("D" "Remove" docker-generic-action-multiple-ids)]) + +(docker-utils-transient-define-prefix docker-container-shells () + "Transient for using shells on containers." + [:description docker-generic-action-description + ("!" "Shell command" docker-container-shell-command-selection) + ("b" "Shell" docker-container-shell-selection) + ("B" "Shell with env" docker-container-shell-env-selection) + ("e" "Eshell" docker-container-eshell-selection) + ("v" "Vterm" docker-container-vterm-selection) + ("V" "Vterm with env" docker-container-vterm-env-selection) + ("a" "Eat" docker-container-eat-selection) + ("A" "Eat with env" docker-container-eat-env-selection)]) + +(docker-utils-transient-define-prefix docker-container-start () + "Transient for starting containers." + :man-page "docker-container-start" + [:description docker-generic-action-description + ("S" "Start" docker-generic-action-multiple-ids)]) + +(docker-utils-transient-define-prefix docker-container-stop () + "Transient for stoping containers." + :man-page "docker-container-stop" + ["Arguments" + ("t" "Timeout" "-t " transient-read-number-N0)] + [:description docker-generic-action-description + ("O" "Stop" docker-generic-action-multiple-ids)]) + +(transient-define-prefix docker-container-help () + "Help transient for docker containers." + ["Docker Containers" + ["Lifecycle" + ("K" "Kill" docker-container-kill) + ("O" "Stop" docker-container-stop) + ("N" "Unpause" docker-container-unpause) + ("P" "Pause" docker-container-pause) + ("R" "Restart" docker-container-restart) + ("S" "Start" docker-container-start)] + ["Admin" + ("C" "Copy" docker-container-cp) + ("D" "Remove" docker-container-rm) + ("I" "Inspect" docker-container-inspect) + ("L" "Logs" docker-container-logs) + ("a" "Attach" docker-container-attach) + ("b" "Shell" docker-container-shells) + ("d" "Diff" docker-container-diff) + ("f" "Find file" docker-container-open) + ("l" "List" docker-container-ls) + ("r" "Rename" docker-container-rename-selection)]]) + +(defvar docker-container-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "?" 'docker-container-help) + (define-key map "C" 'docker-container-cp) + (define-key map "D" 'docker-container-rm) + (define-key map "I" 'docker-container-inspect) + (define-key map "K" 'docker-container-kill) + (define-key map "L" 'docker-container-logs) + (define-key map "O" 'docker-container-stop) + (define-key map "N" 'docker-container-unpause) + (define-key map "P" 'docker-container-pause) + (define-key map "R" 'docker-container-restart) + (define-key map "S" 'docker-container-start) + (define-key map "a" 'docker-container-attach) + (define-key map "b" 'docker-container-shells) + (define-key map "d" 'docker-container-diff) + (define-key map "f" 'docker-container-open) + (define-key map "l" 'docker-container-ls) + (define-key map "r" 'docker-container-rename-selection) + map) + "Keymap for `docker-container-mode'.") + +;;;###autoload (autoload 'docker-containers "docker-container" nil t) +(defun docker-containers () + "List docker containers." + (interactive) + (docker-utils-pop-to-buffer "*docker-containers*") + (docker-container-mode) + (tablist-revert)) + +(define-derived-mode docker-container-mode tabulated-list-mode "Containers Menu" + "Major mode for handling a list of docker containers." + (setq tabulated-list-format (docker-utils-columns-list-format docker-container-columns)) + (setq tabulated-list-padding 2) + (setq tabulated-list-sort-key docker-container-default-sort-key) + (add-hook 'tabulated-list-revert-hook 'docker-container-refresh nil t) + (tabulated-list-init-header) + (tablist-minor-mode)) + +(provide 'docker-container) + +;;; docker-container.el ends here diff --git a/elpa/docker-20260126.1212/docker-context.el b/elpa/docker-20260126.1212/docker-context.el new file mode 100644 index 00000000..46c0e20b --- /dev/null +++ b/elpa/docker-20260126.1212/docker-context.el @@ -0,0 +1,186 @@ +;;; docker-context.el --- Interface to docker-context -*- lexical-binding: t -*- + +;; Author: Pablo González Carrizo + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) +(require 'json) +(require 'tablist) +(require 'transient) + +(require 'docker-core) +(require 'docker-faces) +(require 'docker-utils) + +(defgroup docker-context nil + "Docker context customization group." + :group 'docker) + +(defconst docker-context-id-template + "{{ json .Name }}" + "This Go template extracts the context id which will be passed to transient commands.") + +(defcustom docker-context-default-sort-key '("Name" . nil) + "Sort key for docker contexts. + +This should be a cons cell (NAME . FLIP) where +NAME is a string matching one of the column names +and FLIP is a boolean to specify the sort order." + :group 'docker-context + :type '(cons (string :tag "Column Name" + :validate (lambda (widget) + (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-context-columns) + (widget-put widget :error "Default Sort Key must match a column name") + widget))) + (choice (const :tag "Ascending" nil) + (const :tag "Descending" t)))) + +(defcustom docker-context-columns + '((:name "Name" :width 40 :template "{{ json .Name }}" :sort nil :format nil) + (:name "Description" :width 40 :template "{{ json .Description }}" :sort nil :format nil) + (:name "Endpoint" :width 40 :template "{{ json .DockerEndpoint }}" :sort nil :format nil)) + "Column specification for docker contexts. + +The order of entries defines the displayed column order. +'Template' is the Go template passed to `docker-context-ls' to create the column +data. It should return a string delimited with double quotes. +'Sort function' is a binary predicate that should return true when the first +argument should be sorted before the second. +'Format function' is a function from string to string that transforms the +displayed values in the column." + :group 'docker-context + :set 'docker-utils-columns-setter + :get 'docker-utils-columns-getter + :type '(repeat (list :tag "Column" + (string :tag "Name") + (integer :tag "Width") + (string :tag "Template") + (sexp :tag "Sort function") + (sexp :tag "Format function")))) + +(aio-defun docker-context-inspect () + "Run \"`docker-command' context inspect\" on the selected items." + (interactive) + (docker-inspect "context")) + +(aio-defun docker-context-entries (&rest args) + "Return the docker contexts data for `tabulated-list-entries'." + (let* ((fmt (docker-utils-make-format-string docker-context-id-template docker-context-columns)) + (data (aio-await (docker-run-docker-async "context" "ls" args (format "--format=\"%s\"" fmt)))) + (lines (s-split "\n" data t))) + (-map (-partial #'docker-utils-parse docker-context-columns) lines))) + +(aio-defun docker-context-active-name (&rest args) + (let* ((fmt "{{ json .Current }} {{ json .Name }}") + (data (aio-await (docker-run-docker-async "context" "ls" args (format "--format=\"%s\"" fmt)))) + (lines (s-split "\n" data t)) + (active-line (-first (lambda (line) (string-match-p "true" (car (s-split " " line)))) lines))) + (when active-line + (cadr (split-string active-line "\""))))) + +(aio-defun docker-context-entries-propertized (&rest args) + "Return the propertized docker contexts data for `tabulated-list-entries'." + (let ((entries (aio-await (docker-context-entries args))) + (active (aio-await (docker-context-active-name args)))) + (--map-when (string= active (car it)) (docker-context-entry-set-active it) entries))) + +(defun docker-context-entry-set-active (entry) + "Mark ENTRY (output of `docker-context-entries') as active. + +The result is the tabulated list id for an entry is propertized with +'docker-context-active and the entry is fontified with 'docker-face-active." + (list (propertize (car entry) 'docker-context-active t) + (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-active) (cadr entry))))) + + +(aio-defun docker-context-update-status-async () + "Write the status to `docker-status-strings'." + (plist-put docker-status-strings :contexts "Contexts") + (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) + (let* ((entries (aio-await (docker-context-entries-propertized (docker-context-ls-arguments))))) + (plist-put docker-status-strings + :contexts + (format "Context (%s total)" (number-to-string (length entries)))) + (transient--redisplay)))) + +(add-hook 'docker-open-hook #'docker-context-update-status-async) + +(aio-defun docker-context-refresh () + "Refresh the contexts list." + (docker-utils-refresh-entries + (docker-context-entries-propertized (docker-context-ls-arguments)))) + +(docker-utils-define-transient-arguments docker-context-ls) + +(docker-utils-transient-define-prefix docker-context-rm () + "Transient for removing contexts." + :man-page "docker-context-rm" + [:description docker-generic-action-description + ("D" "Remove" docker-generic-action-multiple-ids)]) + +(docker-utils-transient-define-prefix docker-context-use () + "Transient for using contexts." + :man-page "docker-context-use" + [:description docker-generic-action-description + ("X" "Use" docker-generic-action)]) + +(transient-define-prefix docker-context-help () + "Help transient for docker contexts." + ["Docker contexts help" + ("D" "Remove" docker-context-rm) + ("I" "Inspect" docker-context-inspect) + ("X" "Use" docker-context-use)]) + +(defvar docker-context-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "?" 'docker-context-help) + (define-key map "D" 'docker-context-rm) + (define-key map "I" 'docker-context-inspect) + (define-key map "X" 'docker-context-use) + map) + "Keymap for `docker-context-mode'.") + +;;;###autoload (autoload 'docker-contexts "docker-context" nil t) +(defun docker-contexts () + "List docker contexts." + (interactive) + (docker-utils-pop-to-buffer "*docker-contexts*") + (docker-context-mode) + (tablist-revert)) + +(define-derived-mode docker-context-mode tabulated-list-mode "Contexts Menu" + "Major mode for handling a list of docker contexts." + (setq tabulated-list-format (docker-utils-columns-list-format docker-context-columns)) + (setq tabulated-list-padding 2) + (setq tabulated-list-sort-key docker-context-default-sort-key) + (add-hook 'tabulated-list-revert-hook 'docker-context-refresh nil t) + (tabulated-list-init-header) + (tablist-minor-mode)) + +(provide 'docker-context) + +;;; docker-context.el ends here diff --git a/elpa/docker-20260126.1212/docker-core.el b/elpa/docker-20260126.1212/docker-core.el new file mode 100644 index 00000000..a7d30b26 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-core.el @@ -0,0 +1,173 @@ +;;; docker-core.el --- Docker core -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 'aio) +(require 'transient) + +(require 'docker-group) +(require 'docker-utils) +(require 'docker-process) + +(defcustom docker-command "docker" + "The docker binary." + :group 'docker + :type 'string) + +(defvar docker-open-hook () + "Called when `docker' transient is opened.") + +(defvar docker-status-strings '(:containers "" :images "" :networks "" :volumes "" :contexts "") + "Plist of statuses for `docker' transient.") + +(defcustom docker-show-status 'local-only + "Whether to display docker status in the main transient buffer." + :group 'docker + :type '(choice + (const :tag "Always" t) + (const :tag "Local Only" local-only) + (const :tag "Never" nil))) + +(defcustom docker-inspect-view-mode (if (fboundp 'json-mode) 'json-mode 'js-mode) + "Major mode used in `docker inspect' buffers." + :group 'docker + :type 'symbol) + +(defun docker-run-docker-async (&rest args) + "Execute \"`docker-command' ARGS\" and return a promise with the results." + (apply #'docker-run-async docker-command (docker-arguments) args)) + +(defun docker-run-docker-async-with-buffer-interactive (&rest args) + "Execute \"`docker-command' ARGS\" and display output in an interactive buffer." + (apply #'docker-run-async-with-buffer-interactive docker-command (docker-arguments) args)) + +(defun docker-run-docker-async-with-buffer-noninteractive (&rest args) + "Execute \"`docker-command' ARGS\" and display output in a non-interactive buffer." + (apply #'docker-run-async-with-buffer-noninteractive docker-command (docker-arguments) args)) + +(defun docker-get-transient-action () + "Extract the action out of `transient-current-command'." + (s-replace "-" " " (s-chop-prefix "docker-" (symbol-name transient-current-command)))) + +(defun docker-generic-action-description () + "Make the actions description for the selected items." + (let ((items (s-join ", " (docker-utils-get-marked-items-ids)))) + (format "%s %s" + (propertize "Actions on" 'face 'transient-heading) + (propertize items 'face 'transient-value)))) + +(aio-defun docker-generic-action (action args) + "Run \"`docker-command' ACTION ARGS\" on each of the selected items." + (interactive (list (docker-get-transient-action) + (transient-args transient-current-command))) + (let* ((ids (docker-utils-get-marked-items-ids)) + (promises (--map (docker-run-docker-async action args it) ids))) + (aio-await (aio-all promises)) + (tablist-revert))) + +(aio-defun docker-generic-action-multiple-ids (action args) + "Same as `docker-generic-action', but group selection ids into a single command." + (interactive (list (docker-get-transient-action) + (transient-args transient-current-command))) + (aio-await (docker-run-docker-async action args (docker-utils-get-marked-items-ids))) + (tablist-revert)) + +(defun docker-generic-action-with-buffer-interactive (action args) + "Run \"`docker-command' ACTION ARGS\" and print output in an interactive buffer." + (interactive (list (docker-get-transient-action) + (transient-args transient-current-command))) + (--each (docker-utils-get-marked-items-ids) + (docker-run-docker-async-with-buffer-interactive (s-split " " action) args it))) + +(defun docker-generic-action-with-buffer-noninteractive (action args) + "Run \"`docker-command' ACTION ARGS\" and print output in a non-interactive buffer." + (interactive (list (docker-get-transient-action) + (transient-args transient-current-command))) + (--each (docker-utils-get-marked-items-ids) + (docker-run-docker-async-with-buffer-noninteractive (s-split " " action) args it))) + +(aio-defun docker-generic-action-with-buffer (action args) + "Run \"`docker-command' ACTION ARGS\", wait for completion, then display output. +This collects all output before displaying, suitable for non-interactive commands." + (interactive (list (docker-get-transient-action) + (transient-args transient-current-command))) + (--each (docker-utils-get-marked-items-ids) + (let* ((id it) + (output (aio-await (docker-run-docker-async (s-split " " action) args id)))) + (docker-utils-with-buffer (format "%s %s" action id) + ;; Strip carriage returns (Docker outputs CRLF line endings) + (insert (ansi-color-apply (replace-regexp-in-string "\r" "" output))) + (special-mode))))) + +(aio-defun docker-inspect (&optional subcmd) + "Run \"`docker-command' inspect\" on the selected items." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (let* ((id it) + (data (aio-await (docker-run-docker-async (concat (or subcmd "") " inspect") id)))) + (docker-utils-with-buffer (format "inspect %s" id) + (insert data) + (funcall docker-inspect-view-mode) + (view-mode))))) + +(defun docker-read-log-level (prompt &rest _args) + "Read the docker log level using PROMPT." + (completing-read prompt '(debug info warn error fatal))) + +(defun docker-read-certificate (prompt &optional initial-input _history) + "Wrapper around `read-file-name' forwarding PROMPT and INITIAL-INPUT." + (read-file-name prompt nil nil t initial-input (apply-partially 'string-match ".*\\.pem"))) + +(docker-utils-define-transient-arguments docker) + +;;;###autoload (autoload 'docker "docker" nil t) +(transient-define-prefix docker () + "Transient for docker." + :man-page "docker" + ["Arguments" + (5 "H" "Host" "--host " read-string) + (5 "Tt" "TLS" "--tls") + (5 "Tv" "TLS verify remote" "--tlsverify") + (5 "Ta" "TLS CA" "--tlscacert" docker-read-certificate) + (5 "Tc" "TLS certificate" "--tlscert" docker-read-certificate) + (5 "Tk" "TLS key" "--tlskey" docker-read-certificate) + (5 "l" "Log level" "--log-level " docker-read-log-level)] + ["Docker" + ("c" (lambda ()(plist-get docker-status-strings :containers)) docker-containers) + ("i" (lambda ()(plist-get docker-status-strings :images)) docker-images) + ("n" (lambda ()(plist-get docker-status-strings :networks)) docker-networks) + ("v" (lambda ()(plist-get docker-status-strings :volumes)) docker-volumes) + ("x" (lambda ()(plist-get docker-status-strings :contexts)) docker-contexts)] + ["Other" + ("C" "Compose" docker-compose)] + (interactive) + (run-hooks 'docker-open-hook) + (transient-setup 'docker)) + +(provide 'docker-core) + +;;; docker-core.el ends here diff --git a/elpa/docker-20260126.1212/docker-faces.el b/elpa/docker-20260126.1212/docker-faces.el new file mode 100644 index 00000000..c4e8aeee --- /dev/null +++ b/elpa/docker-20260126.1212/docker-faces.el @@ -0,0 +1,65 @@ +;;; docker-faces.el --- Docker faces -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'dash) + +(require 'docker-core) + +(defgroup docker-faces nil + "Docker faces customization group." + :group 'docker + :group 'faces) + +(defface docker-face-status-up + '((t :inherit success)) + "Face used when the status is up." + :group 'docker-faces) + +(defface docker-face-status-down + '((t :inherit error)) + "Face used when the status is down." + :group 'docker-faces) + +(defface docker-face-status-other + '((t :inherit warning)) + "Face used when the status is not up/down." + :group 'docker-faces) + +(defface docker-face-dangling + '((t :inherit shadow)) + "Face for dangling items." + :group 'docker-faces) + +(defface docker-face-active + '((t :inherit bold)) + "Face for active items." + :group 'docker-faces) + +(provide 'docker-faces) + +;;; docker-faces.el ends here diff --git a/elpa/docker-20260126.1212/docker-group.el b/elpa/docker-20260126.1212/docker-group.el new file mode 100644 index 00000000..fc76e629 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-group.el @@ -0,0 +1,34 @@ +;;; docker-group.el --- Docker group -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(defgroup docker nil + "Docker customization group." + :group 'convenience) + +(provide 'docker-group) + +;;; docker-group.el ends here diff --git a/elpa/docker-20260126.1212/docker-image.el b/elpa/docker-20260126.1212/docker-image.el new file mode 100644 index 00000000..c2b6472b --- /dev/null +++ b/elpa/docker-20260126.1212/docker-image.el @@ -0,0 +1,441 @@ +;;; docker-image.el --- Interface to docker-image -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) +(require 'json) +(require 'tablist) +(require 'transient) + +(require 'docker-core) +(require 'docker-faces) +(require 'docker-utils) + +(defgroup docker-image nil + "Docker images customization group." + :group 'docker) + +(defconst docker-image-id-template + "[{{ json .Repository }},{{ json .Tag }},{{ json .ID }}]" + "This Go template defines what will be passed to transient commands. + +This value is processed by `docker-image-make-id'.") + +(defcustom docker-image-default-sort-key '("Repository" . nil) + "Sort key for docker images. + +This should be a cons cell (NAME . FLIP) where +NAME is a string matching one of the column names +and FLIP is a boolean to specify the sort order." + :group 'docker-image + :type '(cons (string :tag "Column Name" + :validate (lambda (widget) + (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-image-columns) + (widget-put widget :error "Default Sort Key must match a column name") + widget))) + (choice (const :tag "Ascending" nil) + (const :tag "Descending" t)))) + +(defcustom docker-image-columns + '((:name "Repository" :width 30 :template "{{ json .Repository }}" :sort nil :format nil) + (:name "Tag" :width 20 :template "{{ json .Tag }}" :sort nil :format nil) + (:name "Id" :width 16 :template "{{ json .ID }}" :sort nil :format nil) + (:name "Created" :width 24 :template "{{ json .CreatedAt }}" :sort nil :format (lambda (x) (format-time-string "%F %T" (date-to-time x)))) + (:name "Size" :width 10 :template "{{ json .Size }}" :sort docker-utils-human-size-predicate :format nil)) + "Column specification for docker images. + +The order of entries defines the displayed column order. +'Template' is the Go template passed to `docker-image-ls' to create the column +data. It should return a string delimited with double quotes. +'Sort function' is a binary predicate that should return true when the first +argument should be sorted before the second. +'Format function' is a function from string to string that transforms the +displayed values in the column." + :group 'docker-image + :set 'docker-utils-columns-setter + :get 'docker-utils-columns-getter + :type '(repeat (list :tag "Column" + (string :tag "Name") + (integer :tag "Width") + (string :tag "Template") + (sexp :tag "Sort function") + (sexp :tag "Format function")))) + +(defconst docker-image-history-id-template + "{{ json .ID }}" + "This Go template extracts the history entry id.") + +(defcustom docker-image-history-default-sort-key '("Created" . t) + "Sort key for docker image history. + +This should be a cons cell (NAME . FLIP) where +NAME is a string matching one of the column names +and FLIP is a boolean to specify the sort order." + :group 'docker-image + :type '(cons (string :tag "Column Name" + :validate (lambda (widget) + (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-image-history-columns) + (widget-put widget :error "Default Sort Key must match a column name") + widget))) + (choice (const :tag "Ascending" nil) + (const :tag "Descending" t)))) + +(defcustom docker-image-history-columns + '((:name "Id" :width 16 :template "{{ json .ID }}" :sort nil :format nil) + (:name "Created" :width 24 :template "{{ json .CreatedAt }}" :sort nil :format (lambda (x) (format-time-string "%F %T" (date-to-time x)))) + (:name "CreatedBy" :width 60 :template "{{ json .CreatedBy }}" :sort nil :format nil) + (:name "Size" :width 10 :template "{{ json .Size }}" :sort docker-utils-human-size-predicate :format nil) + (:name "Comment" :width 20 :template "{{ json .Comment }}" :sort nil :format nil)) + "Column specification for docker image history. + +The order of entries defines the displayed column order. +'Template' is the Go template passed to `docker-image-history' to create the column +data. It should return a string delimited with double quotes. +'Sort function' is a binary predicate that should return true when the first +argument should be sorted before the second. +'Format function' is a function from string to string that transforms the +displayed values in the column." + :group 'docker-image + :set 'docker-utils-columns-setter + :get 'docker-utils-columns-getter + :type '(repeat (list :tag "Column" + (string :tag "Name") + (integer :tag "Width") + (string :tag "Template") + (sexp :tag "Sort function") + (sexp :tag "Format function")))) + +(defcustom docker-image-run-default-args + '("-i" "-t" "--rm") + "Default infix args used when docker run is invoked. + +Note this can be overriden for specific images using +`docker-image-run-custom-args'." + :group 'docker-image + :type '(repeat string)) + +(make-obsolete-variable 'docker-run-default-args 'docker-image-run-default-args "Docker 2.1.0") + +(defcustom docker-image-run-custom-args + nil + "List which can be used to customize the default arguments for docker run. + +Its elements should be of the form (REGEX ARGS) where +REGEX is a (string) regular expression and ARGS is a list of strings +corresponding to arguments. + +Also note if you do not specify `docker-run-default-args', they will be ignored." + :type '(repeat (list string (repeat string)))) + +(defalias 'docker-image-inspect 'docker-inspect) + +(defun docker-image-make-id (parsed-line) + "Fix the id string of the entry and return the fixed entry. + +PARSED-LINE is the output of `docker-utils-parse', the car is expected to +be the list (repository tag id). See `docker-image-id-template'." + ;; This could be written as a complex go template, + ;; however the literal '' causes havoc in the windows shell. + (-let* ((([repo tag id] rest) parsed-line) + (new-id (if (or (equal repo "") (equal tag "")) + id + (format "%s:%s" repo tag)))) + (list new-id rest))) + +(aio-defun docker-image-entries (&rest args) + "Return the docker images data for `tabulated-list-entries'." + (let* ((fmt (docker-utils-make-format-string docker-image-id-template docker-image-columns)) + (data (aio-await (docker-run-docker-async "image" "ls" args (format "--format=\"%s\"" fmt)))) + (lines (s-split "\n" data t))) + (--map (docker-image-make-id (docker-utils-parse docker-image-columns it)) lines))) + +(aio-defun docker-image-entries-propertized (&rest args) + "Return the propertized docker images data for `tabulated-list-entries'." + (let ((entries (aio-await (docker-image-entries args))) + (dangling (aio-await (docker-image-entries args "--filter dangling=true")))) + (--map-when (-contains? dangling it) (docker-image-entry-set-dangling it) entries))) + +(defun docker-image-dangling-p (entry-id) ; + "Predicate for if ENTRY-ID is dangling. + +For example (docker-image-dangling-p (tabulated-list-get-id)) is t when the entry under point is dangling." + (get-text-property 0 'docker-image-dangling entry-id)) + +(defun docker-image-entry-set-dangling (entry) + "Mark ENTRY (output of `docker-image-entries') as dangling. + +The result is the tabulated list id for an entry is propertized with +'docker-image-dangling and the entry is fontified with 'docker-face-dangling." + (list (propertize (car entry) 'docker-image-dangling t) + (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-dangling) (cadr entry))))) + +(aio-defun docker-image-update-status-async () + "Write the status to `docker-status-strings'." + (plist-put docker-status-strings :images "Images") + (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) + (let* ((entries (aio-await (docker-image-entries-propertized (docker-image-ls-arguments)))) + (dangling (--filter (docker-image-dangling-p (car it)) entries))) + (plist-put docker-status-strings + :images + (format "Images (%s total, %s dangling)" + (number-to-string (length entries)) + (propertize (number-to-string (length dangling)) 'face 'docker-face-dangling))) + (transient--redisplay)))) + +(add-hook 'docker-open-hook #'docker-image-update-status-async) + +(aio-defun docker-image-refresh () + "Refresh the images list." + (docker-utils-refresh-entries + (docker-image-entries-propertized (docker-image-ls-arguments)))) + +(defun docker-image-read-name () + "Read an image name." + (completing-read "Image: " (-map #'car (aio-wait-for (docker-image-entries))))) + +(defvar-local docker-image-history-image nil + "Image name used by the current history buffer.") + +(defvar-local docker-image-history-args nil + "Arguments used by the current history buffer.") + +(aio-defun docker-image-history-entries (image &rest args) + "Return the docker image history data for `tabulated-list-entries'." + (let* ((fmt (docker-utils-make-format-string docker-image-history-id-template docker-image-history-columns)) + (data (aio-await (docker-run-docker-async "image" "history" args (format "--format=\"%s\"" fmt) image))) + (lines (s-split "\n" data t))) + (-map (-partial #'docker-utils-parse docker-image-history-columns) lines))) + +(aio-defun docker-image-history-refresh () + "Refresh the image history list." + (docker-utils-refresh-entries + (apply #'docker-image-history-entries docker-image-history-image docker-image-history-args))) + +(defun docker-image-history-show (image &optional args) + "Display history for IMAGE." + (let ((buffer (docker-utils-generate-new-buffer "docker-image-history" image))) + (with-current-buffer buffer + (docker-image-history-mode) + (setq docker-image-history-image image) + (setq docker-image-history-args args) + (tablist-revert)) + (pop-to-buffer buffer))) + +(defun docker-image-history-selection () + "Show image history for the selection." + (interactive) + (docker-utils-ensure-items) + (let ((args (transient-args 'docker-image-history))) + (--each (docker-utils-get-marked-items-ids) + (docker-image-history-show it args)))) + +;;;###autoload (autoload 'docker-image-pull-one "docker-image" nil t) +(aio-defun docker-image-pull-one (name &optional all) + "Pull the image named NAME. If ALL is set, use \"-a\"." + (interactive (list (docker-image-read-name) current-prefix-arg)) + (aio-await (docker-run-docker-async "pull" (when all "-a") name)) + (tablist-revert)) + +(defun docker-image-run-selection (command) + "Run \"docker image run\" with COMMAND on the images selection." + (interactive "sCommand: ") + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-run-docker-async-with-buffer-interactive "container" "run" (transient-args 'docker-image-run) it command))) + +(aio-defun docker-image-tag-selection () + "Tag images." + (interactive) + (docker-utils-ensure-items) + (let* ((ids (docker-utils-get-marked-items-ids)) + (promises (--map (docker-run-docker-async "tag" it (read-string (format "Tag for %s: " it))) ids))) + (aio-await (aio-all promises)) + (tablist-revert))) + +(defun docker-image-mark-dangling () + "Mark only the dangling images listed in *docker-images*. + +This clears any user marks first and respects any tablist filters +applied to the buffer." + (interactive) + (switch-to-buffer "*docker-images*") + (tablist-unmark-all-marks) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (when (docker-image-dangling-p (tabulated-list-get-id)) + (tablist-put-mark)) + (forward-line)))) + +(docker-utils-define-transient-arguments docker-image-ls) + +(transient-define-prefix docker-image-ls () + "Transient for listing images." + :man-page "docker-image-ls" + ["Arguments" + ("a" "All" "--all") + ("d" "Dangling" "--filter dangling=true") + ("f" "Filter" "--filter " read-string) + ("n" "Don't truncate" "--no-trunc")] + ["Actions" + ("l" "List" tablist-revert)]) + +(docker-utils-define-transient-arguments docker-image-history) + +(docker-utils-transient-define-prefix docker-image-history () + "Transient for showing image history." + :man-page "docker-history" + ["Arguments" + ("n" "Don't truncate" "--no-trunc") + ("r" "Raw sizes" "--human=false")] + [:description docker-generic-action-description + ("H" "History" docker-image-history-selection)]) + +(transient-define-prefix docker-image-pull () + "Transient for pulling images." + :man-page "docker-image-pull" + ["Arguments" + ("a" "All" "-a")] + [:description docker-generic-action-description + ("F" "Pull selection" docker-generic-action) + ("N" "Pull a new image" docker-image-pull-one)]) + +(docker-utils-transient-define-prefix docker-image-push () + "Transient for pushing images." + :man-page "docker-image-push" + [:description docker-generic-action-description + ("P" "Push" docker-generic-action)]) + +(docker-utils-transient-define-prefix docker-image-rm () + "Transient for removing images." + :man-page "docker-image-rm" + ["Arguments" + ("-f" "Force" "-f") + ("-n" "Don't prune" "--no-prune")] + [:description docker-generic-action-description + ("D" "Remove" docker-generic-action-multiple-ids)]) + +(defclass docker-run-prefix (transient-prefix) nil) + +(cl-defmethod transient-init-value ((obj docker-run-prefix)) + "Helper that modify OBJ DOCKER-RUN-PREFIX to handle `docker-image-run-custom-args'." + (oset obj value + (let* ((images (tablist-get-marked-items)) + (matched-args (let ((repo-name (caar images))) + (if repo-name + (--first (string-match (car it) repo-name) + docker-image-run-custom-args) + nil)))) + (if matched-args + (cadr matched-args) + docker-image-run-default-args)))) + +(docker-utils-transient-define-prefix docker-image-run () + "Transient for running images." + :man-page "docker-image-run" + :class 'docker-run-prefix + ["Arguments" + ("D" "With display" "-v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY") + ("M" "Mount volume" "--mount " read-string) + ("N" "Network" "--network " read-string) + ("P" "Privileged" "--privileged") + ("T" "Synchronize time" "-v /etc/localtime:/etc/localtime:ro") + ("W" "Web ports" "-p 80:80 -p 443:443 -p 8080:8080") + ("d" "Detach" "-d") + ("e" "Environment" "-e " read-string) + ("i" "Interactive" "-i") + ("l" "Link" "--link " read-string) + ("m" "Name" "--name " read-string) + ("n" "Entrypoint" "--entrypoint " read-string) + ("o" "Read only" "--read-only") + ("p" "Port" "-p " read-string) + ("r" "Remove container when it exits" "--rm") + ("t" "TTY" "-t") + ("u" "User" "-u " read-string) + ("v" "Volume" "-v " read-string) + ("w" "Workdir" "-w " read-string)] + [:description docker-generic-action-description + ("R" "Run" docker-image-run-selection)]) + +(transient-define-prefix docker-image-help () + "Help transient for docker images." + ["Docker images help" + ("D" "Remove" docker-image-rm) + ("F" "Pull" docker-image-pull) + ("H" "History" docker-image-history) + ("I" "Inspect" docker-image-inspect) + ("P" "Push" docker-image-push) + ("R" "Run" docker-image-run) + ("T" "Tag" docker-image-tag-selection) + ("d" "Mark Dangling" docker-image-mark-dangling) + ("l" "List" docker-image-ls)]) + +(defvar docker-image-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "?" 'docker-image-help) + (define-key map "D" 'docker-image-rm) + (define-key map "F" 'docker-image-pull) + (define-key map "H" 'docker-image-history) + (define-key map "I" 'docker-image-inspect) + (define-key map "P" 'docker-image-push) + (define-key map "R" 'docker-image-run) + (define-key map "T" 'docker-image-tag-selection) + (define-key map "d" 'docker-image-mark-dangling) + (define-key map "l" 'docker-image-ls) + map) + "Keymap for `docker-image-mode'.") + +;;;###autoload (autoload 'docker-images "docker-image" nil t) +(defun docker-images () + "List docker images." + (interactive) + (docker-utils-pop-to-buffer "*docker-images*") + (docker-image-mode) + (tablist-revert)) + +(define-derived-mode docker-image-mode tabulated-list-mode "Images Menu" + "Major mode for handling a list of docker images." + (setq tabulated-list-format (docker-utils-columns-list-format docker-image-columns)) + (setq tabulated-list-padding 2) + (setq tabulated-list-sort-key docker-image-default-sort-key) + (add-hook 'tabulated-list-revert-hook 'docker-image-refresh nil t) + (tabulated-list-init-header) + (tablist-minor-mode)) + +(define-derived-mode docker-image-history-mode tabulated-list-mode "Image History" + "Major mode for handling docker image history." + (setq tabulated-list-format (docker-utils-columns-list-format docker-image-history-columns)) + (setq tabulated-list-padding 2) + (setq tabulated-list-sort-key docker-image-history-default-sort-key) + (add-hook 'tabulated-list-revert-hook 'docker-image-history-refresh nil t) + (tabulated-list-init-header) + (tablist-minor-mode)) + +(provide 'docker-image) + +;;; docker-image.el ends here diff --git a/elpa/docker-20260126.1212/docker-network.el b/elpa/docker-20260126.1212/docker-network.el new file mode 100644 index 00000000..f835bd0b --- /dev/null +++ b/elpa/docker-20260126.1212/docker-network.el @@ -0,0 +1,209 @@ +;;; docker-network.el --- Interface to docker-network -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) +(require 'json) +(require 'tablist) +(require 'transient) + +(require 'docker-core) +(require 'docker-faces) +(require 'docker-utils) + +(defgroup docker-network nil + "Docker network customization group." + :group 'docker) + +(defconst docker-network-id-template + "{{ json .ID }}" + "This Go template extracts the id which will be passed to transient commands.") + +(defcustom docker-network-default-sort-key '("Name" . nil) + "Sort key for docker networks. + +This should be a cons cell (NAME . FLIP) where +NAME is a string matching one of the column names +and FLIP is a boolean to specify the sort order." + :group 'docker-network + :type '(cons (string :tag "Column Name" + :validate (lambda (widget) + (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-network-columns) + (widget-put widget :error "Default Sort Key must match a column name") + widget))) + (choice (const :tag "Ascending" nil) + (const :tag "Descending" t)))) + +(defcustom docker-network-columns + '((:name "Network ID" :width 20 :template "{{ json .ID }}" :sort nil :format nil) + (:name "Name" :width 50 :template "{{ json .Name }}" :sort nil :format nil) + (:name "Driver" :width 10 :template "{{ json .Driver }}" :sort nil :format nil) + (:name "Scope" :width 10 :template "{{ json .Scope }}" :sort nil :format nil)) + "Column specification for docker networks. + +The order of entries defines the displayed column order. +'Template' is the Go template passed to `docker-network-ls' to create the column +data. It should return a string delimited with double quotes. +'Sort function' is a binary predicate that should return true when the first +argument should be sorted before the second. +'Format function' is a function from string to string that transforms the +displayed values in the column." + :group 'docker-network + :set 'docker-utils-columns-setter + :get 'docker-utils-columns-getter + :type '(repeat (list :tag "Column" + (string :tag "Name") + (integer :tag "Width") + (string :tag "Template") + (sexp :tag "Sort function") + (sexp :tag "Format function")))) + +(defalias 'docker-network-inspect 'docker-inspect) + +(aio-defun docker-network-entries (&rest args) + "Return the docker networks data for `tabulated-list-entries'." + (let* ((fmt (docker-utils-make-format-string docker-network-id-template docker-network-columns)) + (data (aio-await (docker-run-docker-async "network" "ls" args (format "--format=\"%s\"" fmt)))) + (lines (s-split "\n" data t))) + (-map (-partial #'docker-utils-parse docker-network-columns) lines))) + +(aio-defun docker-network-entries-propertized (&rest args) + "Return the propertized docker networks data for `tabulated-list-entries'." + (let ((entries (aio-await (docker-network-entries args))) + (dangling (aio-await (docker-network-entries args "--filter dangling=true")))) + (--map-when (-contains? dangling it) (docker-network-entry-set-dangling it) entries))) + +(defun docker-network-dangling-p (entry-id) + "Predicate for if ENTRY-ID is dangling. + +For example (docker-network-dangling-p (tabulated-list-get-id)) is t when the entry under point is dangling." + (get-text-property 0 'docker-network-dangling entry-id)) + +(defun docker-network-entry-set-dangling (entry) + "Mark ENTRY (output of `docker-network-entries') as dangling. + +The result is the tabulated list id for an entry is propertized with +'docker-network-dangling and the entry is fontified with 'docker-face-dangling." + (list (propertize (car entry) 'docker-network-dangling t) + (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-dangling) (cadr entry))))) + +(aio-defun docker-network-update-status-async () + "Write the status to `docker-status-strings'." + (plist-put docker-status-strings :networks "Networks") + (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) + (let* ((entries (aio-await (docker-network-entries-propertized (docker-network-ls-arguments)))) + (dangling (--filter (docker-network-dangling-p (car it)) entries))) + (plist-put docker-status-strings + :networks + (format "Networks (%s total, %s dangling)" + (number-to-string (length entries)) + (propertize (number-to-string (length dangling)) 'face 'docker-face-dangling))) + (transient--redisplay)))) + +(add-hook 'docker-open-hook #'docker-network-update-status-async) + +(aio-defun docker-network-refresh () + "Refresh the networks list." + (docker-utils-refresh-entries + (docker-network-entries-propertized (docker-network-ls-arguments)))) + +(defun docker-network-read-name () + "Read a network name." + (completing-read "Network: " (-map #'car (aio-wait-for (docker-network-entries))))) + +(defun docker-network-mark-dangling () + "Mark only the dangling networks listed in *docker-networks*. + +This clears any user marks first and respects any tablist filters +applied to the buffer." + (interactive) + (switch-to-buffer "*docker-networks*") + (tablist-unmark-all-marks) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (when (docker-network-dangling-p (tabulated-list-get-id)) + (tablist-put-mark)) + (forward-line)))) + +(docker-utils-define-transient-arguments docker-network-ls) + +(transient-define-prefix docker-network-ls () + "Transient for listing networks." + :man-page "docker-network-ls" + ["Arguments" + ("d" "Dangling" "--filter dangling=true") + ("f" "Filter" "--filter " read-string) + ("n" "Don't truncate" "--no-trunc")] + ["Actions" + ("l" "List" tablist-revert)]) + +(docker-utils-transient-define-prefix docker-network-rm () + "Transient for removing networks." + :man-page "docker-network-rm" + [:description docker-generic-action-description + ("D" "Remove" docker-generic-action-multiple-ids)]) + +(transient-define-prefix docker-network-help () + "Help transient for docker networks." + ["Docker networks help" + ("D" "Remove" docker-network-rm) + ("I" "Inspect" docker-network-inspect) + ("d" "Mark Dangling" docker-network-mark-dangling) + ("l" "List" docker-network-ls)]) + +(defvar docker-network-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "?" 'docker-network-help) + (define-key map "D" 'docker-network-rm) + (define-key map "I" 'docker-network-inspect) + (define-key map "d" 'docker-network-mark-dangling) + (define-key map "l" 'docker-network-ls) + map) + "Keymap for `docker-network-mode'.") + +;;;###autoload (autoload 'docker-networks "docker-network" nil t) +(defun docker-networks () + "List docker networks." + (interactive) + (docker-utils-pop-to-buffer "*docker-networks*") + (docker-network-mode) + (tablist-revert)) + +(define-derived-mode docker-network-mode tabulated-list-mode "Networks Menu" + "Major mode for handling a list of docker networks." + (setq tabulated-list-format (docker-utils-columns-list-format docker-network-columns)) + (setq tabulated-list-padding 2) + (setq tabulated-list-sort-key docker-network-default-sort-key) + (add-hook 'tabulated-list-revert-hook 'docker-network-refresh nil t) + (tabulated-list-init-header) + (tablist-minor-mode)) + +(provide 'docker-network) + +;;; docker-network.el ends here diff --git a/elpa/docker-20260126.1212/docker-pkg.el b/elpa/docker-20260126.1212/docker-pkg.el new file mode 100644 index 00000000..9640b8c0 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-pkg.el @@ -0,0 +1,15 @@ +;; -*- no-byte-compile: t; lexical-binding: nil -*- +(define-package "docker" "20260126.1212" + "Interface to Docker." + '((aio "1.0") + (dash "2.19.1") + (emacs "28.1") + (s "1.13.0") + (tablist "1.1") + (transient "0.4.3")) + :url "https://github.com/Silex/docker.el" + :commit "916686b86e83a3bd2281fbc5e6f98962aa747429" + :revdesc "916686b86e83" + :keywords '("filename" "convenience") + :authors '(("Philippe Vaucher" . "philippe.vaucher@gmail.com")) + :maintainers '(("Philippe Vaucher" . "philippe.vaucher@gmail.com"))) diff --git a/elpa/docker-20260126.1212/docker-process.el b/elpa/docker-20260126.1212/docker-process.el new file mode 100644 index 00000000..a0a91c6c --- /dev/null +++ b/elpa/docker-20260126.1212/docker-process.el @@ -0,0 +1,212 @@ +;;; docker-process.el --- Docker process -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) + +(require 'docker-group) +(require 'docker-utils) + +(defcustom docker-run-as-root nil + "Run docker as root." + :group 'docker + :type 'boolean) + +(defcustom docker-show-messages t + "If non-nil `message' docker commands which are run." + :group 'docker + :type 'boolean) + +(defcustom docker-terminal-backend 'auto + "Terminal backend used for commands that need a live buffer. +When set to `auto', prefer eat, then vterm, then shell." + :group 'docker + :type '(choice (const :tag "Auto (eat > vterm > shell)" auto) + (const :tag "Eat" eat) + (const :tag "Vterm" vterm) + (const :tag "Shell" shell))) + +(defcustom docker-run-async-with-buffer-function nil + "Obsolete; use `docker-terminal-backend' instead." + :group 'docker + :type 'symbol) + +(make-obsolete-variable 'docker-run-async-with-buffer-function 'docker-terminal-backend "2.5.0") + + +(defmacro docker-with-sudo (&rest body) + "Ensure `default-directory' is set correctly according to `docker-run-as-root' then execute BODY." + (declare (indent defun)) + `(let ((default-directory (if (and docker-run-as-root (not (file-remote-p default-directory))) + "/sudo::" + default-directory))) + ,@body)) + +(defun docker-run-start-file-process-shell-command (program &rest args) + "Execute \"PROGRAM ARGS\" and return the process." + (docker-with-sudo + (let* ((process-args (-remove 's-blank? (-flatten args))) + (command (s-join " " (-insert-at 0 program process-args)))) + (when docker-show-messages (message "Running: %s" command)) + (start-file-process-shell-command command (apply #'docker-utils-generate-new-buffer-name program process-args) command)))) + +(defun docker-run-async (program &rest args) + "Execute \"PROGRAM ARGS\" and return a promise with the results." + (let* ((process (apply #'docker-run-start-file-process-shell-command program args)) + (promise (aio-promise))) + (set-process-query-on-exit-flag process nil) + (set-process-sentinel process (-partial #'docker-process-sentinel promise)) + promise)) + +(defun docker-run-async-with-buffer (program interactive &rest args) + "Execute \"PROGRAM ARGS\" and display output in a new buffer. +INTERACTIVE selects an interactive terminal buffer when non-nil. +Prefer `docker-run-async-with-buffer-interactive' or +`docker-run-async-with-buffer-noninteractive'." + (if docker-run-async-with-buffer-function + (apply docker-run-async-with-buffer-function program interactive args) + (apply #'docker-run-async-with-buffer-dispatch + (docker--terminal-backend) + program interactive args))) + +(defun docker-run-async-with-buffer-interactive (program &rest args) + "Execute \"PROGRAM ARGS\" and display output in an interactive buffer." + (apply #'docker-run-async-with-buffer program t args)) + +(defun docker-run-async-with-buffer-noninteractive (program &rest args) + "Execute \"PROGRAM ARGS\" and display output in a non-interactive buffer." + (apply #'docker-run-async-with-buffer program nil args)) + +(defun docker--terminal-backend-available-p (backend) + "Return non-nil when BACKEND is available." + (pcase backend + ('eat (fboundp 'eat-other-window)) + ('vterm (fboundp 'vterm-other-window)) + ('shell t) + (_ nil))) + +(defun docker--terminal-backend () + "Return the selected backend symbol." + (pcase docker-terminal-backend + ('auto (cond + ((docker--terminal-backend-available-p 'eat) 'eat) + ((docker--terminal-backend-available-p 'vterm) 'vterm) + (t 'shell))) + (_ docker-terminal-backend))) + +(defun docker-run-async-with-buffer-dispatch (backend program interactive &rest args) + "Dispatch PROGRAM to BACKEND and display output in a new buffer." + (pcase backend + ('eat (if (docker--terminal-backend-available-p 'eat) + (apply #'docker-run-async-with-buffer-eat program interactive args) + (error "The eat package is not installed"))) + ('vterm (if (docker--terminal-backend-available-p 'vterm) + (apply #'docker-run-async-with-buffer-vterm program interactive args) + (error "The vterm package is not installed"))) + ('shell (apply #'docker-run-async-with-buffer-shell program interactive args)) + (_ (error "Unsupported docker terminal backend: %s" backend)))) + +(defun docker-run-async-with-buffer-shell (program &optional interactive &rest args) + "Execute \"PROGRAM ARGS\" and display output in a new buffer. +If INTERACTIVE is non-nil, use a `shell' buffer for interactive use. +Otherwise, use a non-interactive buffer with ANSI color support." + (let* ((process (apply #'docker-run-start-file-process-shell-command program args)) + (buffer (process-buffer process))) + (set-process-query-on-exit-flag process nil) + (if interactive + (with-current-buffer buffer (shell-mode)) + (with-current-buffer buffer (special-mode))) + (set-process-filter process + (if interactive + 'comint-output-filter + 'docker-process-filter-noninteractive)) + (switch-to-buffer-other-window buffer))) + +(defun docker-run-async-with-buffer-vterm (program &optional interactive &rest args) + "Execute \"PROGRAM ARGS\" and display output in a new `vterm' buffer. +If INTERACTIVE is nil, fall back to shell mode since vterm is interactive." + (if (not interactive) + ;; vterm is interactive only, fall back to shell for non-interactive output + (apply #'docker-run-async-with-buffer-shell program nil args) + (defvar vterm-kill-buffer-on-exit) + (defvar vterm-shell) + (if (fboundp 'vterm-other-window) + (let* ((process-args (-remove 's-blank? (-flatten args))) + (vterm-shell (s-join " " (-insert-at 0 program process-args))) + (vterm-kill-buffer-on-exit nil)) + (vterm-other-window + (apply #'docker-utils-generate-new-buffer-name program process-args))) + (error "The vterm package is not installed")))) + +(defun docker-run-async-with-buffer-eat (program &optional interactive &rest args) + "Execute \"PROGRAM ARGS\" and display output in a new `eat' buffer. +If INTERACTIVE is nil, fall back to shell mode since eat is interactive." + (if (not interactive) + (apply #'docker-run-async-with-buffer-shell program nil args) + (defvar eat-buffer-name) + (if (fboundp 'eat-other-window) + (let* ((process-args (-remove 's-blank? (-flatten args))) + (command (s-join " " (-insert-at 0 program process-args))) + (eat-buffer-name (apply #'docker-utils-generate-new-buffer-name + program process-args))) + (eat-other-window command)) + (error "The eat package is not installed")))) + +(defun docker-process-filter-noninteractive (proc string) + "Process filter for non-interactive streaming buffers. +Strips carriage returns and applies ANSI color codes." + (when (buffer-live-p (process-buffer proc)) + (with-current-buffer (process-buffer proc) + (let ((inhibit-read-only t) + (moving (= (point) (process-mark proc)))) + (save-excursion + (goto-char (process-mark proc)) + (insert (ansi-color-apply (replace-regexp-in-string "\r" "" string))) + (set-marker (process-mark proc) (point))) + (when moving (goto-char (process-mark proc))))))) + +(defun docker-process-sentinel (promise process event) + "Sentinel that resolves the PROMISE using PROCESS and EVENT." + (when (memq (process-status process) '(exit signal)) + (setq event (substring event 0 -1)) + (if (not (string-equal event "finished")) + (aio-resolve promise + (lambda () + (error "Error running: \"%s\" (%s)" (process-name process) event))) + (aio-resolve promise + (lambda () + (when docker-show-messages + (message "Finished: %s" (process-name process))) + (run-with-timer 2 nil (lambda () (message nil))) + (with-current-buffer (process-buffer process) + (prog1 (buffer-substring-no-properties (point-min) (point-max)) + (kill-buffer)))))))) + +(provide 'docker-process) + +;;; docker-process.el ends here diff --git a/elpa/docker-20260126.1212/docker-utils.el b/elpa/docker-20260126.1212/docker-utils.el new file mode 100644 index 00000000..25041cf3 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-utils.el @@ -0,0 +1,191 @@ +;;; docker-utils.el --- Random utilities -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) +(require 'json) +(require 'tramp) +(require 'tablist) +(require 'transient) + +(defun docker-utils-get-marked-items-ids () + "Get the id part of `tablist-get-marked-items'." + (-map #'car (tablist-get-marked-items))) + +(defun docker-utils-ensure-items () + "Ensure at least one item is selected." + (when (null (docker-utils-get-marked-items-ids)) + (user-error "This action cannot be used in an empty list"))) + +(defun docker-utils-generate-new-buffer-name (program &rest args) + "Wrapper around `generate-new-buffer-name' using PROGRAM and ARGS." + (generate-new-buffer-name (format "* %s %s *" program (s-join " " args)))) + +(defun docker-utils-generate-new-buffer (program &rest args) + "Wrapper around `generate-new-buffer' using PROGRAM and ARGS." + (generate-new-buffer (apply #'docker-utils-generate-new-buffer-name program args))) + +(defmacro docker-utils-with-buffer (name &rest body) + "Wrapper around `with-current-buffer'. +Execute BODY in a buffer named with the help of NAME." + (declare (indent defun)) + `(with-current-buffer (docker-utils-generate-new-buffer "docker" ,name) + (setq buffer-read-only nil) + (erase-buffer) + ,@body + (setq buffer-read-only t) + (goto-char (point-min)) + (pop-to-buffer (current-buffer)))) + +(defmacro docker-utils-transient-define-prefix (name arglist &rest args) + "Wrapper around `transient-define-prefix' forwarding NAME, ARGLIST and ARGS and calling `docker-utils-ensure-items'." + `(transient-define-prefix ,name ,arglist + ,@args + (interactive) + (docker-utils-ensure-items) + (transient-setup ',name))) + +(defmacro docker-utils-define-transient-arguments (name) + "Define the transient arguments function using NAME that return the latest transient value or its default." + `(defun ,(intern (format "%s-arguments" name)) () + ,(format "Return the latest used arguments in the `%s' transient." name) + (let ((history (alist-get ',name transient-history)) + (default (transient-default-value (get ',name 'transient--prefix)))) + (if (equal 0 (length history)) + (car default) + (car history))))) + +(defmacro docker-utils-refresh-entries (promise) + "Update the current buffer with the results of PROMISE." + `(let ((buffer (current-buffer)) + (entries (aio-await ,promise))) + (with-current-buffer buffer + (setq tabulated-list-entries entries) + (tabulated-list-print t)))) + +(defvar docker-pop-to-buffer-action nil + "Action to use internally when `docker-utils-pop-to-buffer' calls `pop-to-buffer'.") + +(defun docker-utils-pop-to-buffer (name) + "Like `pop-to-buffer', but suffix NAME with the host if on a remote host." + (pop-to-buffer + (if (file-remote-p default-directory) + (with-parsed-tramp-file-name default-directory nil (concat name " - " host)) + name) + docker-pop-to-buffer-action)) + +(defun docker-utils-unit-multiplier (str) + "Return the correct multiplier for STR." + (let* ((unit (or str "B")) + (idx (-elem-index (upcase unit) '("B" "KB" "MB" "GB" "TB" "PB" "EB")))) + (expt 1024 (or idx 0)))) + +(defun docker-utils-human-size-to-bytes (str) + "Parse STR and return size in bytes." + (let* ((parts (s-match "^\\([0-9\\.]+\\)\\([A-Za-z]+\\)?$" str))) + (unless parts + (error "Unexpected size format: %s" str)) + (let* ((value (string-to-number (-second-item parts))) + (multiplier (docker-utils-unit-multiplier (-third-item parts)))) + (* value multiplier)))) + +(defun docker-utils-human-size-predicate (a b) + "Sort A and B by image size." + (< (docker-utils-human-size-to-bytes a) (docker-utils-human-size-to-bytes b))) + +(defun docker-utils-columns-list-format (columns-spec) + "Convert COLUMNS-SPEC (a list of plists) to 'tabulated-list-format', i.e. a vector of (name width sort-fn)." + (apply 'vector + (--map-indexed + (-let* (((&plist :name name :width width :sort sort-fn-inner) it) + (sort-fn (if sort-fn-inner + (let ((idx it-index)) ;; Rebind the closure var! + ;; Sort fn is called with (id [entries..]) + ;; Extract the column value and pass to inner function + (-on sort-fn-inner (lambda (x) (elt (cadr x) idx)))) + t))) + (list name width sort-fn)) + columns-spec))) + +(defun docker-utils-make-format-string (id-template column-spec) + "Make the format string to pass to docker-ls commands. + +ID-TEMPLATE is the Go template used to extract the property that +identifies the object (usually its id). +COLUMN-SPEC is the value of docker-X-columns." + (let* ((templates (--map (plist-get it :template) column-spec)) + (delimited (string-join templates ","))) + (format "[%s,%s]" id-template delimited))) + +(defun docker-utils-parse (column-specs line) + "Convert a LINE from \"docker ls\" to a `tabulated-list-entries' entry. + +LINE is expected to be a JSON formatted array, and COLUMN-SPECS is the relevant +defcustom (e.g. `docker-image-columns`) used to apply any custom format functions." + (condition-case nil + (let* ((data (json-read-from-string line))) + ;; apply format function, if any + (--each-indexed + column-specs + (let ((fmt-fn (plist-get it :format)) + (data-index (+ it-index 1))) + (when fmt-fn (aset data data-index (apply fmt-fn (list (aref data data-index))))))) + + (list (aref data 0) (seq-drop data 1))) + (json-readtable-error + (error "Could not read following string as json:\n%s" line)))) + +(defun docker-utils-columns-setter (sym new-value) + "Convert NEW-VALUE into a list of plists, then assign to SYM. + +If NEW-VALUE already looks like a list of plists, no conversion is performed and + NEW-VALUE is assigned to SYM unchanged. This is expected to be used as the +value of :set in a defcustom." + (let ((is-plist (plist-member (car new-value) :name)) + (new-value-plist (--map + (-interleave '(:name :width :template :sort :format) it) + new-value))) + (set sym (if is-plist new-value new-value-plist)))) + +(defun docker-utils-columns-getter (sym) + "Convert the value of SYM for displaying in the customization menu. + +Just strips the plist symbols and returns only values. +This has no effect on the actual value of the variable." + (--map + (-map (-partial #'plist-get it) '(:name :width :template :sort :format)) + (symbol-value sym))) + +(defun docker-utils-package-p (package) + "Check if PACKAGE is available." + (or (featurep package) + (ignore-errors (require package)))) + +(provide 'docker-utils) + +;;; docker-utils.el ends here diff --git a/elpa/docker-20260126.1212/docker-volume.el b/elpa/docker-20260126.1212/docker-volume.el new file mode 100644 index 00000000..27887364 --- /dev/null +++ b/elpa/docker-20260126.1212/docker-volume.el @@ -0,0 +1,222 @@ +;;; docker-volume.el --- Interface to docker-volume -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 's) +(require 'aio) +(require 'dash) +(require 'json) +(require 'tablist) +(require 'transient) + +(require 'docker-core) +(require 'docker-faces) +(require 'docker-utils) + +(defgroup docker-volume nil + "Docker volume customization group." + :group 'docker) + +(defconst docker-volume-id-template + "{{ json .Name }}" + "This Go template extracts the volume id which will be passed to transient commands.") + +(defcustom docker-volume-default-sort-key '("Driver" . nil) + "Sort key for docker volumes. + +This should be a cons cell (NAME . FLIP) where +NAME is a string matching one of the column names +and FLIP is a boolean to specify the sort order." + :group 'docker-volume + :type '(cons (string :tag "Column Name" + :validate (lambda (widget) + (unless (--any-p (equal (plist-get it :name) (widget-value widget)) docker-volume-columns) + (widget-put widget :error "Default Sort Key must match a column name") + widget))) + (choice (const :tag "Ascending" nil) + (const :tag "Descending" t)))) + +(defcustom docker-volume-columns + '((:name "Driver" :width 10 :template "{{ json .Driver }}" :sort nil :format nil) + (:name "Name" :width 40 :template "{{ json .Name }}" :sort nil :format nil)) + "Column specification for docker volumes. + +The order of entries defines the displayed column order. +'Template' is the Go template passed to `docker-volume-ls' to create the column +data. It should return a string delimited with double quotes. +'Sort function' is a binary predicate that should return true when the first +argument should be sorted before the second. +'Format function' is a function from string to string that transforms the +displayed values in the column." + :group 'docker-volume + :set 'docker-utils-columns-setter + :get 'docker-utils-columns-getter + :type '(repeat (list :tag "Column" + (string :tag "Name") + (integer :tag "Width") + (string :tag "Template") + (sexp :tag "Sort function") + (sexp :tag "Format function")))) + +(defalias 'docker-volume-inspect 'docker-inspect) + +(aio-defun docker-volume-entries (&rest args) + "Return the docker volumes data for `tabulated-list-entries'." + (let* ((fmt (docker-utils-make-format-string docker-volume-id-template docker-volume-columns)) + (data (aio-await (docker-run-docker-async "volume" "ls" args (format "--format=\"%s\"" fmt)))) + (lines (s-split "\n" data t))) + (-map (-partial #'docker-utils-parse docker-volume-columns) lines))) + +(aio-defun docker-volume-entries-propertized (&rest args) + "Return the propertized docker volumes data for `tabulated-list-entries'." + (let ((entries (aio-await (docker-volume-entries args))) + (dangling (aio-await (docker-volume-entries args "--filter dangling=true")))) + (--map-when (-contains? dangling it) (docker-volume-entry-set-dangling it) entries))) + +(defun docker-volume-dangling-p (entry-id) + "Predicate for if ENTRY-ID is dangling. + +For example (docker-volume-dangling-p (tabulated-list-get-id)) is t when the entry under point is dangling." + (get-text-property 0 'docker-volume-dangling entry-id)) + +(defun docker-volume-entry-set-dangling (entry) + "Mark ENTRY (output of `docker-volume-entries') as dangling. + +The result is the tabulated list id for an entry is propertized with +'docker-volume-dangling and the entry is fontified with 'docker-face-dangling." + (list (propertize (car entry) 'docker-volume-dangling t) + (apply #'vector (--map (propertize it 'font-lock-face 'docker-face-dangling) (cadr entry))))) + +(aio-defun docker-volume-update-status-async () + "Write the status to `docker-status-strings'." + (plist-put docker-status-strings :volumes "Volumes") + (when (or (eq docker-show-status t) (and (eq docker-show-status 'local-only) (not (file-remote-p default-directory)))) + (let* ((entries (aio-await (docker-volume-entries-propertized (docker-volume-ls-arguments)))) + (dangling (--filter (docker-volume-dangling-p (car it)) entries))) + (plist-put docker-status-strings + :volumes + (format "Volumes (%s total, %s dangling)" + (number-to-string (length entries)) + (propertize (number-to-string (length dangling)) 'face 'docker-face-dangling))) + (transient--redisplay)))) + +(add-hook 'docker-open-hook #'docker-volume-update-status-async) + +(aio-defun docker-volume-refresh () + "Refresh the volumes list." + (docker-utils-refresh-entries + (docker-volume-entries-propertized (docker-volume-ls-arguments)))) + +(defun docker-volume-read-name () + "Read a volume name." + (completing-read "Volume: " (-map #'car (aio-wait-for (docker-volume-entries))))) + +;;;###autoload (autoload 'docker-volume-dired "docker-volume" nil t) +(aio-defun docker-volume-dired (name) + "Enter `dired' in the volume named NAME." + (interactive (list (docker-volume-read-name))) + (let ((path (s-trim-right (aio-await (docker-run-docker-async "inspect" "-f" "\"{{ .Mountpoint }}\"" name))))) + (dired (format "/sudo::%s" path)))) + +(defun docker-volume-dired-selection () + "Run `docker-volume-dired' on the volumes selection." + (interactive) + (docker-utils-ensure-items) + (--each (docker-utils-get-marked-items-ids) + (docker-volume-dired it))) + +(defun docker-volume-mark-dangling () + "Mark only the dangling volumes listed in *docker-volumes*. + +This clears any user marks first and respects any tablist filters +applied to the buffer." + (interactive) + (switch-to-buffer "*docker-volumes*") + (tablist-unmark-all-marks) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (when (docker-volume-dangling-p (tabulated-list-get-id)) + (tablist-put-mark)) + (forward-line)))) + +(docker-utils-define-transient-arguments docker-volume-ls) + +(transient-define-prefix docker-volume-ls () + "Transient for listing volumes." + :man-page "docker-volume-ls" + ["Arguments" + ("d" "Dangling" "--filter dangling=true") + ("f" "Filter" "--filter " read-string)] + ["Actions" + ("l" "List" tablist-revert)]) + +(docker-utils-transient-define-prefix docker-volume-rm () + "Transient for removing volumes." + :man-page "docker-volume-rm" + [:description docker-generic-action-description + ("D" "Remove" docker-generic-action-multiple-ids)]) + +(transient-define-prefix docker-volume-help () + "Help transient for docker volumes." + ["Docker volumes help" + ("D" "Remove" docker-volume-rm) + ("I" "Inspect" docker-volume-inspect) + ("d" "Mark Dangling" docker-volume-mark-dangling) + ("f" "Dired" docker-volume-dired-selection) + ("l" "List" docker-volume-ls)]) + +(defvar docker-volume-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "?" 'docker-volume-help) + (define-key map "D" 'docker-volume-rm) + (define-key map "I" 'docker-volume-inspect) + (define-key map "d" 'docker-volume-mark-dangling) + (define-key map "f" 'docker-volume-dired-selection) + (define-key map "l" 'docker-volume-ls) + map) + "Keymap for `docker-volume-mode'.") + +;;;###autoload (autoload 'docker-volumes "docker-volume" nil t) +(defun docker-volumes () + "List docker volumes." + (interactive) + (docker-utils-pop-to-buffer "*docker-volumes*") + (docker-volume-mode) + (tablist-revert)) + +(define-derived-mode docker-volume-mode tabulated-list-mode "Volumes Menu" + "Major mode for handling a list of docker volumes." + (setq tabulated-list-format (docker-utils-columns-list-format docker-volume-columns)) + (setq tabulated-list-padding 2) + (setq tabulated-list-sort-key docker-volume-default-sort-key) + (add-hook 'tabulated-list-revert-hook 'docker-volume-refresh nil t) + (tabulated-list-init-header) + (tablist-minor-mode)) + +(provide 'docker-volume) + +;;; docker-volume.el ends here diff --git a/elpa/docker-20260126.1212/docker.el b/elpa/docker-20260126.1212/docker.el new file mode 100644 index 00000000..48d5929e --- /dev/null +++ b/elpa/docker-20260126.1212/docker.el @@ -0,0 +1,44 @@ +;;; docker.el --- Interface to Docker -*- lexical-binding: t -*- + +;; Author: Philippe Vaucher +;; URL: https://github.com/Silex/docker.el +;; Keywords: filename, convenience +;; Package-Version: 20260126.1212 +;; Package-Revision: 916686b86e83 +;; Package-Requires: ((aio "1.0") (dash "2.19.1") (emacs "28.1") (s "1.13.0") (tablist "1.1") (transient "0.4.3")) + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This package allows you to manipulate docker images, containers & more from Emacs. + +;;; Code: +(eval-when-compile + (setq-local byte-compile-warnings '(not docstrings))) + +(require 'docker-compose) +(require 'docker-container) +(require 'docker-image) +(require 'docker-network) +(require 'docker-volume) +(require 'docker-context) + +(provide 'docker) + +;;; docker.el ends here