From 8a4fd2f83f9a4212bbd761354fc7ed29785b900e Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Mon, 2 Oct 2023 14:25:13 +0200 Subject: [PATCH 1/4] Add specs for missing rails db commands and runner --- src/rails.ts | 81 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/src/rails.ts b/src/rails.ts index 9000d654efc..170bd995898 100644 --- a/src/rails.ts +++ b/src/rails.ts @@ -354,6 +354,20 @@ const dbOptions = [ }, ]; +const environmentOption: Fig.Option = { + name: ["-e", "--environment"], + description: + "Specifies the environment to run this console under (test/development/production)", + args: { + name: "environment", + generators: { + script: "ls config/environments", + postProcess: (out) => + out.split("\n").map((env) => ({ name: env.replace(".rb", "") })), + }, + }, +}; + const defaultCommands: Fig.Subcommand[] = [ { name: ["c", "console"], @@ -363,26 +377,15 @@ const defaultCommands: Fig.Subcommand[] = [ name: ["-s", "--sandbox"], description: "Rollback database modifications on exit", }, - { - name: ["-e", "--environment"], - description: "Specifies the environment to run this console under", - args: { - name: "environment", - }, - }, + environmentOption, ], }, { - name: "server", + name: ["s", "server"], description: "Launch a web server to access your application through a browser", options: [ - { - name: ["-e", "--environment"], - description: - "Specifies the environment to run this server under (e.g. test/development/production)", - args: { name: "environment" }, - }, + environmentOption, { name: ["-p", "--port"], description: "Runs Rails on the specified port - defaults to 3000", @@ -441,16 +444,41 @@ const defaultCommands: Fig.Subcommand[] = [ options: dbOptions, }, { - name: "dbconsole", + name: "db:migrate:redo", + description: "Rollback the last database migration", + args: { + name: "STEP", + isOptional: true, + suggestions: ["STEP="], + }, + options: dbOptions, + }, + { + name: "db:rollback", + description: "Rollback the last database migration", + args: { + name: "STEP", + isOptional: true, + suggestions: ["STEP="], + }, + options: dbOptions, + }, + { + name: "db:drop", + description: "Drop your database", + options: dbOptions, + }, + { + name: "db:version", + description: "Print the current schema version number", + options: dbOptions, + }, + { + name: ["dbconsole", "db"], description: "Opens a console to your database (supports MySQL, PostgreSQL, and SQLite3)", options: [ - { - name: "-e", - description: - "Specifies the environment to run this dbconsole under (e.g. test/development/production)", - args: {}, - }, + environmentOption, { name: "--mode", description: @@ -477,7 +505,16 @@ const defaultCommands: Fig.Subcommand[] = [ ], }, { - name: "generate", + name: "runner", + description: "Run a piece of code in the application environment", + args: { + name: "code", + template: "filepaths", + }, + options: [environmentOption], + }, + { + name: ["g", "generate"], description: "Use templates to generate Rails resources", args: [ { From 5c9a23c661458d53997b3b9d463fd1580212ff0a Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Sat, 2 Dec 2023 22:22:23 +0100 Subject: [PATCH 2/4] Wip setup checkDir function --- src/rails.ts | 66 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/src/rails.ts b/src/rails.ts index 170bd995898..fb414012c17 100644 --- a/src/rails.ts +++ b/src/rails.ts @@ -3,6 +3,49 @@ import { filepaths } from "@fig/autocomplete-generators"; const RB_ICON = "https://raw.githubusercontent.com/vscode-icons/vscode-icons/master/icons/file_type_ruby.svg"; +/** + * @param executeShellCommand + * @param file + * @param contains MAKE sure to escape all double quotes + * + * @returns [true, output] if file is found and contains the string + * @returns [false, "NOT_CONTAINS"] if file is found but does not contain the string + * @returns [false, "NOT_FOUND"] if file is not found + */ +const checkDir = async ( + executeShellCommand: Fig.ExecuteShellCommandFunction, + file: string, + contains?: string +) => { + const checkFileContains = (check: string) => { + return `cat ${file} | grep "${check}" > /dev/null && pwd || echo '_NOT_CONTAINS_'`; + }; + + const output = + await executeShellCommand(`until [[ -f ${file} ]] || [[ $PWD = '/' ]]; do + cd ..; +done; + +if [ -f ${file} ]; then + ${contains ? checkFileContains(contains) : "pwd"} +else + echo '_NOT_FOUND_' +fi`); + + switch (output) { + case "_NOT_CONTAINS_": + return [false, "NOT_CONTAINS"] as const; + case "_NOT_FOUND_": + return [false, "NOT_FOUND"] as const; + default: + return [true, output]; + } +}; + +const getRailsRoot = (executeShellCommand: Fig.ExecuteShellCommandFunction) => { + return checkDir(executeShellCommand, "Gemfile", `gem [\'\\"]rails[\'\\"]`); +}; + const newCommand = { name: "new", description: "Create a new rails application", @@ -357,13 +400,20 @@ const dbOptions = [ const environmentOption: Fig.Option = { name: ["-e", "--environment"], description: - "Specifies the environment to run this console under (test/development/production)", + "Specifies the environment to run this console under (test/development/production/)", args: { name: "environment", + suggestions: ["test", "development", "production"], generators: { - script: "ls config/environments", - postProcess: (out) => - out.split("\n").map((env) => ({ name: env.replace(".rb", "") })), + async custom(token, executeShellCommand) { + const [found, path] = await getRailsRoot(executeShellCommand); + if (!found) return []; + + return (await executeShellCommand(`ls ${path}/config/environments`)) + .split("\n") + .map((env) => env.slice(0, env.indexOf(".rb"))) + .map((env) => ({ name: env })); + }, }, }, }; @@ -667,11 +717,9 @@ const completionSpec: Fig.Spec = { name: "rails", description: "Ruby on Rails CLI", generateSpec: async (_, executeShellCommand) => { - const isRailsDirectory = !!(await executeShellCommand( - `until [[ -f Gemfile ]] || [[ $PWD = '/' ]]; do cd ..; done; if [ -f Gemfile ]; then cat Gemfile | \\grep "gem ['\\"]rails['\\"]"; fi` - )); - - if (!isRailsDirectory) { + console.log("here"); + const [found, _path] = await getRailsRoot(executeShellCommand); + if (!found) { return { name: "rails", subcommands: [newCommand], From 8394cd60ad366995c62bcb1f9bf6ed8b2f4f7400 Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Sat, 2 Dec 2023 22:29:01 +0100 Subject: [PATCH 3/4] Bump to work with new shell command --- src/rails.ts | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/rails.ts b/src/rails.ts index f6f0a839a34..7fda252eff0 100644 --- a/src/rails.ts +++ b/src/rails.ts @@ -13,7 +13,7 @@ const RB_ICON = * @returns [false, "NOT_FOUND"] if file is not found */ const checkDir = async ( - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, file: string, contains?: string ) => { @@ -21,8 +21,11 @@ const checkDir = async ( return `cat ${file} | grep "${check}" > /dev/null && pwd || echo '_NOT_CONTAINS_'`; }; - const output = - await executeShellCommand(`until [[ -f ${file} ]] || [[ $PWD = '/' ]]; do + const output = await executeShellCommand({ + command: "bash", + args: [ + "-c", + `until [[ -f ${file} ]] || [[ $PWD = '/' ]]; do cd ..; done; @@ -30,19 +33,23 @@ if [ -f ${file} ]; then ${contains ? checkFileContains(contains) : "pwd"} else echo '_NOT_FOUND_' -fi`); +fi`, + ], + }); + + if (output.status === 1) return [false, "ERROR"] as const; - switch (output) { + switch (output.stdout) { case "_NOT_CONTAINS_": return [false, "NOT_CONTAINS"] as const; case "_NOT_FOUND_": return [false, "NOT_FOUND"] as const; default: - return [true, output]; + return [true, output.stdout.trim()] as const; } }; -const getRailsRoot = (executeShellCommand: Fig.ExecuteShellCommandFunction) => { +const getRailsRoot = (executeShellCommand: Fig.ExecuteCommandFunction) => { return checkDir(executeShellCommand, "Gemfile", `gem [\'\\"]rails[\'\\"]`); }; @@ -409,7 +416,16 @@ const environmentOption: Fig.Option = { const [found, path] = await getRailsRoot(executeShellCommand); if (!found) return []; - return (await executeShellCommand(`ls ${path}/config/environments`)) + const envs = await executeShellCommand({ + // TODO: fix this + // eslint-disable-next-line + args: [`${path}/config/environments`], + command: "ls", + }); + + console.log(envs); + + return envs.stdout .split("\n") .map((env) => env.slice(0, env.indexOf(".rb"))) .map((env) => ({ name: env })); From 576ea71b26bfcfbb1e74b6ebc29e4a659b9d761e Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Sat, 2 Dec 2023 22:32:08 +0100 Subject: [PATCH 4/4] Remove logs --- src/rails.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rails.ts b/src/rails.ts index 7fda252eff0..d2623f75a9e 100644 --- a/src/rails.ts +++ b/src/rails.ts @@ -423,8 +423,6 @@ const environmentOption: Fig.Option = { command: "ls", }); - console.log(envs); - return envs.stdout .split("\n") .map((env) => env.slice(0, env.indexOf(".rb"))) @@ -741,7 +739,6 @@ const completionSpec: Fig.Spec = { description: "Ruby on Rails CLI", icon: "https://avatars.githubusercontent.com/u/4223?s=48&v=4", generateSpec: async (_, executeShellCommand) => { - console.log("here"); const [found, _path] = await getRailsRoot(executeShellCommand); if (!found) { return {