Skip to content

Commit

Permalink
perf: extract context type in background (#384)
Browse files Browse the repository at this point in the history
Co-authored-by: Jason Kuhrt <kuhrt@prisma.io>
  • Loading branch information
Weakky and Jason Kuhrt authored Mar 3, 2020
1 parent e224cba commit 2eacc8a
Show file tree
Hide file tree
Showing 15 changed files with 253 additions and 214 deletions.
56 changes: 0 additions & 56 deletions .circleci/config.yml

This file was deleted.

1 change: 1 addition & 0 deletions .github/workflows/trunk-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,5 @@ jobs:
echo "Failed to extract version"
exit 1
fi
yarn test:e2e
12 changes: 8 additions & 4 deletions src/cli/commands/__default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@ export class __Default implements Command {
switch (projectType.type) {
case 'new':
log.trace(
'detected CWD is empty and not within an existing nexus project, delegating to create sub-command'
'detected CWD is empty and not within an existing nexus project, delegating to create sub-command',
{ cwd: process.cwd() }
)
await runCreateApp({
projectName: CWDProjectNameOrGenerate(),
})
break
case 'NEXUS_project':
log.trace(
'detected CWD is within a nexus project, delegating to dev mode'
'detected CWD is within a nexus project, delegating to dev mode',
{ cwd: process.cwd() }
)
await new Dev().parse([])
break
case 'node_project':
log.trace(
'detected CWD is within a node but not nexus project, aborting'
'detected CWD is within a node but not nexus project, aborting',
{ cwd: process.cwd() }
)
console.log(
"Looks like you are inside a node but not nexus project. Please either add nexus to this project's dependencies and re-run this command or navigate to a new empty folder that does not have a package.json file present in an anecestor directory."
Expand All @@ -42,7 +45,8 @@ export class __Default implements Command {
// name and then changing into that directory.
const projectName = generateProjectName()
log.info(
`creating ./${projectName} where all subsequent work will occur`
`creating project directory where all subsequent work will occur`,
{ cwd: process.cwd(), projectName: projectName }
)
await fs.dirAsync(projectName)
process.chdir(fs.path(projectName))
Expand Down
15 changes: 11 additions & 4 deletions src/cli/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env node

import { stripIndent } from 'common-tags'
import * as dotenv from 'dotenv'
import * as Path from 'path'
import { isError } from 'util'
import * as Layout from '../framework/layout'
import { CLI, HelpError } from '../lib/cli'
Expand Down Expand Up @@ -28,25 +30,30 @@ main().then(exitCode => {

/**
* Check that this nexus process is being run from a locally installed
* veresion unless there is local project or the local project does not have
* version unless there is no local project or the local project does not have
* nexus installed.
*/
async function guardNotGlobalCLIWithLocalProject(
packageManager: PackageManager.PackageManager
): Promise<void> {
// TODO data is attainable from layout scan calculated later on... not optimal to call this twice...
const projectType = await Layout.scanProjectType()

if (
projectType.type === 'NEXUS_project' &&
isProcessFromProjectBin(projectType.packageJsonPath)
isProcessFromProjectBin(projectType.packageJsonLocation.path)
) {
// TODO make npm aware
fatal(stripIndent`
You are using the nexus cli from a location other than this project.
Location of the nexus CLI you executed: ${process.argv[1]}
Location of the nexus CLI for this project: ${projectType.packageJsonPath +
'/node_modules/.bin/nexus'}
Location of the nexus CLI for this project: ${Path.join(
projectType.packageJsonLocation.dir,
'node_modules',
'.bin',
'nexus'
)}
Please use the nexus CLI for this project:
Expand Down
2 changes: 1 addition & 1 deletion src/framework/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export function create(): App {
// At build time we inline static imports.
// This code MUST run after user/system has had chance to run global installation
if (process.env.NEXUS_STAGE === 'dev') {
Layout.schema.importModules()
await Layout.schema.importModules()
}

const nexusConfig = Schema.createInternalConfig(plugins)
Expand Down
65 changes: 40 additions & 25 deletions src/framework/layout/layout.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import Chalk from 'chalk'
import { stripIndent } from 'common-tags'
import * as fs from 'fs-jetpack'
import * as FS from 'fs-jetpack'
import * as Path from 'path'
import { PackageJson } from 'type-fest'
import { findConfigFile, findFile, stripExt } from '../../utils'
import {
findDirContainingFileRecurisvelyUpwardSync,
findFile,
stripExt,
} from '../../utils'
import { rootLogger } from '../../utils/logger'
import * as PackageManager from '../../utils/package-manager'
import * as Schema from './schema-modules'
Expand Down Expand Up @@ -125,7 +129,7 @@ export function createFromData(layoutData: Data): Layout {
export const scan = async (): Promise<ScanResult> => {
log.trace('starting scan...')
const packageManagerType = await PackageManager.detectProjectPackageManager()
const maybeAppModule = await findAppModule()
const maybeAppModule = findAppModule()
const maybeSchemaModules = Schema.findDirOrModules()

// TODO do not assume app module is at source root?
Expand Down Expand Up @@ -166,7 +170,6 @@ export const scan = async (): Promise<ScanResult> => {
}

log.trace('...completed scan', { result })

return result
}

Expand Down Expand Up @@ -197,8 +200,12 @@ const checks = {
/**
* Find the (optional) app module in the user's project.
*/
export const findAppModule = async () => {
return findFile(ENTRYPOINT_FILE_NAMES)
export function findAppModule(): string | null {
log.trace('looking for app module')
const path = findFile(ENTRYPOINT_FILE_NAMES)
log.trace('done looking for app module')

return path
}

/**
Expand All @@ -212,10 +219,10 @@ export const findAppModule = async () => {
*
*/
export function findProjectDir(): string {
let packageJsonPath = findPackageJsonPath()
let packageJsonPath = findPackageJson()

if (packageJsonPath) {
return Path.dirname(packageJsonPath)
return packageJsonPath.dir
}

return process.cwd()
Expand All @@ -235,14 +242,6 @@ function calcSourceRootToModule(layout: Layout, modulePath: string) {
return Path.relative(layout.sourceRoot, modulePath)
}

/**
* Find the package.json file path. Looks recursively upward to disk root. If no
* package.json found along search, returns null.
*/
function findPackageJsonPath(): string | null {
return findConfigFile('package.json', { required: false })
}

/**
* Detect whether or not CWD is inside a nexus project. nexus project is
* defined as there being a package.json in or above CWD with nexus as a
Expand All @@ -253,32 +252,40 @@ export async function scanProjectType(): Promise<
| {
type: 'NEXUS_project' | 'node_project'
packageJson: {}
packageJsonPath: string
packageJsonLocation: { path: string; dir: string }
}
> {
const packageJsonPath = findPackageJsonPath()
const packageJsonLocation = findPackageJson()

if (packageJsonPath === null) {
if (packageJsonLocation === null) {
if (await isEmptyCWD()) {
return { type: 'new' }
}
return { type: 'unknown' }
}

const packageJson = fs.read(packageJsonPath, 'json')
if (packageJson?.dependencies?.['nexus']) {
return { type: 'NEXUS_project', packageJson, packageJsonPath }
const packageJson = FS.read(packageJsonLocation.path, 'json')
if (packageJson?.dependencies?.['nexus-future']) {
return {
type: 'NEXUS_project',
packageJson: packageJsonLocation,
packageJsonLocation: packageJsonLocation,
}
}

return { type: 'node_project', packageJson, packageJsonPath }
return {
type: 'node_project',
packageJson: packageJsonLocation,
packageJsonLocation: packageJsonLocation,
}
}

/**
* Check if the CWD is empty of any files or folders.
* TODO we should make nice exceptions for known meaningless files, like .DS_Store
*/
async function isEmptyCWD(): Promise<boolean> {
const contents = await fs.listAsync()
const contents = await FS.listAsync()
return contents === undefined || contents.length === 0
}

Expand Down Expand Up @@ -306,7 +313,7 @@ export async function loadDataFromParentProcess(): Promise<Layout> {

function readProjectInfo(): ScanResult['project'] {
try {
const packageJson: PackageJson = require(fs.path('package.json'))
const packageJson: PackageJson = require(FS.path('package.json'))

if (packageJson.name) {
return {
Expand All @@ -321,3 +328,11 @@ function readProjectInfo(): ScanResult['project'] {
isAnonymous: true,
}
}

/**
* Find the package.json file path. Looks recursively upward to disk root.
* Starts looking in CWD If no package.json found along search, returns null.
*/
function findPackageJson() {
return findDirContainingFileRecurisvelyUpwardSync('package.json')
}
Loading

0 comments on commit 2eacc8a

Please sign in to comment.