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: change command api #91

Merged
merged 1 commit into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { createVersionedSpec } from "@fig/autocomplete-helpers";
const versionFiles = ["1.0.0", "2.0.0"];
export const getVersionCommand: Fig.GetVersionCommand = async (
executeShellCommand
) => {
const out = await executeShellCommand("fig --version");
return out.slice(out.indexOf(" ") + 1);
export const getVersionCommand: Fig.GetVersionCommand = async (executeCommand) => {
const { stdout } = await executeCommand({
command: "fig",
args: ["--version"],
});
return stdout.slice(stdout.indexOf(" ") + 1);
};
export default createVersionedSpec("fig", versionFiles);
11 changes: 6 additions & 5 deletions cli/tools-cli/test/versioning/fixtures/case-4/old-spec/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { createVersionedSpec } from "@fig/autocomplete-helpers";
const versionFiles = ["1.0.0", "2.0.0"];
export const getVersionCommand: Fig.GetVersionCommand = async (
executeShellCommand
) => {
const out = await executeShellCommand("fig --version");
return out.slice(out.indexOf(" ") + 1);
export const getVersionCommand: Fig.GetVersionCommand = async (executeCommand) => {
const { stdout } = await executeCommand({
command: "fig",
args: ["--version"],
});
return stdout.slice(stdout.indexOf(" ") + 1);
};
export default createVersionedSpec("fig", versionFiles);
28 changes: 14 additions & 14 deletions generators/src/ai.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export type GeneratorFn<T> = (args: {
tokens: string[];
executeShellCommand: Fig.ExecuteShellCommandFunction;
executeCommand: Fig.ExecuteCommandFunction;
generatorContext: Fig.GeneratorContext;
}) => Promise<T> | T;

Expand Down Expand Up @@ -35,20 +35,21 @@ export function ai({
}): Fig.Generator {
return {
scriptTimeout: 15000,
custom: async (tokens, executeShellCommand, generatorContext) => {
const enabled = await executeShellCommand(
"fig settings --format json autocomplete.ai.enabled"
);
custom: async (tokens, executeCommand, generatorContext) => {
const settingOutput = await executeCommand({
command: "fig",
args: ["settings", "--format", "json", "autocomplete.ai.enabled"],
});

if (!JSON.parse(enabled)) {
if (!JSON.parse(settingOutput.stdout)) {
return [];
}

const promptString =
typeof prompt === "function"
? await prompt({
tokens,
executeShellCommand,
executeCommand,
generatorContext,
})
: prompt;
Expand All @@ -57,7 +58,7 @@ export function ai({
typeof message === "function"
? await message({
tokens,
executeShellCommand,
executeCommand,
generatorContext,
})
: message;
Expand Down Expand Up @@ -91,13 +92,12 @@ export function ai({
};

const bodyJson = JSON.stringify(body);
const escapedBodyJson = bodyJson.replace(/'/g, "'\"'\"'");

const res = await executeShellCommand(
`fig _ request --route /ai/chat --method POST --body '${escapedBodyJson}'`
);

const json = JSON.parse(res);
const requestOutput = await executeCommand({
command: "fig",
args: ["_", "request", "--route", "/ai/chat", "--method", "POST", "--body", bodyJson],
});
const json = JSON.parse(requestOutput.stdout);

const a =
json?.choices
Expand Down
10 changes: 7 additions & 3 deletions generators/src/filepaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function filepathsFn(options: FilepathsOptions = {}): Fig.Generator {
},
getQueryTerm: (token) => token.slice(token.lastIndexOf("/") + 1),

custom: async (_, executeShellCommand, generatorContext) => {
custom: async (_, executeCommand, generatorContext) => {
const { isDangerous, currentWorkingDirectory, searchTerm } = generatorContext;
const currentInsertedDirectory =
getCurrentInsertedDirectory(
Expand All @@ -187,8 +187,12 @@ function filepathsFn(options: FilepathsOptions = {}): Fig.Generator {

try {
// Use \ls command to avoid any aliases set for ls.
const data = await executeShellCommand("command ls -1ApL", currentInsertedDirectory);
const sortedFiles = sortFilesAlphabetically(data.split("\n"), [".DS_Store"]);
const data = await executeCommand({
command: "ls",
args: ["-1ApL"],
cwd: currentInsertedDirectory,
});
const sortedFiles = sortFilesAlphabetically(data.stdout.split("\n"), [".DS_Store"]);

const generatorOutputArray: Fig.TemplateSuggestion[] = [];
// Then loop through them and add them to the generatorOutputArray
Expand Down
65 changes: 17 additions & 48 deletions generators/test/filepaths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,33 +140,19 @@
});

describe("Test filepaths generators", () => {
let globalSSHString: string;
let currentCWD: string;
let executeCommand: sinon.SinonStub;

async function executeCommandInDir(
command: string,
dir: string,
sshContextString?: string,
timeout?: number
): Promise<string> {
const inputDir = dir.replace(/[\s()[\]]/g, "\\$&");
let commandString = `cd ${inputDir} && ${command} | cat`;

if (sshContextString) {
commandString = commandString.replace(/'/g, `'"'"'`);
commandString = `${sshContextString} '${commandString}'`;
}

return executeCommand(commandString, timeout && timeout > 0 ? timeout : undefined);
}
let executeCommandStub: sinon.SinonStub;

async function executeShellCommand(cmd: string, overrideCWD?: string): Promise<string> {
async function executeCommand(args: Fig.ExecuteCommandInput): Promise<Fig.ExecuteCommandOutput> {
try {
return executeCommandInDir(cmd, overrideCWD ?? currentCWD, globalSSHString);
return executeCommandStub(args);
} catch (err) {
return new Promise((resolve) => {
resolve("");
resolve({
stdout: "",
stderr: "",
status: 1,
});
});
}
}
Expand All @@ -176,20 +162,19 @@
mockLSResults: string[],
context = defaultContext
): Promise<string[]> {
executeCommand.resolves(mockLSResults.join("\n"));
return (await filepaths(options).custom!([], executeShellCommand, context)).map(toName);
executeCommandStub.resolves(mockLSResults.join("\n"));
return (await filepaths(options).custom!([], executeCommand, context)).map(toName);

Check warning on line 166 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion

Check warning on line 166 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion
}

beforeEach(() => {
executeCommand = sinon.stub();
executeCommandStub = sinon.stub();
// these steps are approximately the ones performed by the engine before running a generator
globalSSHString = "";
currentCWD = "~/current_cwd/";
defaultContext.currentWorkingDirectory = currentCWD;
});

afterEach(() => {
executeCommand.resetHistory();
executeCommandStub.resetHistory();
});

after(() => {
Expand Down Expand Up @@ -224,8 +209,8 @@
describe("should return filepaths suggestions", () => {
const suggestions = ["a/", "c/", "l", "x"];
it("should show all suggestions when no options or search term is specified", async () => {
executeCommand.resolves(suggestions.join("\n"));
expect(await filepaths.custom!([], executeShellCommand, defaultContext)).to.eql(
executeCommandStub.resolves(suggestions.join("\n"));
expect(await filepaths.custom!([], executeCommand, defaultContext)).to.eql(

Check warning on line 213 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion

Check warning on line 213 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion
[
{ insertValue: "a/", name: "a/", type: "folder", context: { templateType: "folders" } },
{ insertValue: "c/", name: "c/", type: "folder", context: { templateType: "folders" } },
Expand Down Expand Up @@ -395,7 +380,7 @@

describe("deprecated sshPrefix", () => {
it("should call executeCommand with default user input dir ignoring ssh", async () => {
await filepaths.custom!([], executeShellCommand, {
await filepaths.custom!([], executeCommand, {

Check warning on line 383 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion

Check warning on line 383 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion
...defaultContext,
sshPrefix: "ssh -i blabla",
});
Expand All @@ -405,20 +390,6 @@
undefined
);
});

it("should call executeCommand with specified user input dir ignoring ssh but adding the global ssh string", async () => {
globalSSHString = "some_ssh_string";
await filepaths({ rootDirectory: "/etc" }).custom!([], executeShellCommand, {
...defaultContext,
searchTerm: "some_path/",
sshPrefix: "ssh -i blabla",
});

expect(executeCommand).to.have.been.calledWith(
"some_ssh_string 'cd /etc/some_path/ && command ls -1ApL | cat'",
undefined
);
});
});
});

Expand All @@ -427,10 +398,8 @@
const passing: string[] = ["folder1.txt/", "folder2.txt/", "folder3/"];
const failing: string[] = ["file1.test.js", "file2.js", "file3.mjs", "file4.ts"];

executeCommand.resolves(passing.concat(failing).join("\n"));
const results = (await folders().custom!([], executeShellCommand, defaultContext)).map(
toName
);
executeCommandStub.resolves(passing.concat(failing).join("\n"));
const results = (await folders().custom!([], executeCommand, defaultContext)).map(toName);

Check warning on line 402 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion

Check warning on line 402 in generators/test/filepaths.test.ts

View workflow job for this annotation

GitHub Actions / lint

Forbidden non-null assertion

expect(results).to.eql(passing.concat("../"));
});
Expand Down
23 changes: 16 additions & 7 deletions generators/test/keyvalue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@ function testSuggestions(
generator: Fig.Generator
): (token: string, expected: Fig.Suggestion[]) => Promise<void> {
return async (token, expected) => {
const result = await generator.custom?.(["spec", token], () => Promise.resolve(""), {
searchTerm: "",
currentProcess: "",
currentWorkingDirectory: "",
sshPrefix: "",
environmentVariables: {},
});
const result = await generator.custom?.(
["spec", token],
() =>
Promise.resolve({
status: 1,
stderr: "",
stdout: "",
}),
{
searchTerm: "",
currentProcess: "",
currentWorkingDirectory: "",
sshPrefix: "",
environmentVariables: {},
}
);
expect(result).to.deep.equal(expected);
};
}
Expand Down
3 changes: 2 additions & 1 deletion helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
"devDependencies": {
"@tsconfig/recommended": "^1.0.1",
"@types/jest": "^27.5.0",
"@types/node": "^20.8.10",
"@types/prettier": "^2.6.0",
"@types/semver": "^7.3.9",
"@withfig/autocomplete-types": "^1.15.0",
"@withfig/autocomplete-types": "workspace:^",
"jest": "^28.0.3",
"prettier": "^2.6.2",
"ts-jest": "^28.0.0",
Expand Down
3 changes: 2 additions & 1 deletion shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
"devDependencies": {
"@tsconfig/recommended": "^1.0.1",
"@types/jest": "^27.5.0",
"@types/node": "^20.8.10",
"@types/semver": "^7.3.9",
"@withfig/autocomplete-types": "^1.15.0",
"@withfig/autocomplete-types": "workspace:^",
"jest": "^28.0.3",
"prettier": "^2.6.2",
"ts-jest": "^28.0.0",
Expand Down
Loading
Loading