autocomplete icon indicating copy to clipboard operation
autocomplete copied to clipboard

feat(docker): enhance docker completion

Open xwjdsh opened this issue 3 years ago • 9 comments
trafficstars

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...) feature

What is the current behavior? (You can also link to an open issue here)

What is the new behavior (if this is a feature change)?

Additional info: After #796 , I noticed that the docker prompt items were still missing a lot, so I tried to parse all docker subcommands and generate the docker.ts file, that’s https://github.com/xwjdsh/completion-gen (I’m not very familiar with JavaScript, so using Golang to do this). I trying to keep the migration of previous features, but there is no guarantee that there are no omissions, I am willing to revise any suggestions and omissions.

xwjdsh avatar Dec 27 '21 10:12 xwjdsh

Overview

src/docker.ts:

Info:

Script: docker images --format '{{.Repository}} {{.Size}} {{.Tag}} {{.ID}}' postProcess(function):

 function (out) {
            return out.split("\n").map((image) => {
              const [repo, size, tag, id] = image.split(" ");
              return {
                name: repo,
                description: `${id}@${tag} - ${size}`,
                icon: "fig://icon?type=docker",
              };
            });
          }

Single Functions:

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: `${i.ID}`,
          displayName: `${i.Repository} - ${i.ID}`,
          icon: "fig://icon?type=docker",
        }));
    }

script:

 function (context) {
      if (context[context.length - 1] === "") return "";
      const searchTerm = context[context.length - 1];
      return `docker search ${searchTerm} --format '{{ json . }}'`;
    }

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: `${i.Name}`,
          icon: "fig://icon?type=docker",
        }));
    }

trigger:

 function () {
      return true;
    }

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: i.Name,
          description: i.Description,
          icon: "fig://icon?type=docker",
        }));
    }

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: i.ID,
          displayName: `${i.ID} - ${i.Hostname}`,
          description: i.Status,
          icon: "fig://icon?type=docker",
        }));
    }

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: i.Name,
          description: i.Image,
          icon: "fig://icon?type=docker",
        }));
    }

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: `${i.Name}=`,
          description: i.Image,
          icon: "fig://icon?type=docker",
        }));
    }

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: i.Name,
          icon: "fig://icon?type=docker",
        }));
    }

postProcess:

 function (out) {
      return out
        .split("\n")
        .map((line) => JSON.parse(line))
        .map((i) => ({
          name: i.Name,
          icon: "fig://icon?type=docker",
        }));
    }

postProcess:

 function (out) {
            const allLines = out.split("\n").map((line) => JSON.parse(line));
            return allLines.map((i) => ({
              name: i.ID,
              displayName: `[con] ${i.ID} (${i.Image})`,
            }));
          }

postProcess:

 function (out) {
            const allLines = out.split("\n").map((line) => JSON.parse(line));
            return allLines.map((i) => {
              let displayName;
              if (i.Repository === "\u003cnone\u003e") {
                displayName = i.ID;
              } else {
                displayName = i.Repository;
                if (i.Tag !== "\u003cnone\u003e") {
                  displayName += `:${i.Tag}`;
                }
              }

              return {
                name: i.ID,
                displayName: `[img] ${displayName}`,
              };
            });
          }

postProcess:

 function (out) {
            const allLines = out.split("\n").map((line) => JSON.parse(line));
            return allLines.map((i) => ({
              name: i.Name,
              displayName: `[vol] ${i.Name}`,
            }));
          }

trigger:

 function () {
          return true;
        }

script:

 function (context) {
          let fileFlagIndex, dockerfilePath;
          if (context.includes("-f")) {
            fileFlagIndex = context.indexOf("-f");
            dockerfilePath = context[fileFlagIndex + 1];
          } else if (context.includes("--file")) {
            fileFlagIndex = context.indexOf("--file");
            dockerfilePath = context[fileFlagIndex + 1];
          } else {
            dockerfilePath = "$PWD/Dockerfile";
          }

          return `\grep -iE 'FROM.*AS' "${dockerfilePath}"`;
        }

postProcess:

 function (out) {
          // This just searches the Dockerfile for the alias name after AS,
          // and due to the grep above, will only match lines where FROM and AS
          // are on the same line. This could certainly be made more robust
          // down the line.
          const imageNameRegexp = /(?:[aA][sS]\s+)([\w:.-]+)/;
          return out
            .split("\n")
            .map((i) => {
              const result = imageNameRegexp.exec(i);
              if (result) {
                return {
                  name: result[1],
                };
              }
            })
            .filter((i) => i !== undefined);
        }

withfig-bot avatar Dec 27 '21 10:12 withfig-bot

Hello @xwjdsh, thank you very much for creating a Pull Request! Here is a small checklist to get this PR merged as quickly as possible:

  • [ ] Do all subcommands / options which take arguments include the args property (args: {})?
  • [ ] Are all options modular? E.g. -a -u -x instead of -aux
  • [ ] Have all other checks passed?

Please add a 👍 as a reaction to this comment to show that you read this.

withfig-bot avatar Dec 27 '21 10:12 withfig-bot

I haven't had a chance to look into this but if the merge tool can successfully work here we can assume it is battle-tested😄

fedeci avatar Dec 30 '21 21:12 fedeci

@mschrage The generators are still there, I put them at the end, by dynamically modifying completionSpec. The diff is huge, you can check this file: https://github.com/xwjdsh/completion-gen/blob/main/tmpls/docker.tmpl, the first line {{ template "base.tmpl" . }} represents the generated part and the rest is the dynamically modified part.

xwjdsh avatar Dec 31 '21 05:12 xwjdsh

Any updates?

xwjdsh avatar Jan 17 '22 13:01 xwjdsh

Hi @xwjdsh, sorry for the late reply. I am trying to review the spec but it is basically impossible :(. Could you try to move the generators back to the top to see if that improves the diff?

fedeci avatar Jan 21 '22 16:01 fedeci

:smiling_face_with_tear: OK, I'll update this.

xwjdsh avatar Jan 21 '22 17:01 xwjdsh

recheck

mschrage avatar Oct 12 '23 19:10 mschrage

CLA Assistant Lite bot:
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request

withfig-bot avatar Oct 12 '23 19:10 withfig-bot