feat(cli): parse Cargo.toml using cargo metadata (#1330)

This commit is contained in:
messense 2022-10-01 22:06:14 +08:00 committed by GitHub
parent e54c37a0b1
commit 4279291f4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -7,7 +7,6 @@ import { Instance } from 'chalk'
import { Command, Option } from 'clipanion' import { Command, Option } from 'clipanion'
import envPaths from 'env-paths' import envPaths from 'env-paths'
import { groupBy } from 'lodash-es' import { groupBy } from 'lodash-es'
import toml from 'toml'
import { getNapiConfig } from './consts' import { getNapiConfig } from './consts'
import { debugFactory } from './debug' import { debugFactory } from './debug'
@ -191,39 +190,39 @@ export class BuildCommand extends Command {
const cwd = this.cargoCwd const cwd = this.cargoCwd
? join(process.cwd(), this.cargoCwd) ? join(process.cwd(), this.cargoCwd)
: process.cwd() : process.cwd()
const cargoTomlPath = join(cwd, 'Cargo.toml')
let tomlContentString: string let cargoMetadata: any
let tomlContent: any
try {
debug('Start read toml')
tomlContentString = await readFileAsync(join(cwd, 'Cargo.toml'), 'utf-8')
} catch {
throw new TypeError(`Could not find Cargo.toml in ${cwd}`)
}
try { try {
debug('Start parse toml') debug('Start parse toml')
tomlContent = toml.parse(tomlContentString) cargoMetadata = JSON.parse(
} catch { execSync(
throw new TypeError('Could not parse the Cargo.toml') `cargo metadata --format-version 1 --manifest-path ${cargoTomlPath}`,
{
stdio: 'pipe',
maxBuffer: 1024 * 1024 * 10,
},
).toString('utf8'),
)
} catch (e) {
throw new TypeError('Could not parse the Cargo.toml: ' + e)
} }
const packages = cargoMetadata.packages
let cargoPackageName: string let cargoPackageName: string
if (tomlContent.package?.name) { if (this.cargoName) {
cargoPackageName = tomlContent.package.name
} else if (this.cargoName) {
cargoPackageName = this.cargoName cargoPackageName = this.cargoName
} else {
const root = cargoMetadata.resolve.root
if (root) {
const rootPackage = packages.find((p: { id: string }) => p.id === root)
cargoPackageName = rootPackage.name
} else { } else {
throw new TypeError('No package.name field in Cargo.toml') throw new TypeError('No package.name field in Cargo.toml')
} }
}
const cargoMetadata = JSON.parse(
execSync('cargo metadata --format-version 1', {
stdio: 'pipe',
maxBuffer: 1024 * 1024 * 10,
}).toString('utf8'),
)
const packages = cargoMetadata.packages
const cargoPackage = packages.find( const cargoPackage = packages.find(
(p: { name: string }) => p.name === cargoPackageName, (p: { name: string }) => p.name === cargoPackageName,
) )
@ -369,7 +368,12 @@ export class BuildCommand extends Command {
cargoArtifactName = cargoPackageName.replace(/-/g, '_') cargoArtifactName = cargoPackageName.replace(/-/g, '_')
} }
if (!this.bin && !tomlContent.lib?.['crate-type']?.includes?.('cdylib')) { if (
!this.bin &&
!cargoPackage.targets.some((target: { crate_types: string[] }) =>
target.crate_types.includes('cdylib'),
)
) {
throw new TypeError( throw new TypeError(
`Missing ${chalk.green('crate-type = ["cdylib"]')} in ${chalk.green( `Missing ${chalk.green('crate-type = ["cdylib"]')} in ${chalk.green(
'[lib]', '[lib]',