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

feat: @target intrinsic #7161

Merged
merged 5 commits into from
Sep 24, 2024
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
1 change: 1 addition & 0 deletions docs/api/05-language-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ the following properties (given an example intrinsic `@x`):
| `@assert()` | checks a condition and _throws_ if evaluated to false |
| `@filename` | absolute path of the source file |
| `@dirname` | absolute path of the source file's directory |
| `@target` | a string identifying the current target platform |
| `@app` | the root of the construct tree |
| `@unsafeCast()` | cast a value into a different type |
| `@nodeof()` | obtain the [tree node](/docs/concepts/application-tree) of a preflight object |
Expand Down
4 changes: 2 additions & 2 deletions docs/contributing/998-archived/01-compile-targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ new cloud.Function(inflight ()=> {
// push a message to queue
queue.push("m");
// sleep according to target
if util.env("WING_TARGET") == "sim" {
if @target == "sim" {
log("Running on Simulator, sleeping for 1s");
util.sleep(1s);
} else {
Expand All @@ -85,7 +85,7 @@ new cloud.Function(inflight ()=> {
});
```

In this example, we want to sleep briefly for the Simulator target and for 30 seconds for cloud targets, this is achieved using the `WING_TARGET` environment variable.
In this example, we want to sleep briefly for the simulator target and for 30 seconds for cloud targets, this is achieved using the `@target` intrinsic function.

## Compiler plugins

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/03-platforms/01-understanding-platforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ vpc_api_gateway = true

There might be times when you need to write code that is specific to a particular platform target. For example, you may want to activate a verbose logging service only when testing locally to save on cloud log storage costs.

With the Wing `util` library, you can access environment variables. The `WING_TARGET` environment variable contains the current platform target as it's value, which you can use to conditionally run target-specific code. See the example below:
The `@target` intrinsic returns the current platform target as a string value, which you can use to conditionally run target-specific code. See the example below:

```js playground example
bring cloud;
Expand All @@ -138,7 +138,7 @@ new cloud.Function(inflight ()=> {
// push a message to queue
queue.push("m");
// sleep according to target
if util.env("WING_TARGET") == "sim" {
if @target == "sim" {
log("Running on Simulator, sleeping for 1s");
util.sleep(1s);
} else {
Expand Down
4 changes: 0 additions & 4 deletions packages/@winglang/sdk/src/cloud/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,6 @@ export class Function extends Resource implements IInflightHost {
const entrypoint = join(workdir, `${assetName}.cjs`);
this.entrypoint = entrypoint;

if (process.env.WING_TARGET) {
this.addEnvironment("WING_TARGET", process.env.WING_TARGET);
}

if (props.concurrency !== undefined && props.concurrency <= 0) {
throw new Error(
"concurrency option on cloud.Function must be a positive integer"
Expand Down
4 changes: 0 additions & 4 deletions packages/@winglang/sdk/src/cloud/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ export class Service extends Resource implements IInflightHost {
const entrypoint = join(workdir, `${this.assetName}.cjs`);
this.entrypoint = entrypoint;

if (process.env.WING_TARGET) {
this.addEnvironment("WING_TARGET", process.env.WING_TARGET);
}

this.handler = handler;
}

Expand Down
4 changes: 4 additions & 0 deletions packages/@winglang/sdk/src/core/lifting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,5 +423,9 @@ export class Lifting {
// no lift-related methods to call - it's probably a primitive
// so no capabilities need to be added to the inflight host
}

if (process.env.WING_TARGET) {
host.addEnvironment("WING_TARGET", process.env.WING_TARGET!);
}
}
}
4 changes: 0 additions & 4 deletions packages/@winglang/sdk/src/target-sim/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ export class Resource
const entrypoint = join(workdir, `${assetName}.cjs`);
this.entrypoint = entrypoint;

if (process.env.WING_TARGET) {
this.addEnvironment("WING_TARGET", process.env.WING_TARGET);
}

this.factory = factory;
}

Expand Down
4 changes: 4 additions & 0 deletions packages/@winglang/wingc/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ pub enum IntrinsicKind {
Dirname,
Filename,
App,
Target,
}

impl Display for IntrinsicKind {
Expand All @@ -601,6 +602,7 @@ impl Display for IntrinsicKind {
IntrinsicKind::Dirname => write!(f, "@dirname"),
IntrinsicKind::Filename => write!(f, "@filename"),
IntrinsicKind::App => write!(f, "@app"),
IntrinsicKind::Target => write!(f, "@target"),
}
}
}
Expand All @@ -611,6 +613,7 @@ impl IntrinsicKind {
"@dirname" => IntrinsicKind::Dirname,
"@filename" => IntrinsicKind::Filename,
"@app" => IntrinsicKind::App,
"@target" => IntrinsicKind::Target,
_ => IntrinsicKind::Unknown,
}
}
Expand All @@ -630,6 +633,7 @@ impl IntrinsicKind {
Phase::Preflight => true,
_ => false,
},
IntrinsicKind::Target => true,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/@winglang/wingc/src/jsify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,9 @@ impl<'a> JSifier<'a> {
IntrinsicKind::App => {
new_code!(expr_span, HELPERS_VAR, ".nodeof(this).app")
}
IntrinsicKind::Target => {
new_code!(expr_span, "process.env.WING_TARGET")
}
},
ExprKind::Call { callee, arg_list } => {
let function_type = match callee {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,11 @@ source: packages/@winglang/wingc/src/lsp/completions.rs
kind: markdown
value: "Get the normalized absolute path of the current Wing source file.\n\nThe resolved path represents a path during preflight only and is not guaranteed to be valid while inflight."
sortText: bb|@filename
- label: "@target"
kind: 6
detail: str
documentation:
kind: markdown
value: "Returns a string identifying the current compilation platform.\n\nThis value is set by the CLI at compile time and can be used to conditionally compile code that is dependent on the target platform."
sortText: bb|@target

Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,11 @@ source: packages/@winglang/wingc/src/lsp/completions.rs
kind: markdown
value: "Get the normalized absolute path of the current Wing source file.\n\nThe resolved path represents a path during preflight only and is not guaranteed to be valid while inflight."
sortText: bb|@filename
- label: "@target"
kind: 6
detail: str
documentation:
kind: markdown
value: "Returns a string identifying the current compilation platform.\n\nThis value is set by the CLI at compile time and can be used to conditionally compile code that is dependent on the target platform."
sortText: bb|@target

2 changes: 1 addition & 1 deletion packages/@winglang/wingc/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2527,7 +2527,7 @@ impl<'s> Parser<'s> {
};

if matches!(kind, IntrinsicKind::Unknown) {
self.add_error("Invalid intrinsic", &expression_node);
self.add_error(format!("Unknown intrinsic: @{}", name), &expression_node);
}

Ok(Expr::new(
Expand Down
28 changes: 27 additions & 1 deletion packages/@winglang/wingc/src/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,28 @@ See https://www.winglang.io/docs/concepts/application-tree for more information.
AccessModifier::Public,
StatementIdx::Top,
);

// @target
let _ = self.types
.intrinsics
.define(
&Symbol::global(IntrinsicKind::Target.to_string()),
SymbolKind::Variable(VariableInfo {
access: AccessModifier::Public,
name: Symbol::global(IntrinsicKind::Target.to_string()),
docs: Some(Docs::with_summary(
r#"Returns a string identifying the current compilation platform.

This value is set by the CLI at compile time and can be used to conditionally compile code that is dependent on the target platform."#,
)),
kind: VariableKind::StaticMember,
phase: Phase::Independent,
type_: self.types.string(),
reassignable: false,
}),
AccessModifier::Public,
StatementIdx::Top,
);
}

fn add_builtin(&mut self, name: &str, typ: Type, scope: &mut Scope) {
Expand Down Expand Up @@ -2981,7 +3003,11 @@ See https://www.winglang.io/docs/concepts/application-tree for more information.
}

match intrinsic.kind {
IntrinsicKind::Dirname | IntrinsicKind::Filename | IntrinsicKind::App | IntrinsicKind::Unknown => {
IntrinsicKind::Dirname
| IntrinsicKind::Filename
| IntrinsicKind::App
| IntrinsicKind::Target
| IntrinsicKind::Unknown => {
return (sig.return_type, sig.phase);
}
}
Expand Down
5 changes: 2 additions & 3 deletions packages/winglang/project-templates/wing/private-api/main.w
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
bring cloud;
bring http;
bring util;

/**
* The example below is a simple note-taking app.
Expand Down Expand Up @@ -96,7 +95,7 @@ bring util;
let noteService = new NoteService();

// Consumer functions (not required for the app to work, but useful for testing)
if util.env("WING_TARGET") == "tf-aws" {
if @target == "tf-aws" {
new cloud.Function(inflight (event) => {
if let event = event?.tryAsStr() {
let parts = event.split(":");
Expand Down Expand Up @@ -128,4 +127,4 @@ if util.env("WING_TARGET") == "tf-aws" {

return "event is required `NAME`";
}) as "Consumer-GET";
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions tests/error/invalid-token.test.w
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
bring sim;
bring util;

inflight class MyResourceBackend impl sim.IResource {
ctx: sim.IResourceContext;
Expand All @@ -22,7 +21,7 @@ class MyResource {
}

// Only run these tests in the simulator
if util.env("WING_TARGET") == "sim" {
if @target == "sim" {
let r = new MyResource();
let fakeAttr = r.fakeAttr();

Expand Down
5 changes: 1 addition & 4 deletions tests/sdk_tests/api/aws-api.test.w
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
bring cloud;
bring aws;
bring util;

let target = util.env("WING_TARGET");

let api = new cloud.Api() as "api";
api.get("/api", inflight (req: cloud.ApiRequest): cloud.ApiResponse => {
Expand Down Expand Up @@ -39,4 +36,4 @@ test "validates the AWS Api" {
// If the test is not on AWS, it should not fail, so I am returning true.
assert(true);
}
}
}
2 changes: 1 addition & 1 deletion tests/sdk_tests/api/cycle.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ bring util;
// This test checks that an API can have a route whose handler
// references the API's URL.

if ["sim", "tf-aws", "awscdk"].contains(util.env("WING_TARGET")) {
if ["sim", "tf-aws", "awscdk"].contains(@target) {
let api = new cloud.Api();

api.get("/my_url", inflight () => {
Expand Down
7 changes: 2 additions & 5 deletions tests/sdk_tests/bucket/aws-bucket.test.w
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
bring cloud;
bring aws;
bring util;

let target = util.env("WING_TARGET");

let bucket = new cloud.Bucket() as "aws-wing-bucket";

Expand All @@ -20,7 +17,7 @@ let bucketInfo = getBucketInfo(bucket);

test "validates the AWS Bucket" {
if let bucket = bucketInfo {
if target == "tf-aws" {
if @target == "tf-aws" {
assert(bucket.get("bucketArn").contains("arn:aws:s3:::aws-wing-bucket"));
assert(bucket.get("bucketName").contains("aws-wing-bucket"));
} else { // If it's not a 'tf-aws' target, it's an 'awscdk'
Expand All @@ -32,4 +29,4 @@ test "validates the AWS Bucket" {
// If the test is not on AWS, it should not fail, so I am returning true.
assert(true);
}
}
}
4 changes: 2 additions & 2 deletions tests/sdk_tests/bucket/bucket-ref.test.w
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
bring cloud;
bring aws;
bring util;
bring expect;

let b = new cloud.Bucket();

// this will only work if we are testing on tf-aws
Expand All @@ -14,7 +14,7 @@ if let name = aws.Bucket.from(b)?.bucketName {
}
}

if util.env("WING_TARGET") == "sim" {
if @target == "sim" {
let dummyName = "wing-dummy-bucket";
let dummyArn = "arn:aws:s3:::{dummyName}";
let br = new aws.BucketRef(dummyName);
Expand Down
2 changes: 1 addition & 1 deletion tests/sdk_tests/bucket/events.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ new std.Test(inflight () => {
b.delete("c");

// https://github.com/winglang/wing/issues/2724
if (util.env("WING_TARGET") != "tf-aws") {
if @target != "tf-aws" {
// assert that onCreate events about the "a", "b", and "c" objects were each produced exactly 1 time
checkHitCount(key: "a", type: "OnCreate()", source: Source.anyEvent, count: 1);
checkHitCount(key: "b", type: "OnCreate()", source: Source.anyEvent, count: 1);
Expand Down
7 changes: 3 additions & 4 deletions tests/sdk_tests/bucket/signed_url.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,13 @@ test "signedUrl PUT" {

test "signedUrl duration option is respected" {
let isExpiredTokenError = (output: str) => {
let target = util.env("WING_TARGET");
let var result = false;

if target == "tf-aws" {
if @target == "tf-aws" {
result = output.contains("<Code>AccessDenied</Code><Message>Request has expired</Message>");
} else if target == "tf-gcp" {
} else if @target == "tf-gcp" {
result = output.contains("<Code>ExpiredToken</Code><Message>Invalid argument.</Message>");
} else if target == "sim" {
} else if @target == "sim" {
result = output.contains("Signed URL has expired");
}

Expand Down
4 changes: 1 addition & 3 deletions tests/sdk_tests/container/container.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ skipPlatforms:

bring sim;
bring http;
bring util;
bring expect;

// only relevant in simulator
if util.env("WING_TARGET") == "sim" {

if @target == "sim" {
let echo = new sim.Container(
name: "http-echo",
image: "hashicorp/http-echo",
Expand Down
3 changes: 1 addition & 2 deletions tests/sdk_tests/container/entrypoint.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ skipPlatforms:

bring sim;
bring http;
bring util;
bring expect;

// only relevant in simulator
if util.env("WING_TARGET") == "sim" {
if @target == "sim" {
let entrypoint = new sim.Container(
name: "my-entrypoint-app",
image: "./my-docker-image",
Expand Down
3 changes: 1 addition & 2 deletions tests/sdk_tests/container/mount.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ skipPlatforms:
- darwin
\*/
bring sim;
bring util;

// only relevant in simulator
if util.env("WING_TARGET") == "sim" {
if @target == "sim" {
let container = new sim.Container(
name: "postgres",
image: "postgres:15",
Expand Down
3 changes: 1 addition & 2 deletions tests/sdk_tests/container/network.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ skipPlatforms:

bring sim;
bring http;
bring util;
bring expect;

// only relevant in simulator
if util.env("WING_TARGET") == "sim" {
if @target == "sim" {
let networkHost = new sim.Container(
name: "http-echo",
image: "hashicorp/http-echo",
Expand Down
Loading