Skip to content

Commit

Permalink
make pkg possible
Browse files Browse the repository at this point in the history
  • Loading branch information
timsuchanek committed Apr 6, 2020
1 parent ec370e1 commit 8122037
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 98 deletions.
2 changes: 1 addition & 1 deletion cli/prisma2/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ prisma
test
/prisma-client
write-test
prisma2*.tgz
prisma2*.tgz
9 changes: 7 additions & 2 deletions cli/prisma2/src/Version.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Command, getVersion } from '@prisma/sdk'
import { Command, getVersion, resolveBinary } from '@prisma/sdk'
import { getPlatform } from '@prisma/get-platform'
import fs from 'fs'
import path from 'path'
import { getBinaryName } from '@prisma/fetch-engine'
const packageJson = require('../package.json')
import Debug from 'debug'
const debug = Debug('version')

interface BinaryInfo {
path: string
Expand All @@ -21,6 +23,9 @@ export class Version implements Command {
private constructor() {}
async parse(argv: string[]) {
const platform = await getPlatform()
const parentDir = fs.readdirSync(path.join(__dirname, '../'))
debug({ parentDir })

const introspectionEngine = await this.resolveEngine(
'introspection-engine',
'PRISMA_INTROSPECTION_ENGINE_BINARY',
Expand Down Expand Up @@ -50,7 +55,7 @@ export class Version implements Command {
return { version, path: pathFromEnv!, fromEnvVar: envVar }
}

const binaryPath = path.join(__dirname, `../${getBinaryName(binaryName, platform)}`)
const binaryPath = await resolveBinary(binaryName as any)
const version = await getVersion(binaryPath)
return { path: binaryPath, version }
}
Expand Down
3 changes: 2 additions & 1 deletion cli/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"devDependencies": {
"@types/jest": "24.0.22",
"@types/node": "^12.12.32",
"@types/node": "^12.12.34",
"@types/tar": "^4.0.3",
"@typescript-eslint/eslint-plugin": "^2.25.0",
"@typescript-eslint/parser": "^2.25.0",
Expand Down Expand Up @@ -61,6 +61,7 @@
"strip-ansi": "6.0.0",
"strip-indent": "3.0.0",
"tar": "^5.0.5",
"temp-dir": "^2.0.0",
"temp-write": "^4.0.0",
"tempy": "^0.3.0",
"terminal-link": "^2.1.1",
Expand Down
30 changes: 3 additions & 27 deletions cli/sdk/src/IntrospectionEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import byline from './utils/byline'
const debugRpc = debugLib('IntrospectionEngine:rpc')
const debugStderr = debugLib('IntrospectionEngine:stderr')
const debugStdin = debugLib('IntrospectionEngine:stdin')
import { getPlatform } from '@prisma/get-platform'
import fs from 'fs'
import { now } from './utils/now'
import path from 'path'
import { RustPanic, ErrorArea } from './panic'
import { resolveBinary } from './resolveBinary'

export interface IntrospectionEngineOptions {
binaryPath?: string
Expand Down Expand Up @@ -76,7 +75,6 @@ let messageId = 1

/* tslint:disable */
export class IntrospectionEngine {
private binaryPath?: string
private debug: boolean
private cwd: string
private child?: ChildProcess
Expand All @@ -88,14 +86,11 @@ export class IntrospectionEngine {
private lastUrl?: string
public isRunning: boolean = false
constructor(
{ binaryPath, debug, cwd }: IntrospectionEngineOptions = {
binaryPath: process.env.PRISMA_INTROSPECTION_ENGINE_BINARY, // ncc go home
{ debug, cwd }: IntrospectionEngineOptions = {
debug: false,
cwd: process.cwd(),
},
) {
this.binaryPath =
process.env.PRISMA_INTROSPECTION_ENGINE_BINARY || binaryPath
if (debug) {
debugLib.enable('IntrospectionEngine*')
}
Expand Down Expand Up @@ -183,30 +178,11 @@ export class IntrospectionEngine {

return this.initPromise!
}
private async getBinaryPath() {
if (this.binaryPath) {
return path.resolve(process.cwd(), this.binaryPath)
}

const platform = await getPlatform()
const extension = platform === 'windows' ? '.exe' : ''

this.binaryPath = path.join(
eval(`require('path').join(__dirname, '../')`),
`introspection-engine-${platform}${extension}`,
)
if (!fs.existsSync(this.binaryPath)) {
throw new Error(
`Expected introspection engine at ${this.binaryPath} does not exist.`,
)
}
return this.binaryPath
}
private internalInit(): Promise<void> {
return new Promise(async (resolve, reject) => {
try {
const { PWD, ...env } = process.env
const binaryPath = await this.getBinaryPath()
const binaryPath = await resolveBinary('introspection-engine')
debugRpc('starting introspection engine with binary: ' + binaryPath)
this.child = spawn(binaryPath, {
stdio: ['pipe', 'pipe', 'pipe'],
Expand Down
79 changes: 12 additions & 67 deletions cli/sdk/src/engineCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import tmpWrite from 'temp-write'
import fs from 'fs'
import { promisify } from 'util'
import Debug from 'debug'
import { resolveBinary } from './resolveBinary'
const debug = Debug('engineCommands')

const unlink = promisify(fs.unlink)
Expand Down Expand Up @@ -34,58 +35,6 @@ path.join(__dirname, '../introspection-engine-rhel-openssl-1.0.x')
path.join(__dirname, '../query-engine-rhel-openssl-1.0.x')
path.join(__dirname, '../introspection-engine-rhel-openssl-1.0.x')

/**
* Dynamic path resolution
*/
async function getPrismaPath(): Promise<string> {
// tslint:disable-next-line
if (process.env.PRISMA_QUERY_ENGINE_BINARY) {
if (!fs.existsSync(process.env.PRISMA_QUERY_ENGINE_BINARY)) {
throw new Error(
`Env var PRISMA_QUERY_ENGINE_BINARY is provided but provided path ${process.env.PRISMA_QUERY_ENGINE_BINARY} can't be resolved.`,
)
}
return process.env.PRISMA_QUERY_ENGINE_BINARY
}
const dir = eval('__dirname')
const platform = await getPlatform()
const extension = platform === 'windows' ? '.exe' : ''
const binaryName = `query-engine-${platform}${extension}`
let prismaPath = path.join(dir, '..', binaryName)
if (fs.existsSync(prismaPath)) {
return prismaPath
}
// for pkg
prismaPath = path.join(dir, '../..', binaryName)
if (fs.existsSync(prismaPath)) {
return prismaPath
}

prismaPath = path.join(__dirname, '..', binaryName)
if (fs.existsSync(prismaPath)) {
return prismaPath
}

prismaPath = path.join(__dirname, '../..', binaryName)
if (fs.existsSync(prismaPath)) {
return prismaPath
}

// needed to come from @prisma/client/generator-build to @prisma/client/runtime
prismaPath = path.join(__dirname, '../runtime', binaryName)
if (fs.existsSync(prismaPath)) {
return prismaPath
}

throw new Error(
`Could not find query-engine binary. Searched in ${path.join(
dir,
'..',
binaryName,
)} and ${path.join(dir, '../..', binaryName)}`,
)
}

export type GetDMMFOptions = {
datamodel?: string
cwd?: string
Expand All @@ -102,7 +51,7 @@ export async function getDMMF({
retry = 4,
}: GetDMMFOptions): Promise<DMMF.Document> {
debug(`getDMMF, override prismaPath = ${prismaPath}`)
prismaPath = prismaPath || (await getPrismaPath())
prismaPath = prismaPath || (await resolveBinary('query-engine'))
let result
try {
let tempDatamodelPath: string | undefined = datamodelPath
Expand Down Expand Up @@ -214,7 +163,7 @@ export async function getConfig({
datamodelPath,
}: GetDMMFOptions): Promise<ConfigMetaFormat> {
debug(`getConfig, override prismaPath = ${prismaPath}`)
prismaPath = prismaPath || (await getPrismaPath())
prismaPath = prismaPath || (await resolveBinary('query-engine'))

let tempDatamodelPath: string | undefined = datamodelPath
if (!tempDatamodelPath) {
Expand All @@ -229,19 +178,15 @@ export async function getConfig({
}

try {
const result = await execa(
prismaPath,
['cli', 'get-config'],
{
cwd,
env: {
...process.env,
PRISMA_DML_PATH: tempDatamodelPath,
RUST_BACKTRACE: '1',
},
maxBuffer: MAX_BUFFER,
const result = await execa(prismaPath, ['cli', 'get-config'], {
cwd,
env: {
...process.env,
PRISMA_DML_PATH: tempDatamodelPath,
RUST_BACKTRACE: '1',
},
)
maxBuffer: MAX_BUFFER,
})

if (!datamodelPath) {
await unlink(tempDatamodelPath)
Expand All @@ -260,7 +205,7 @@ export async function getConfig({
}

export async function getVersion(enginePath?: string): Promise<string> {
enginePath = enginePath || (await getPrismaPath())
enginePath = enginePath || (await resolveBinary('query-engine'))

debug(`Getting version of ${enginePath}`)
const result = await execa(enginePath, ['--version'], {
Expand Down
2 changes: 2 additions & 0 deletions cli/sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export { resolveBinary } from './resolveBinary'

export { missingGeneratorMessage } from './utils/missingGeneratorMessage'

export {
Expand Down
100 changes: 100 additions & 0 deletions cli/sdk/src/resolveBinary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import fs from 'fs'
import path from 'path'
import tempDir from 'temp-dir'
import makeDir from 'make-dir'
import { promisify } from 'util'
import { getPlatform } from '@prisma/get-platform'
import { plusX } from '@prisma/engine-core/dist/util'
import Debug from 'debug'
const debug = Debug('resolveBinary')

const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const copyFile = promisify(fs.copyFile)

export type EngineType =
| 'query-engine'
| 'migration-engine'
| 'introspection-engine'

const engineEnvVarMap = {
'query-engine': 'PRISMA_QUERY_ENGINE_BINARY',
'migration-engine': 'PRISMA_MIGRATION_ENGINE_BINARY',
'introspection-engine': 'PRISMA_INTROSPECTION_ENGINE_BINARY',
}

export async function resolveBinary(name: EngineType): Promise<string> {
// tslint:disable-next-line

const envVar = engineEnvVarMap[name]

if (process.env[envVar]) {
if (!fs.existsSync(process.env[envVar]!)) {
throw new Error(
`Env var ${envVar} is provided, but provided path ${process.env[envVar]} can't be resolved.`,
)
}
return process.env[envVar]!
}

const dir = eval('__dirname')

const platform = await getPlatform()
const extension = platform === 'windows' ? '.exe' : ''
const binaryName = `${name}-${platform}${extension}`
let prismaPath = path.join(dir, '..', binaryName)
if (fs.existsSync(prismaPath)) {
return maybeCopyToTmp(prismaPath)
}
// for pkg
prismaPath = path.join(dir, '../..', binaryName)
if (fs.existsSync(prismaPath)) {
return maybeCopyToTmp(prismaPath)
}

prismaPath = path.join(__dirname, '..', binaryName)
if (fs.existsSync(prismaPath)) {
return maybeCopyToTmp(prismaPath)
}

prismaPath = path.join(__dirname, '../..', binaryName)
if (fs.existsSync(prismaPath)) {
return maybeCopyToTmp(prismaPath)
}

// needed to come from @prisma/client/generator-build to @prisma/client/runtime
prismaPath = path.join(__dirname, '../runtime', binaryName)
if (fs.existsSync(prismaPath)) {
return maybeCopyToTmp(prismaPath)
}

throw new Error(
`Could not find ${name} binary. Searched in ${path.join(
dir,
'..',
binaryName,
)} and ${path.join(dir, '../..', binaryName)}`,
)
}

async function maybeCopyToTmp(file: string): Promise<string> {
// in this case, we are in a "pkg" context with a virtual fs
// to make this work, we need to copy the binary to /tmp and execute it from there

const dir = eval('__dirname')
if (dir.startsWith('/snapshot/prisma2')) {
const targetDir = path.join(tempDir, 'prisma-binaries')
await makeDir(targetDir)
const target = path.join(targetDir, path.basename(file))
debug({ file, target })
const data = await readFile(file)
await writeFile(target, data)
// We have to read and write until https://github.com/zeit/pkg/issues/639
// is resolved
// await copyFile(file, target)
plusX(target)
return target
}

return file
}

0 comments on commit 8122037

Please sign in to comment.