Skip to content

Commit

Permalink
feat(repl): add help function
Browse files Browse the repository at this point in the history
  • Loading branch information
tsirysndr committed Jan 23, 2024
1 parent b4094d9 commit 950bfb0
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 46 deletions.
5 changes: 4 additions & 1 deletion deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ export {
ZipReader,
ZipWriter,
} from "https://deno.land/x/zipjs@v2.7.32/index.js";
import introspect from "https://cdn.jsdelivr.net/gh/fluentci-io/daggerverse@main/deno-sdk/sdk/src/mod/introspect.ts";
import introspect, {
Metadata,
} from "https://cdn.jsdelivr.net/gh/fluentci-io/daggerverse@main/deno-sdk/sdk/src/mod/introspect.ts";
export { introspect };
export type { Metadata };
export { wait } from "https://deno.land/x/wait@0.1.13/mod.ts";
import * as _ from "https://cdn.skypack.dev/lodash";
export { _ };
Expand Down
2 changes: 1 addition & 1 deletion main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ export async function main() {
.option("--ap, --azure", "Show Azure Pipelines documentation")
.option("--ac, --aws", "Show AWS CodePipeline documentation")
.action(async function (options, pipeline) {
await docs(options, pipeline);
await docs(pipeline, options);
})
.command("doctor", "Check if FluentCI CLI is installed correctly")
.action(async function () {
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { green } from "../../deps.ts";
import { BASE_URL } from "../consts.ts";

async function docs(
pipeline = ".",
options: {
gl?: unknown;
gh?: unknown;
cci?: unknown;
ap?: unknown;
ac?: unknown;
},
pipeline = "."
} = {}
) {
// verify if glow is installed

Expand Down
2 changes: 1 addition & 1 deletion src/cmd/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const BASE_URL = "https://api.fluentci.io/v1";
* @returns {Promise<void>}
*/
async function init(
{ template, standalone }: { template?: string; standalone?: boolean },
{ template, standalone }: { template?: string; standalone?: boolean } = {},
_name?: string
) {
const infos = await promptPackageDetails(standalone);
Expand Down
171 changes: 152 additions & 19 deletions src/cmd/repl.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,60 @@
import {
SpinnerTypes,
TerminalSpinner,
Metadata,
magenta,
introspect,
green,
cyan,
bold,
yellow,
} from "../../deps.ts";
import { BASE_URL } from "../consts.ts";
import { extractVersion, fluentciDirExists } from "../utils.ts";

async function repl({ debug }: { debug?: boolean }, pipelines: string[]) {
const terminalSpinner = new TerminalSpinner({
text: `Loading functions ...`,
spinner: SpinnerTypes.dots,
});
terminalSpinner.start();

const isFluentciProject = await fluentciDirExists();
const parsedPipelines = await parsePipelines(pipelines);
const args = [];

if (isFluentciProject) {
const metadata = introspect("./.fluentci/mod.ts");
const functions = metadata.map((fn) => fn.functionName).join(", ");
args.push(`--eval=import {${functions}} from "./.fluentci/mod.ts"`);
args.push(`--eval=
import {${functions}} from "./.fluentci/mod.ts";
function help() {
${(await descriptions(metadata, parsedPipelines))
.map(
(x) =>
`console.log("${x.job ? yellow(x.name) : cyan(x.name)} ${
x.description
}")`
)
.join(";\n")}
}
`);
} else {
args.push(`--eval=
function help() {
${(await descriptions([], parsedPipelines))
.map(
(x) =>
`console.log("${x.job ? yellow(x.name) : cyan(x.name)} ${
x.description
}")`
)
.join(";\n")}
}
`);
}

for (const pipeline of pipelines) {
const name = pipeline.split("@")[0];
let version = extractVersion(pipeline);

const result = await fetch(`${BASE_URL}/pipeline/${name}`);
const data = await result.json();

if (!data.github_url && !data.version) {
console.log(
`Pipeline template ${green('"')}${green(name)}${green(
'"'
)} not found in Fluent CI registry`
);
Deno.exit(1);
}
version =
version === "latest" ? data.version || data.default_branch : version;
for (const { name, version } of parsedPipelines) {
if (args.length > 0) {
args[0] = `${args[0]};import * as ${name.replaceAll(
"_pipeline",
Expand All @@ -49,6 +70,8 @@ async function repl({ debug }: { debug?: boolean }, pipelines: string[]) {
}
}

terminalSpinner.succeed("Functions loaded!");

const port = Math.floor(Math.random() * (65535 - 1024 + 1)) + 1024;
const dagger = await startDagger(port, debug);
const command = new Deno.Command("deno", {
Expand Down Expand Up @@ -79,7 +102,16 @@ async function repl({ debug }: { debug?: boolean }, pipelines: string[]) {
Welcome to the ${magenta("FluentCI REPL!")}
You can call any ${green("FluentCI Pipeline function")} or any ${green(
"fluentci command"
)} (as a function) here.`);
)} (as a function) here.
Enter ${green("help()")} to see a list of available functions.
${bold("Examples:")}
await docs();
await run();
await ls();
await client.container().from('alpine').withExec(['echo', 'hello']).stdout();
`);

const process = command.spawn();
await process.status;
Expand Down Expand Up @@ -138,4 +170,105 @@ async function startDagger(port: number, debug?: boolean) {
return process;
}

async function descriptions(
metadata: Metadata[],
parsedPipelines: { name: string; version: string }[]
) {
const descriptions: { name: string; description: string; job?: boolean }[] = [
{
name: "client",
description: `a default ${bold(
"Dagger Client"
)} for interacting with Dagger`,
job: true,
},
{
name: "ls",
description:
"list all available functions in the current pipeline or a specific pipeline",
},
{
name: "docs",
description:
"open documentation for the current pipeline or a specific pipeline from the package registry",
},
{
name: "run",
description:
"run the current pipeline or a specific pipeline from the package registry",
},
{
name: "upgrade",
description: "upgrade FluentCI CLI to the latest version",
},
{
name: "init",
description: "initialize a new pipeline",
},
{
name: "search",
description: "search for reusable pipelines",
},
{
name: "cache",
description: "cache remote dependencies of a pipeline",
},
{
name: "doctor",
description: "diagnose and fix common FluentCI issues",
},
{
name: "whoami",
description: "display the currently logged in user",
},
];
for (const fn of metadata) {
descriptions.push({
name: fn.functionName,
description: fn.doc || "",
job: true,
});
}
for (const { name, version } of parsedPipelines) {
const x = await import(`https://pkg.fluentci.io/${name}@${version}/mod.ts`);
const { jobDescriptions } = x;
for (const job of Object.keys(jobDescriptions)) {
descriptions.push({
name: `${name.replaceAll("_pipeline", "")}.${job}`,
description: jobDescriptions[job] || "",
job: true,
});
}
}
return descriptions.sort((a, b) => a.name.localeCompare(b.name));
}

async function parsePipelines(pipelines: string[]) {
const results = [];
for (const pipeline of pipelines) {
const name = pipeline.split("@")[0];
let version = extractVersion(pipeline);

const result = await fetch(`${BASE_URL}/pipeline/${name}`);
const data = await result.json();

if (!data.github_url && !data.version) {
console.log(
`Pipeline template ${green('"')}${green(name)}${green(
'"'
)} not found in Fluent CI registry`
);
Deno.exit(1);
}
version =
version === "latest" ? data.version || data.default_branch : version;
results.push({
name,
version,
});
}

return results;
}

export default repl;
8 changes: 4 additions & 4 deletions src/cmd/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import { getAccessToken, isLogged, extractVersion } from "../utils.ts";
* @throws An error if the pipeline fails to run.
*/
async function run(
pipeline: string,
jobs: [string, ...Array<string>],
options: Record<string, string | number | boolean | undefined>
pipeline = ".",
jobs: [string, ...Array<string>] | string[] = [],
options: Record<string, string | number | boolean | undefined> = {}
) {
await load({
envPath: ".fluentci/.env",
Expand Down Expand Up @@ -204,7 +204,7 @@ const spawnCommand = async (command: Deno.Command) => {

const runPipelineRemotely = async (
pipeline: string,
jobs: [string, ...Array<string>],
jobs: [string, ...Array<string>] | string[],
denoModule?: string[]
) => {
if (!(await isLogged())) {
Expand Down
36 changes: 18 additions & 18 deletions src/prelude.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import run from "https://deno.land/x/fluentci@v0.10.9/src/cmd/run.ts";
import init from "https://deno.land/x/fluentci@v0.10.9/src/cmd/init.ts";
import search from "https://deno.land/x/fluentci@v0.10.9/src/cmd/search.ts";
import run from "https://deno.land/x/fluentci/src/cmd/run.ts";
import init from "https://deno.land/x/fluentci/src/cmd/init.ts";
import search from "https://deno.land/x/fluentci/src/cmd/search.ts";
import upgrade, {
checkForUpdate,
} from "https://deno.land/x/fluentci@v0.10.9/src/cmd/upgrade.ts";
import listJobs from "https://deno.land/x/fluentci@v0.10.9/src/cmd/list.ts";
import generateWorkflow from "https://deno.land/x/fluentci@v0.10.9/src/cmd/github.ts";
import generateGitlabCIConfig from "https://deno.land/x/fluentci@v0.10.9/src/cmd/gitlab.ts";
import generateAWSCodePipelineConfig from "https://deno.land/x/fluentci@v0.10.9/src/cmd/aws.ts";
import generateAzurePipelinesConfig from "https://deno.land/x/fluentci@v0.10.9/src/cmd/azure.ts";
import generateCircleCIConfig from "https://deno.land/x/fluentci@v0.10.9/src/cmd/circleci.ts";
import docs from "https://deno.land/x/fluentci@v0.10.9/src/cmd/docs.ts";
import cache from "https://deno.land/x/fluentci@v0.10.9/src/cmd/cache.ts";
import doctor from "https://deno.land/x/fluentci@v0.10.9/src/cmd/doctor.ts";
import showEnvs from "https://deno.land/x/fluentci@v0.10.9/src/cmd/env.ts";
import login from "https://deno.land/x/fluentci@v0.10.9/src/cmd/login.ts";
import publish from "https://deno.land/x/fluentci@v0.10.9/src/cmd/publish.ts";
} from "https://deno.land/x/fluentci/src/cmd/upgrade.ts";
import listJobs from "https://deno.land/x/fluentci/src/cmd/list.ts";
import generateWorkflow from "https://deno.land/x/fluentci/src/cmd/github.ts";
import generateGitlabCIConfig from "https://deno.land/x/fluentci/src/cmd/gitlab.ts";
import generateAWSCodePipelineConfig from "https://deno.land/x/fluentci/src/cmd/aws.ts";
import generateAzurePipelinesConfig from "https://deno.land/x/fluentci/src/cmd/azure.ts";
import generateCircleCIConfig from "https://deno.land/x/fluentci/src/cmd/circleci.ts";
import docs from "https://deno.land/x/fluentci/src/cmd/docs.ts";
import cache from "https://deno.land/x/fluentci/src/cmd/cache.ts";
import doctor from "https://deno.land/x/fluentci/src/cmd/doctor.ts";
import showEnvs from "https://deno.land/x/fluentci/src/cmd/env.ts";
import login from "https://deno.land/x/fluentci/src/cmd/login.ts";
import publish from "https://deno.land/x/fluentci/src/cmd/publish.ts";
import startAgent, {
listAgents,
} from "https://deno.land/x/fluentci@v0.10.9/src/cmd/agent.ts";
import whoami from "https://deno.land/x/fluentci@v0.10.9/src/cmd/whoami.ts";
} from "https://deno.land/x/fluentci/src/cmd/agent.ts";
import whoami from "https://deno.land/x/fluentci/src/cmd/whoami.ts";
import { Client } from "https://esm.sh/@dagger.io/dagger@0.9.6";
import { GraphQLClient } from "https://esm.sh/graphql-request@6.1.0";

Expand Down

0 comments on commit 950bfb0

Please sign in to comment.