-
Notifications
You must be signed in to change notification settings - Fork 40
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
Cli update and typescript conversion wip (new branch name) #69
base: master
Are you sure you want to change the base?
Cli update and typescript conversion wip (new branch name) #69
Conversation
chore: update deps / package.json scripts; add `tsup` build tool; feat: new config API (WIP)
see: #68 (comment) |
lib/opts/index.ts
Outdated
|
||
if (svConfig) { | ||
for (const key in svConfig) { | ||
// @ts-expect-error - We know this key SHOULD NOT be in svConfig, but we're going to allow it and warn the user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably avoid all the // @ts-expect-error
directives by making this an Object.keys(svConfig).filter(() => /* etc */)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, I don't believe .filter()
acts as a type guard. There is a library, ts-reset
, that does this, but it's not recommended for libraries because it pollutes the global scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, let's not pollute the global scope 😅
What I mean is:
Object.keys(svConfig)
.filter((key) => catVOnlyFeatures.includes(key))
.forEach((key) => console.warn(
`The "${key}" option is a feature of commit-and-tag-version, and is not supported by standard-version.${"\n"}Please move this option to the 'commit-and-tag-version' key.${"\n"}In a future version, this will throw an error.`))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand your meaning, but what I'm saying is that - despite how one might expect .filter() and Object.keys() to work - the type of key
remains as string
throughout that pipeline. It is never narrowed to the union of literal strings that are keys of svConfig, which is what is needed to remove the type errors.
You aren't the only one to expect this behavior, though. I certainly did, as did many others. That's why I bring up ts-reset
- it was written with the purpose of making some less intuitive behaviors act how you would expect, and I think this is one of the things it addresses (again, not advocating for it here lol).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow - ignore me. I feel dumb now! I think I understand what you mean. I've refactored like so:
export const getMergedConfig = async (
cwd?: string
): Promise<Partial<Config>> => {
const searchDir = cwd ?? process.cwd();
const pkgJson = (await import("path")).join(searchDir, "package.json");
const legacyConf: LegacyConfig = (await import(pkgJson))["standard-version"];
const modernConf: Config = (await import(pkgJson))["commit-and-tag-version"];
Object.keys(legacyConf ?? {}).forEach((key) => {
if (catVOnlyFeatures.includes(key as any)) {
console.warn(
`The "${key}" option is a feature of commit-and-tag-version, and is not supported by standard-version.${"\n"}Please move this option to the 'commit-and-tag-version' key.${"\n"}In a future version, this will throw an error.`
);
}
if (modernConf && isin(modernConf, key as any)) {
console.warn(
`"standard-version"."${key}" in package.json is being overridden by "commit-and-tag-version"."${key}". in package.json`
);
}
});
const configFromFile = await getConfigFromFile();
return { ...(legacyConf ?? {}), ...(modernConf ?? {}), ...(configFromFile ?? {}) };
};
That about right?
@@ -0,0 +1,52 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the opinions here.
For ease of maintenance in the future, we could instead extend one of the @tsconfig
base configs - https://github.com/tsconfig/bases - what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably, I just pulled this from my own lib and made a couple of modifications lol. It's geared for maximum strictness.
Edit, on second thought... I kinda like having the config be explicitly defined in-source. Personal preference, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general I agree. The advantage of those particular ones are:
- Now you don't need to do a close read every time you pick up a new repo
- I feel more confident that it's definitely compatible with the node version we want
Yours looks fine to me though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll keep this comment open, but during development, I'll stick to a custom-curated tsconfig.json
for ease of debugging. Once we know that the refactor and its accompanying tsconfig.json
are all working as intended, we can look for a combination of base configs to extend to provide the same resulting config.
This is good work! I've left a bunch of comments inline and enabled the build. A nitpick about the commit names - |
Eek, sorry about that! I've been using Also, replying to your suggestions 1 by 1, and I'll commit the changes! Also need to dig into the failed build, I missed a setting somewhere I guess... it's not pulling in the JSON module correctly. |
refactor: cleaner types in command.ts
Fixes pushed! Let me know what you think. EDIT: I did not fix the build error - no need to enable the build |
After taking a look at the build issue, it turns out the problem is that Ultimately, the best fix would be to move to the |
I don’t think we need to move to another test framework for mocha to run on typescript- I can take a look when I’m back at my desk |
So, you should just be able to drop in However, when I do this, I get a lot of errors, and they don't have valid stack traces. I'm not sure why this is - I think maybe something in the .tsconfig is throwing it off, maybe.
Mocha normally prints proper stack traces with typescript (although, I don't really use it much so I'm a bit unclear on why it isn't doing it here). I pushed this commit which is very rushed, just to get one fully typescript test at least executing. Possibly I did something wrong in the conversion - but it's up in case you want to have a look or cherry-pick it to get you going. |
After looking at your suggestion, as well as the I can't say testing is at the top of my priority list for the refactor - in fact, it might make more sense to do the testing refactor entirely separately so that we know the tests pass both before AND after the TS refactor. |
I'm not wild about vitest as I've found the documentation to be straight up inaccurate. But, it's not a preference worth blocking a PR over, so if you're doing the work, feel free to bring in whatever you feel comfortable with. Also this prompted me to send them a PR fixing the problem that annoyed me.
Ideally we'd have the tests passing during the introduction of TS with minimal changes. Of course... that's not necessarily possible. |
I dug further in to this, and I have some bad news - it isn't the test framework at fault - the failures are real. One problem is that replacing Some good news though - the most common problem is that the tests are written with programmatic I suspect that the mocking might not work the same with typescript, so we might have to replace some of that too, potentially. The tests for config object from files don't work any more - I had a brief poke around, and I think some of the new code isn't called - but I didn't look too closely. It might be the mocking. |
On the contrary, that's great news! Real failures beat the heck out of false negatives. I had wondered how much of it was due to the TS conversion being only partial, so it's good to know that's probably the most significant factor. I'll focus on just getting everything to full conversion, then double back for the tests to see what still fails. Ideally, there should be minimal test refactoring to get them passing. I'd certainly rather not have to migrate to a whole new testing framework, so this would definitely be the preferred route. At the risk of derailing the conversation, though, I'm curious about what sort of inaccuracies you've come across in the Vitest docs? It would be nice to know of any foot-guns I might be unwittingly wielding! |
This is a work in progress for a refactor that addresses the following issues: #29, #31, #44, #61