Skip to content

fix(generate): add support for Expo Router app directory prompts #2905

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

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 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
56 changes: 52 additions & 4 deletions src/commands/generate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GluegunToolbox } from "gluegun"
import { boolFlag } from "../tools/flag"
import { generateFromTemplate, runGenerator } from "../tools/generators"
import { command, heading, p, warning } from "../tools/pretty"
import { frontMatterDirectoryDir, generateFromTemplate, runGenerator } from "../tools/generators"
import { command, heading, p, prettyPrompt, warning } from "../tools/pretty"
import { Options } from "./new"

const SUB_DIR_DELIMITER = "/"
Expand All @@ -16,13 +16,13 @@ module.exports = {
}

async function generate(toolbox: GluegunToolbox) {
const { parameters, strings } = toolbox
const { parameters, strings, filesystem, prompt } = toolbox

// what generator are we running?
const generator = parameters.first.toLowerCase()

// check if we should override front matter dir or default dir
const dir = parameters.options.dir ?? parameters.third
let dir = parameters.options.dir ?? parameters.third

// we need a name for this component
let name = parameters.second
Expand Down Expand Up @@ -52,6 +52,54 @@ async function generate(toolbox: GluegunToolbox) {
pascalName = pascalName.slice(0, -1 * pascalGenerator.length)
command(`npx ignite-cli generate ${generator} ${pascalName}`)
}
// Check if src/app exists, denoting an Expo Router app
Copy link
Contributor

Choose a reason for hiding this comment

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

this comment could use updating now that we changed the strategy to look at package.json

if (generator === "screen") {
const packageJson = filesystem.read("package.json", "json")
const isExpoRouterApp = !!packageJson?.dependencies?.["expo-router"]

if (isExpoRouterApp) {
const directoryDirSetInFrontMatter = frontMatterDirectoryDir("screen")

if (directoryDirSetInFrontMatter || dir) {
heading(
`It looks like you're working in a project using Expo Router, determined directory for screen from ${dir ? "override" : "template front matter"}`,
)
dir = dir || directoryDirSetInFrontMatter
} else {
const result = await prompt.ask({
type: "input",
name: "dir",
message:
"It looks like you're working in a project using Expo Router, please enter the desired directory (e.g., src/app):",
})

if (result.dir) {
// Validate the directory
const isValidDir = filesystem.exists(result.dir) === "dir"
if (isValidDir) {
dir = result.dir
} else {
const createDirResult = await prompt.ask({
type: "confirm",
name: "createDir",
message: `⚠️ Directory ${result.dir} does not exist. Would you like to create it?`,
initial: true,
format: prettyPrompt.format.boolean,
})

if (createDirResult.createDir) {
filesystem.dir(result.dir)
dir = result.dir
} else {
warning(`⚠️ Placing screen in src/app root.`)
p()
dir = "src/app"
Copy link
Contributor

@frankcalise frankcalise Mar 5, 2025

Choose a reason for hiding this comment

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

I'm thinking this still needs to detect if src/app exists or app exists - as it could be either if not coming from an Ignite project

maybe we can set it to be the default of the prompt since it's the example in the message anyway

}
}
}
}
}
}

// okay, let's do it!
p()
Expand Down
23 changes: 23 additions & 0 deletions src/tools/generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,29 @@ export async function generateFromTemplate(
return { written, exists, overwritten }
}

/**
* Checks a file for a directoryDir in template front matter.
*/
export function frontMatterDirectoryDir(generator: string): "string" | undefined {
if (!validateGenerator(generator)) {
return undefined
}

const { path } = filesystem

// where are we copying from?
const templateDir = path(templatesDir(), generator)

const fileContents = filesystem.read(`${templateDir}/NAME.tsx.ejs`)
const { data: frontMatterData } = frontMatter(fileContents)

if (frontMatterData?.destinationDir === undefined) {
return undefined
}

return frontMatterData.destinationDir
}

/**
* Ignite cli root directory
*/
Expand Down