Add tsconfig option to specify tsconfig path (#8452)

* Add tsconfig option to specify tsconfig path

* Add CHANGELOG entry and fix lint

* Add a test

* Fix test
This commit is contained in:
Ian Wahbe 2021-11-22 11:42:39 -08:00 committed by GitHub
parent 574a6a104d
commit d9dd88c740
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 107 additions and 11 deletions

View file

@ -18,7 +18,10 @@
### Bug Fixes
- [codegen/typescript] - Respect default values in Pulumi object types.
- [cli/nodejs] - Allow specifying the tsconfig file used in Pulumi.yaml.
[#8452](https://github.com/pulumi/pulumi/pull/8452)
- [codegen/nodejs] - Respect default values in Pulumi object types.
[#8400](https://github.com/pulumi/pulumi/pull/8400)
- [sdk/python] - Correctly handle version checking python virtual environments.

View file

@ -82,11 +82,14 @@ func main() {
var tracing string
var typescript bool
var root string
var tsconfigpath string
flag.StringVar(&tracing, "tracing", "",
"Emit tracing to a Zipkin-compatible tracing endpoint")
flag.BoolVar(&typescript, "typescript", true,
"Use ts-node at runtime to support typescript source natively")
flag.StringVar(&root, "root", "", "Project root path to use")
flag.StringVar(&tsconfigpath, "tsconfig", "",
"Path to tsconfig.json to use")
flag.Parse()
args := flag.Args()
@ -118,7 +121,7 @@ func main() {
// Fire up a gRPC server, letting the kernel choose a free port.
port, done, err := rpcutil.Serve(0, nil, []func(*grpc.Server) error{
func(srv *grpc.Server) error {
host := newLanguageHost(nodePath, runPath, engineAddress, tracing, typescript)
host := newLanguageHost(nodePath, runPath, engineAddress, tracing, typescript, tsconfigpath)
pulumirpc.RegisterLanguageRuntimeServer(srv, host)
return nil
},
@ -155,16 +158,18 @@ type nodeLanguageHost struct {
engineAddress string
tracing string
typescript bool
tsconfigpath string
}
func newLanguageHost(nodePath, runPath, engineAddress,
tracing string, typescript bool) pulumirpc.LanguageRuntimeServer {
tracing string, typescript bool, tsconfigpath string) pulumirpc.LanguageRuntimeServer {
return &nodeLanguageHost{
nodeBin: nodePath,
runPath: runPath,
engineAddress: engineAddress,
tracing: tracing,
typescript: typescript,
tsconfigpath: tsconfigpath,
}
}
@ -504,6 +509,9 @@ func (host *nodeLanguageHost) execNodejs(
if host.typescript {
env = append(env, "PULUMI_NODEJS_TYPESCRIPT=true")
}
if host.tsconfigpath != "" {
env = append(env, "PULUMI_NODEJS_TSCONFIG_PATH="+host.tsconfigpath)
}
if logging.V(5) {
commandStr := strings.Join(args, " ")

View file

@ -20,6 +20,7 @@ import { parseConfigFileTextToJson } from "typescript";
import { ResourceError, RunError } from "../../errors";
import * as log from "../../log";
import * as runtime from "../../runtime";
import { Inputs } from "../../output";
import * as mod from ".";
@ -96,7 +97,7 @@ function throwOrPrintModuleLoadError(program: string, error: Error): void {
const deps = packageObject["dependencies"] || {};
const devDeps = packageObject["devDependencies"] || {};
const scripts = packageObject["scripts"] || {};
const mainProperty = packageObject["main"] || "index.js";
const mainProperty = packageObject["main"] || "index.js";
// Is there a build script associated with this program? It's a little confusing that the
// Pulumi CLI doesn't run build scripts before running the program so call that out
@ -106,7 +107,7 @@ function throwOrPrintModuleLoadError(program: string, error: Error): void {
const command = scripts["build"];
console.error(` * Your program looks like it has a build script associated with it ('${command}').\n`);
console.error("Pulumi does not run build scripts before running your program. " +
`Please run '${command}', 'yarn build', or 'npm run build' and try again.`);
`Please run '${command}', 'yarn build', or 'npm run build' and try again.`);
return;
}
@ -132,10 +133,11 @@ function throwOrPrintModuleLoadError(program: string, error: Error): void {
}
/** @internal */
export function run(argv: minimist.ParsedArgs,
programStarted: () => void,
reportLoggedError: (err: Error) => void,
isErrorReported: (err: Error) => boolean) {
export function run(
argv: minimist.ParsedArgs,
programStarted: () => void,
reportLoggedError: (err: Error) => void,
isErrorReported: (err: Error) => boolean): Promise<Inputs | undefined> {
// If there is a --pwd directive, switch directories.
const pwd: string | undefined = argv["pwd"];
if (pwd) {
@ -150,7 +152,8 @@ export function run(argv: minimist.ParsedArgs,
// find a tsconfig.json. For us, it's reasonable to say that the "root" of the project is the cwd,
// if there's a tsconfig.json file here. Otherwise, just tell ts-node to not load project options at all.
// This helps with cases like pulumi/pulumi#1772.
const tsConfigPath = "tsconfig.json";
const defaultTsConfigPath = "tsconfig.json";
const tsConfigPath: string = process.env["PULUMI_NODEJS_TSCONFIG_PATH"] ?? defaultTsConfigPath;
const skipProject = !fs.existsSync(tsConfigPath);
let compilerOptions: object;
@ -184,7 +187,7 @@ export function run(argv: minimist.ParsedArgs,
// Now fake out the process-wide argv, to make the program think it was run normally.
const programArgs: string[] = argv._.slice(1);
process.argv = [ process.argv[0], process.argv[1], ...programArgs ];
process.argv = [process.argv[0], process.argv[1], ...programArgs];
// Set up the process uncaught exception, unhandled rejection, and program exit handlers.
const uncaughtHandler = (err: Error) => {
@ -230,6 +233,15 @@ ${defaultMessage}`);
programStarted();
// This needs to occur after `programStarted` to ensure execution of the parent process stops.
if (skipProject && tsConfigPath !== defaultTsConfigPath) {
return new Promise(() => {
const e = new Error(`tsconfig path was set to ${tsConfigPath} but the file was not found`);
e.stack = undefined;
throw e;
});
}
const runProgram = async () => {
// We run the program inside this context so that it adopts all resources.
//

View file

@ -1178,3 +1178,23 @@ func TestAboutNodeJS(t *testing.T) {
func TestConstructOutputValuesNode(t *testing.T) {
testConstructOutputValues(t, "nodejs", "@pulumi/pulumi")
}
func TestTSConfigOption(t *testing.T) {
if runtime.GOOS == WindowsOS {
t.Skip("Skip on windows because we lack yarn")
}
e := ptesting.NewEnvironment(t)
defer func() {
if !t.Failed() {
e.DeleteEnvironment()
}
}()
e.ImportDirectory("tsconfig")
e.RunCommand("yarn", "link", "@pulumi/pulumi")
e.RunCommand("yarn", "install")
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.RunCommand("pulumi", "stack", "select", "tsconfg", "--create")
e.RunCommand("pulumi", "preview")
}

View file

@ -0,0 +1,5 @@
name: test-yaml-option
runtime:
name: nodejs
options:
tsconfig: other.json

View file

@ -0,0 +1,7 @@
import * as pulumi from "@pulumi/pulumi";
// If this is run onder "module": "esnext", it will fail. Neither the import nor the export are
// valid for "esnext".
// Export the name of the bucket
export const bucketName = "name";

View file

@ -0,0 +1,16 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": ["index.ts"]
}

View file

@ -0,0 +1,9 @@
{
"name": "tsconfig",
"devDependencies": {
"@types/node": "^14"
},
"dependencies": {
"@pulumi/pulumi": "^3.0.0"
}
}

View file

@ -0,0 +1,16 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "esnext",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": ["index.ts"]
}