Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docker): enhance docker completion #805

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

xwjdsh
Copy link
Contributor

@xwjdsh xwjdsh commented Dec 27, 2021

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.

@withfig-bot
Copy link
Collaborator

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
Copy link
Collaborator

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.

Copy link
Member

@mschrage mschrage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @xwjdsh! This looks really good - I love the automatically generated completion spec. The issue we need to resolve before we get this merged in is that all of the generators are gone.

These add a lot of value to Fig by providing dynamic suggestions. Can we try to merge them back in? We have a merge utility tool that might be helpful here: https://github.com/withfig/autocomplete-tools/tree/main/packages/autocomplete-tools

@fedeci
Copy link
Contributor

fedeci commented Dec 30, 2021

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😄

@xwjdsh
Copy link
Contributor Author

xwjdsh commented Dec 31, 2021

@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
Copy link
Contributor Author

xwjdsh commented Jan 17, 2022

Any updates?

@fedeci
Copy link
Contributor

fedeci commented Jan 21, 2022

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?

@xwjdsh
Copy link
Contributor Author

xwjdsh commented Jan 21, 2022

🥲 OK, I'll update this.

@mschrage
Copy link
Member

recheck

@withfig-bot
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants