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

Datasource Spans & Completions #3703

Merged
merged 31 commits into from
Mar 16, 2023
Merged

Datasource Spans & Completions #3703

merged 31 commits into from
Mar 16, 2023

Conversation

Druue
Copy link
Contributor

@Druue Druue commented Feb 10, 2023

Changes

Adding datasource completions was necessary as part of this to ensure effective testing. This will require a follow-up PR in language-tools to remove the completions mentioned below from there

  • Added datasource completions :: text_document_completions/datasource.rs

    • schemas
    • relationMode
    • provider
      • providers - [postgresql, etc...]
    • extensions
    • directUrl
    • shadowDatabase
    • url
      • ""
      • env
        • XYZ_URL
  • Completions trigger at start of line

    • this was enabled by pulling the NEWLINE out of the values i.e. (key_value ~ NEWLINE), this has only been done for config_block and will need to be done for the rest later
  • Completions only trigger within the bounds ({}) of the model

    • this was enabled by the new inner_span in the parser from the xyz_contents added to the grammar
  • Func for generating pretty doc for params, see language-tools/completionUtils

    • Added this through format_completion_docs
  • Specific completions should show before general

    • Previously general DS completions were showing before specific URL completions despite them showing up in the correct spot image image
    • This was fixed by updating config block property values to be Optional so that it was possible to select positions for properties that did not yet have a value assigned
  • Fix other tests

  • Add tests

  • Remove "engines" marker from new completions labels

Bugs

  • Completions shouldn't trigger on the closing line with the } on it :: This also existed prior to this PR with the language-tools impl. issue

  • Property value completions can trigger anywhere after the name, which can be before the = sign :: This is an issue with find_at_position and would probably require changes in the PEST grammar to include having the = as an identifiable piece in the parser for config blocks. issue

    • image
  • Value completions are available after a value (but not immediately like one space after) -- note, this only seems to affect url completions, completions do not show up again on the same line for provider, schemas, and relationMode. issue for the following

    • image
  • This is silly -- XYZ_URL showing up as a completion within the text env but not between v and (

    • image
  • XYZ_URL shows up as a completion anywhere between the left parenthesis and the character right after ) in env(...)

    • image

Todo

  • Remove datasource completions from https://github.com/prisma/language-tools
    • This will include sub-completions such as env && "" for url, or XYZ_URL for inside env
  • update pris.ly links per internal convo
  • Break-up lift_datasource & lift_generator starting to get a lil unwieldy
  • Make eldritch language tests more readable to avoid future issues where snapshots change and we don't know what or why
  • Stub datasource so that we can validate for missing providers / urls prior to having a full datasource (i.e. both exist)?

closes prisma/prisma#17000
Note: This does not entirely fix the issue and is instead a template for future completions additions to engines. This fixes the issue for datasource completions. When, in the future, we add completions to other parts of the schema from engines, this will require similar changes as done here to the PSL.
This is built off the back of the previous pr for adding schemas completions.

@Druue
Copy link
Contributor Author

Druue commented Feb 22, 2023

As a note, further changes in the PSL grammar and parsing were necessary due to issues in the formatter. It ended up being simpler to just add the notion of nesting to the rest of the blocks (as opposed to just the configs -- datasource & generator). So, now they all have some form of xyz_contents, e.g. model_contents which wraps everything between the opening and closing braces of a block.

@Druue

This comment was marked as resolved.

@Druue Druue added this to the 4.12.0 milestone Mar 2, 2023
@Druue Druue marked this pull request as ready for review March 3, 2023 12:04
@Druue Druue requested a review from a team as a code owner March 3, 2023 12:04
@Druue
Copy link
Contributor Author

Druue commented Mar 3, 2023

The providers completions, i.e. [mysql, postgresql, sqlite...] are still being emitted from language-tools but the current engines completions aren't suppressing them so I'm inclined to leave those for now.

Copy link
Contributor

@pimeys pimeys left a comment

Choose a reason for hiding this comment

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

Maybe check the few comments I left?

let expected = expect![[
r#"{"message":"\u001b[1;91merror\u001b[0m: \u001b[1mError validating datasource `thedb`: You must provide a nonempty direct URL\u001b[0m\n \u001b[1;94m-->\u001b[0m \u001b[4mschema.prisma:5\u001b[0m\n\u001b[1;94m | \u001b[0m\n\u001b[1;94m 4 | \u001b[0m url = env(\"DBURL\")\n\u001b[1;94m 5 | \u001b[0m directUrl = \u001b[1;91m\"\"\u001b[0m\n\u001b[1;94m | \u001b[0m\n\nValidation Error Count: 1","error_code":"P1012"}"#
]];
let expected = expect![[r#"{"message":"\u001b[1;91merror\u001b[0m: \u001b[1mError validating datasource `thedb`: You must provide a nonempty direct URL\u001b[0m\n \u001b[1;94m-->\u001b[0m \u001b[4mschema.prisma:5\u001b[0m\n\u001b[1;94m | \u001b[0m\n\u001b[1;94m 4 | \u001b[0m url = env(\"DBURL\")\n\u001b[1;94m 5 | \u001b[0m \u001b[1;91mdirectUrl = \"\"\u001b[0m\n\u001b[1;94m | \u001b[0m\n\nValidation Error Count: 1","error_code":"P1012"}"#]];
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to do this now, but by doing the following:

let response = get_config(&requqest.to_string()).unwrap_err();
let response: serde_json::Value = serde_json::from_str(&response).unwrap();
let response = serde_json::to_string_pretty(&response).unwrap();

The resulting string is having indentation, tabs and all that in place, so it's much nicer to read your expectation when it's not a oneliner.

Maybe a morning PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or, even better, deserialize the result, and assert the different parts. Now you can assert the datamodel a bit like we do in the psl tests, and additionally the error code as a separate assert.

prisma-fmt/src/text_document_completion.rs Outdated Show resolved Hide resolved
prisma-fmt/src/text_document_completion/datasource.rs Outdated Show resolved Hide resolved
prisma-fmt/src/text_document_completion/datasource.rs Outdated Show resolved Hide resolved
prisma-fmt/src/text_document_completion/datasource.rs Outdated Show resolved Hide resolved
psl/psl-core/src/validate/datasource_loader.rs Outdated Show resolved Hide resolved
psl/schema-ast/src/ast.rs Show resolved Hide resolved
let expected = expect![[
r#"{"message":"\u001b[1;91merror\u001b[0m: \u001b[1mEnvironment variable not found: DOES_NOT_EXIST.\u001b[0m\n \u001b[1;94m-->\u001b[0m \u001b[4mschema.prisma:5\u001b[0m\n\u001b[1;94m | \u001b[0m\n\u001b[1;94m 4 | \u001b[0m url = env(\"DBURL\")\n\u001b[1;94m 5 | \u001b[0m directUrl = \u001b[1;91menv(\"DOES_NOT_EXIST\")\u001b[0m\n\u001b[1;94m | \u001b[0m\n\nValidation Error Count: 1","error_code":"P1012"}"#
]];
let expected = expect![[r#"{"message":"\u001b[1;91merror\u001b[0m: \u001b[1mEnvironment variable not found: DOES_NOT_EXIST.\u001b[0m\n \u001b[1;94m-->\u001b[0m \u001b[4mschema.prisma:5\u001b[0m\n\u001b[1;94m | \u001b[0m\n\u001b[1;94m 4 | \u001b[0m url = env(\"DBURL\")\n\u001b[1;94m 5 | \u001b[0m \u001b[1;91mdirectUrl = env(\"DOES_NOT_EXIST\")\u001b[0m\n\u001b[1;94m | \u001b[0m\n\nValidation Error Count: 1","error_code":"P1012"}"#]];
Copy link
Member

@janpio janpio Mar 3, 2023

Choose a reason for hiding this comment

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

The diff in this example is that before only the env(...) part was one format, and now the whole line it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm honestly not sure how to read the diff here 😅

Copy link
Member

Choose a reason for hiding this comment

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

image

I think this is the additional line with a line number and the | that was removed - I commented on that below as well in a snapshot where it is more clearly visible.

Copy link
Member

Choose a reason for hiding this comment

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

(I think in prisam/prisma we use a stripAnsi function to remove the color codes from the messages and snapshot that as well - as it is more readable without breaking your brain)

kind: MarkupKind::Markdown,
value: generate_pretty_doc(
r#""connectionString""#,
r#"Connection URL including authentication info. Each datasource provider documents the URL syntax. Most providers use the syntax provided by the database. [Learn more](https://pris.ly/d/prisma-schema)."#,
Copy link
Member

Choose a reason for hiding this comment

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

Duplication with line 92 avoidable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As an update to url

Connection URL to connect to your database. [Learn more](https://pris.ly/d/connection-strings).
// instead of 
Connection URL including authentication info. Each datasource provider documents the URL syntax. Most providers use the syntax provided by the database. [Learn more](https://pris.ly/d/connection-strings).

let expected = expect![[
r#"{"error_code":"P1012","message":"\u001b[1;91merror\u001b[0m: \u001b[1mThe `referentialIntegrity` and `relationMode` attributes cannot be used together. Please use only `relationMode` instead.\u001b[0m\n \u001b[1;94m-->\u001b[0m \u001b[4mschema.prisma:6\u001b[0m\n\u001b[1;94m | \u001b[0m\n\u001b[1;94m 5 | \u001b[0m relationMode = \"prisma\"\n\u001b[1;94m 6 | \u001b[0m \u001b[1;91mreferentialIntegrity = \"foreignKeys\"\u001b[0m\n\u001b[1;94m 7 | \u001b[0m }\n\u001b[1;94m | \u001b[0m\n\nValidation Error Count: 1"}"#
]];
let expected = expect![[r#"{"error_code":"P1012","message":"\u001b[1;91merror\u001b[0m: \u001b[1mThe `referentialIntegrity` and `relationMode` attributes cannot be used together. Please use only `relationMode` instead.\u001b[0m\n \u001b[1;94m-->\u001b[0m \u001b[4mschema.prisma:6\u001b[0m\n\u001b[1;94m | \u001b[0m\n\u001b[1;94m 5 | \u001b[0m relationMode = \"prisma\"\n\u001b[1;94m 6 | \u001b[0m \u001b[1;91mreferentialIntegrity = \"foreignKeys\"\u001b[0m\n\u001b[1;94m | \u001b[0m\n\nValidation Error Count: 1"}"#]];
Copy link
Member

Choose a reason for hiding this comment

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

What is the differnece here? Can not figure it out visually.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is the diff running cargo t locally
image

@@ -132,7 +132,6 @@ fn datasource_should_not_allow_arbitrary_parameters() {
 | 
 3 |  url = "mysql://localhost"
 4 |  foo = "bar"
 5 | }
Copy link
Member

Choose a reason for hiding this comment

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

This additional line of context could in theory contain text and snippets from the schema, and be helpful this way. Did we intentionally remove this?

@Druue Druue force-pushed the tech/spans branch 2 times, most recently from c21eb86 to 108cad8 Compare March 14, 2023 12:04
Copy link
Contributor

@pimeys pimeys left a comment

Choose a reason for hiding this comment

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

Much better already. The specialization of certain completions is something we should have before we merge this. I'm willing to pair about this if needed. Just ping me.

position => ctx.connector().push_completions(ctx.db, position, completion_list),
}
}

fn ds_has_prop(ctx: CompletionContext<'_>, prop: &str) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd implement these directly in the datasource. So, we could ask from datasource ds.schemas_defined() and so on.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure do we really need this. Maybe in a follow-up PR.

prisma-fmt/src/text_document_completion.rs Outdated Show resolved Hide resolved
psl/schema-ast/src/ast/model.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@pimeys pimeys left a comment

Choose a reason for hiding this comment

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

a few things!

prisma-fmt/src/text_document_completion.rs Outdated Show resolved Hide resolved
position => ctx.connector().push_completions(ctx.db, position, completion_list),
}
}

fn ds_has_prop(ctx: CompletionContext<'_>, prop: &str) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure do we really need this. Maybe in a follow-up PR.

psl/psl-core/src/configuration/datasource.rs Show resolved Hide resolved
psl/psl-core/src/configuration/datasource.rs Show resolved Hide resolved
psl/psl-core/src/configuration/datasource.rs Show resolved Hide resolved
psl/psl-core/src/configuration/datasource.rs Show resolved Hide resolved
psl/psl-core/src/configuration/datasource.rs Show resolved Hide resolved
Copy link
Contributor

@pimeys pimeys left a comment

Choose a reason for hiding this comment

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

Well done. To production we go!

@Druue Druue merged commit 3b9f029 into main Mar 16, 2023
@Druue Druue deleted the tech/spans branch March 16, 2023 09:18
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.

Completions: provided by engines break right at the start of a newline
3 participants