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

perf: extract context type in background #384

Merged
merged 22 commits into from
Mar 3, 2020
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
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 +
Copy link
Member

Choose a reason for hiding this comment

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

Fixed a print bug here

'/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