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

Enable support for per package assert tagging configuration #23452

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

CraigMacomber
Copy link
Contributor

@CraigMacomber CraigMacomber commented Jan 3, 2025

Description

Refactor assert tagger so its relies much less on function side effects and global state.

Make assert functions configuration per package instead of global.

Remove exclusion of test packages: exclude them as needed using config.

Configure tree to tag its "fail" function. This will enable a small bundle size improvement for tree.

Reviewer Guidance

The review process is outlined on this wiki page.

@github-actions github-actions bot added area: build Build related issues area: dds Issues related to distributed data structures area: dds: tree area: runtime Runtime related issues area: tests Tests to add, test infrastructure improvements, etc public api change Changes to a public API base: main PRs targeted against main branch labels Jan 3, 2025
@CraigMacomber CraigMacomber marked this pull request as ready for review January 7, 2025 17:49
@Copilot Copilot bot review requested due to automatic review settings January 7, 2025 17:49
@CraigMacomber CraigMacomber requested a review from a team as a code owner January 7, 2025 17:49

Choose a reason for hiding this comment

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

Copilot reviewed 5 out of 12 changed files in this pull request and generated no comments.

Files not reviewed (7)
  • packages/dds/test-dds-utils/flub.config.cjs: Evaluated as low risk
  • packages/runtime/test-runtime-utils/flub.config.cjs: Evaluated as low risk
  • build-tools/packages/build-cli/src/commands/generate/assertTags.ts: Evaluated as low risk
  • build-tools/packages/build-cli/src/config.ts: Evaluated as low risk
  • packages/dds/tree/flub.config.cjs: Evaluated as low risk
  • packages/dds/tree/src/feature-libraries/sequence-field/sequenceFieldCodecV1.ts: Evaluated as low risk
  • packages/dds/tree/src/simple-tree/toMapTree.ts: Evaluated as low risk
Comments suppressed due to low confidence (1)

packages/dds/tree/src/simple-tree/api/treeNodeApi.ts:177

  • The error message should include the specific field information to aid in debugging. Suggest reverting to the original message: fail(Could not find stored key '${field}' in schema.).
fail("Could not find stored key in schema.")

private collectAssertData(tsconfigPath: string): void {
// TODO: this can probably be removed now
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removing this caused many more packages to be processed, like test-dds-utils, test-runtime-utils and everything in packages/test . See the config files added to filter them out.

* Some of this applies to the root where flub is being run,
* and some of it applies to the specific package being processed.
* @privateRemarks
* It seems like having each package have its own configuration would be simpler.
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 you could make it work that way for this command. fluid-build supports task definitions in both places, but flub has not historically needed such a capability outside of the typetest commands. I'm inclined to leave handling individual package config to individual commands for now.

@zhenmichael Something to keep an eye on as you port commands to the new infrastructure. Are there more commands that could benefit from a general-purpose per-package config loading capability? Maybe that feature could be baked into the new PackageCommand base class from the beginning?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you are going to look at general things we want for configuration, I think the big one thats missing is any sort of schema/validation system.

Using a library like typebox to give you errors if you have a typo in your config field names or invalid structure would be nice (instead of just casting config data parsed as json to a type an hoping its right). Would have saved me some annoyance when I messed up the nesting working on this PR.

Copy link
Member

Choose a reason for hiding this comment

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

Using typescript types in the JS config files helps prevent a lot of these errors. You're absolutely right about the stuff in package.json.

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 this will mean that the root flub config is never loaded. The config nearest to the working dir is loaded, and there's no implied inheritance or merging. You could import the root config here, modify it and then export it.

But I am conflicted about this approach. In the type tests, the one other place where this sort of scenario (command/package-specific config) exists, the per-package config is in the package.json for the package and the type test commands load the settings there. I like this because it makes it clearer that this config is not flub config, really, but config for a specific command.

That said, I don't think we should pollute the top-level package.json 'namespace,' so maybe a flubCommandConfig node that individual commands can add entries to?

Comment on lines +92 to +98
// 3. The division of responsibility here is odd. Generally the user of a PackageCommand selects which packages to apply it to on the command line.
// Currently this is done by passing --all (as specified in the script that invokes this command),
// and a separate regex in a config.
// This extra config even more confusing since typically this kind of configuration is per package,
// but in this case the config from one package is applying to multiple release groups based on the working directory the command is run in.
// Normally configuration in a package applies to the package, and sometimes configuration for a release group lives at its root.
// In this case configuration spanning multiple release groups lives in the root of one of them but uses the same file we would use for per package configuration which makes it hard to understand.
Copy link
Member

Choose a reason for hiding this comment

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

Great observation. This is a side effect of the evolution of the code and the developers writing it. :)

@zhenmichael Let's chat about the specific ideas Craig shared and integrate them into the design for PackageCommand vnext. The most critical thing to decide in order to unblock this PR is where the per-package config should live (see other comments). Any enhancements to the selection/filtering should live in build-infrastructure with the new functions there. Some of the things called out here will likely be addressed as a side effect of building on the new selection/filtering stuff.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If PackageCommand allowed passing both --releaseGroup and --package at the same time then we could use that to replace the regex filter. Thats likely the simplest solution since we could just pass in --releaseGroup client --package @fluidframework/common-utils instead of --all.

If we do want to keep the regex functionality, it can be kept and moved to PackageCommand along with its other filtering options.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Supporting multiple selection flags seems trivial, so I'm going to try and make that change.

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 should do it: #23511

Comment on lines 168 to 169
const tsconfigPath = await this.getTsConfigPath(pkg);
const packageConfig = getFlubConfig(pkg.directory).assertTagging;
Copy link
Member

Choose a reason for hiding this comment

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

Ahh, I see you're loading the package config here. I think putting it in package.json will be clearer and lets you get rid of some of this code since you can just get the config from the package directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you suggesting to:

  1. not use FlubConfig for this, or
  2. to put it in the package.json as part of the FlubConfig?

I think you mean 1, which makes sense, though I suspect it won't be less code just less over all coupling.

Copy link
Member

Choose a reason for hiding this comment

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

I'm suggesting putting the settings in package.json, but not with the existing FlubConfig interface. Maybe it makes sense to use the AssertTaggingConfig interface? I was imagining something like this in the individual packages:

{
  "flubCommandConfig":
    "generate:asserts": {
      "assertionFunctions": {
        "assert": 1,
        "fail": 0,
	}
}

We could get rid of the "flubCommandConfig" layer, and maybe that's a bad name anyway. I was trying to avoid adding a bunch of stuff at the top level, but I'm more pragmatic than principled in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping the ability to have one config file cover all 13 packages in packages/test is useful, so I kept the use of cosmic config, but make it use its own config. THis should prevent this folder config from causing issues with any other configurations.

Comment on lines 55 to 58
export function fail(message: string | number): never {
throw new Error(
typeof message === "number" ? `0x${message.toString(16).padStart(3, "0")}` : message,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

At this point would it make sense to define it in terms of assert(false, ...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

doing that is an error, since assert tagging errors if you pass something other than a constant string to assert. Its possible to work around that, but thats why I didn't do exactly as you suggest.

@CraigMacomber
Copy link
Contributor Author

CraigMacomber commented Jan 7, 2025

We seem to have a second implementation of assert tagging in build-tools/packages/build-cli/src/library/repoPolicyCheck/assertShortCode.ts . The implications of doing changes to one copy of the code and not the other are not super clear, but will likely cause issues. I think this should be deduplicated before this changes goes forward. Hopefully said deduplication can be done without conflicting with this change too much.

(Edit: it has now been removed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: build Build related issues area: dds: tree area: dds Issues related to distributed data structures area: runtime Runtime related issues area: tests Tests to add, test infrastructure improvements, etc base: main PRs targeted against main branch public api change Changes to a public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants