typed-ember / glint

TypeScript powered tooling for Glimmer templates
https://typed-ember.gitbook.io/glint
MIT License
108 stars 50 forks source link

Codemods #90

Open wagenet opened 3 years ago

wagenet commented 3 years ago

Convert signatures, add to registry, etc.

dfreeman commented 3 years ago

I think we chatted about this in Discord, but just so it's captured here: I think codemods are going to be a super important part of adoption here, particularly as we discuss upstreaming things like the FooArgs => FooSignature change into @glimmer/component itself.

The balance we're currently trying to strike is between investing in easing adoption today vs progressing further toward a more stable place where we think major elements of the API are unlikely to change and we won't need to completely rewrite any codemods we've previously developed.

That said, if folks in the community are interested in building codemods for signature conversion, registry stuff, import updates, etc. for the current status quo, I'd be happy to see that happen.

simonihmig commented 2 years ago

FWIW, I was able to save me some time by using my IDE's (Jetbrains, hope it works as well elsewhere) project-wide find & replace function using just regular expressions. I know this is far from perfect and not able to replace a real codemod, as a.o.t. it's much more likely to cause incorrect transformations without knowledge of the AST, but again it saved my a good amount of time adding that boilerplate, so maybe it's helpful for other folks as well...

Change imports

Should be straightforward, no Regex needed, e.g. from '@glimmer/component' -> from '@glint/environment-ember-loose/glimmer-component' etc.

Add components to registry

Find: export default class (\w+)(<(?s).*>)? extends Component((?s).*\}) Replace:

export default class $1$2 extends Component$3

declare module '@glint/environment-ember-loose/registry' {
  export default interface Registry {
    '$1': typeof $1;
  }
}

Note that the registry keys are likely to be incorrect, especially for nested components, so need to be manually adjusted. A Regex is just not capable of this...

Convert Args to Signatures

Find: interface (\w*)Args (\{(?s)[^\}]*\}) Replace:

interface $1Signature {
  Args: $2;
}

<(\w*)Args>
<$1Signature>

This assumes your existing interface names are ending on ...Args, and will be transformed to ...Signature.

boris-petrov commented 2 years ago

@simonihmig - keep in mind that with the latest changes for @glimmer/component and @types/ember__component you actually wouldn't have to/mustn't use the changed imports. We're just waiting for a new version of Glint from @dfreeman and it should work with the original imports! :)

dfreeman commented 2 years ago

I'm definitely excited to stop requiring the custom imports, but the Args -> Signature migration and registry boilerplate both do make for a lot of boring manual labor that would be great to automate. To @simonihmig's point, even a simple regex-based approach can be a super helpful starting point—thanks for sharing those!

I think with the Signature RFC merged and the custom imports (soon to be) a thing of the past, we're now at a point where investment in a proper codemod would start to pay off.

More robust handling for extracting existing Args and adding registry entries would be a fantastic baseline, and with a bit more elbow grease to examine templates as part of the codemod, I think a best-effort pass would be possible for:

All that said, I don't think I myself am going to have the bandwidth to work on that codemod any time in the near future, but I would certainly use it if it existed! If others are interested, though, I'd encourage you to pursue it and be happy to offer any guidance I can đź’ś

chriskrycho commented 1 year ago

Doing some triage; do we still want/feel the need for codemods? I expect the answer is likely yes, and likely to get much louder now that we're hitting 1.0—the swaths of the community using TS but not yet using Glint will want it!

wagenet commented 1 year ago

I think that at least having tooling to generate signatures would be nice.

chadhietala commented 1 year ago

I think all plumbing is in place now to do this in code actions

ijlee2 commented 1 year ago

I've started working on it: https://github.com/ijlee2/ember-codemod-args-to-signature