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

List Params support in CEL #5137

Merged
merged 25 commits into from Dec 19, 2022
Merged

List Params support in CEL #5137

merged 25 commits into from Dec 19, 2022

Conversation

Berlioz
Copy link
Contributor

@Berlioz Berlioz commented Oct 17, 2022

"This creaky regular expression based hack of an interpreter for our limited CEL subset can't possibly handle more features!," said Frog, as he built another feature on top of it

@Berlioz Berlioz changed the title WIP: List Params List Params support in CEL Oct 19, 2022
@codecov-commenter
Copy link

codecov-commenter commented Oct 19, 2022

Codecov Report

Base: 56.41% // Head: 56.30% // Decreases project coverage by -0.11% ⚠️

Coverage data is based on head (65c5635) compared to base (77e6e6d).
Patch coverage: 40.00% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5137      +/-   ##
==========================================
- Coverage   56.41%   56.30%   -0.12%     
==========================================
  Files         315      315              
  Lines       21150    21282     +132     
  Branches     4288     4338      +50     
==========================================
+ Hits        11932    11982      +50     
- Misses       8193     8263      +70     
- Partials     1025     1037      +12     
Impacted Files Coverage Δ
src/deploy/functions/prepare.ts 31.42% <0.00%> (-0.16%) ⬇️
...rc/deploy/functions/runtimes/discovery/v1alpha1.ts 76.62% <ø> (ø)
src/deploy/functions/params.ts 31.95% <15.38%> (-5.55%) ⬇️
src/deploy/functions/build.ts 61.62% <40.00%> (-0.51%) ⬇️
src/deploy/functions/runtimes/discovery/parsing.ts 74.13% <60.00%> (-1.79%) ⬇️
src/deploy/functions/cel.ts 79.62% <71.66%> (-2.41%) ⬇️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@inlined inlined left a comment

Choose a reason for hiding this comment

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

The winds are blowing in the direction of making lists be delimited strings rather than JSON expressions. This would make it easier to represent in GUI dialogs and reads easier in .env files.

export type Field<T extends string | number | boolean> = T | Expression<T> | null;
export type FieldList = Expression<string[]> | (string | Expression<string>)[] | null;
Copy link
Member

Choose a reason for hiding this comment

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

I do wonder if we can start by assuming you have either a string[] or Expression<string[]>. Array<string | Expression> may be hard to represent in Proto and it may not be a hard blocker for people to not be able to hard code only parts of a list.

export type Field<T extends string | number | boolean> = T | Expression<T> | null;
export type FieldList = Expression<string[]> | (string | Expression<string>)[] | null;
Copy link
Member

Choose a reason for hiding this comment

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

Also, nit picking, if it's a FieldList it sounds like a list of fields. A ListField sounds like a field that is a list, which personally sounds more accurate to my ears. NBD if you disagree though.

(res: string[]) => res
);
} else if (isTextInput(param.input)) {
prompt = `Enter a list of strings for ${param.label || param.name}:`;
Copy link
Member

Choose a reason for hiding this comment

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

This will probably get more complex if/when we transition to inputting with a delimiter. If your delimiter is newline, you probably have to accept double newlines as the way you end your prompt. IDK if the prompt library supports that, so we might, for now stick to just comma delimiters.

@@ -584,6 +688,10 @@ async function promptResourceString(
}

type retryInput = { message: string };
function shouldRetry(obj: any): obj is retryInput {
return (obj as retryInput).message !== undefined;
Copy link
Member

Choose a reason for hiding this comment

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

Do you also need to verify that obj is indeed an object? It looks like the previous code this is replacing used to check for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch.

resolvedDefault: T[] | undefined,
converter: (res: string[]) => T[] | retryInput
): Promise<T[]> {
const response = await promptOnce({
Copy link
Member

Choose a reason for hiding this comment

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

In firebase init we explain to people that they should use space to select a list item and return to choose the selection. We should probably add that to the prompt here. Similarly, when using a text input for list items, we should explain the delimiter usage.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

@@ -106,6 +107,14 @@ export function assertKeyTypes<T extends object>(
}
continue;
}
if (schemaType === "List") {
Copy link
Member

Choose a reason for hiding this comment

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

Technically you've defined "List?" as a type. Do you want to check for value === null first or is that case already handled?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks to me like the conditional checks immediately above that one cover this case, unless I'm badly misinterpreting your comment.

expect(
resolveExpression(
"string[]",
'{{ params.FOO == params.FOO ? [ "foo", params.BAR, {{ params.BAR }} ] : [] }}',
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't the last field be "{{ params.BAR }}" (with the quotes)

src/deploy/functions/cel.ts Outdated Show resolved Hide resolved
// by the preprocessLists() invocation at the beginning of CEL resolution
const parsed = JSON.parse(value);
if (!Array.isArray(parsed)) {
throw new ExprParseError("");
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we include more descriptive parser error message?

(res: string[]) => res
);
} else if (isTextInput(param.input)) {
prompt = `Enter a list of strings for ${param.label || param.name}:`;
Copy link
Contributor

Choose a reason for hiding this comment

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

can we expand the prompt to help instruct users how they can input the delimeter-separated list input?

src/deploy/functions/params.ts Outdated Show resolved Hide resolved
src/deploy/functions/params.ts Outdated Show resolved Hide resolved
src/deploy/functions/params.ts Outdated Show resolved Hide resolved
src/deploy/functions/params.ts Outdated Show resolved Hide resolved
resolvedDefault: T[] | undefined,
converter: (res: string[]) => T[] | retryInput
): Promise<T[]> {
const response = await promptOnce({
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Berlioz and others added 6 commits December 18, 2022 21:02
Co-authored-by: Daniel Lee <danielylee@google.com>
Co-authored-by: Daniel Lee <danielylee@google.com>
Co-authored-by: Daniel Lee <danielylee@google.com>
Co-authored-by: Daniel Lee <danielylee@google.com>
Co-authored-by: Daniel Lee <danielylee@google.com>
@Berlioz Berlioz merged commit e939a2b into master Dec 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants