-
-
Notifications
You must be signed in to change notification settings - Fork 735
fix(options): Increase argument options reader discover event priority #610
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
Conversation
This is also necessary to give the input files of the tsconfig reader priority over the command line argument (that usually just points to the directory of the tsconfig file). |
/cc @thecjharries |
Ill explain the issue a bit further: In this.options.read(options, OptionsReadMode.Prefetch);
this.options.read(options, OptionsReadMode.Fetch); Each reader listens for the options discover event via: this.listenTo(this.owner, DiscoverEvent.DISCOVER, this.onDiscover, -200); tsconfig: this.listenTo(this.owner, DiscoverEvent.DISCOVER, this.onDiscover, -100); typedoc: this.listenTo(this.owner, DiscoverEvent.DISCOVER, this.onDiscover, -150); That leads to the readers executing their respective However, both the tsconfig and typedoc tsconfig: onDiscover(event: DiscoverEvent) {
if (TSConfigReader.OPTIONS_KEY in event.data) {
this.load(event, Path.resolve(event.data[TSConfigReader.OPTIONS_KEY]));
} else if (TSConfigReader.PROJECT_KEY in event.data) {
// The `project` option may be a directory or file, so use TS to find it
let file: string = ts.findConfigFile(event.data[TSConfigReader.PROJECT_KEY], ts.sys.fileExists);
// If file is undefined, we found no file to load.
if (file) {
this.load(event, file);
}
} else if (this.application.isCLI) {
let file: string = ts.findConfigFile('.', ts.sys.fileExists);
// If file is undefined, we found no file to load.
if (file) {
this.load(event, file);
}
}
} typedoc: onDiscover(event: DiscoverEvent) {
if (TypedocReader.OPTIONS_KEY in event.data) {
this.load(event, Path.resolve(event.data[TypedocReader.OPTIONS_KEY]));
} else if (this.application.isCLI) {
const file = Path.resolve('typedoc.js');
if (FS.existsSync(file)) {
this.load(event, file);
}
}
} This leads to the onDiscover(event: DiscoverEvent) {
if (this.application.isCLI) {
this.parseArguments(event);
}
} Another note. Would it be worth considering parsing the arguments during @thecjharries A comment about #587, one solution is to enforce an |
I can confirm, #587 should be reverted or refactored. Priority issues:The commit introduces a lot of issues, both order execution issues and logical issues.
It does not make sense to fire
Logical issuesFor some reason,
I'm not aware of the reason for that change, but if it's to give the CLI args precedence for file selection it is a problem, if a user specify a Same thing for |
@pat841 you need to add more thing to the commit. @blakeembrey As a guideline, I suggest locking CLI arguments are used as the interface for controlling low level configuration, such as which tsconfig file to use or which |
BTW, this should be done ASAP, it's hard to workaround. |
@shlomiassaf:
Re priority: the options are parsed twice, first using defaults, then second with values discovered from the initial read. That wasn't something I added. That's why it starts with TS, adds TypeDoc, and finishes with CLI.
Re logic: in general, command line options override configuration (Google that phrase for some examples) because they're used to modify the base. Again, that's not something I made up. Similarly, any options from TypeDoc would be specified to replace base config.
|
If we want to follow that way it's fine but it needs to make sense.
I'm fine with that, but with logic that fits our use case, we can't just follow someone's best practice without adaption to the specific use case. If readers depends on CLI input, CLI must come first... that's simple logic. BTW, it is still required to add files and not remove, in ArgumentsReader... or at least skip if length is 0. |
I'm not sure I understand your concern about the use case. Are you saying TypeDoc shouldn't use As to your concern about the load order, I'm not sure you're following how TypeDoc parses options. Check out the original PR for a detailed explanation. Again, like a majority of tools running a stack of other tools, TypeDoc layers its config. It first finds a base Edit: Think of it this way: tools that extend configuration have to start with something. You can either specify a subset of the options first and fill the missing options with defaults later, or start with everything and replace the defaults as you discover values. TypeDoc uses the latter approach. It's an easier solution programmatically, because you're simply setting members instead of performing diffs or checking if a value exists. |
@thecjharries On top of that, BOTH options events @shlomiassaf I'm not entirely sure what you want me to change. This PR is only for modifying the reader orders. |
@pat841 So you're saying the defaults loaded during |
@thecjharries I'm all for that. I just assumed we dropped the event data for some specific reason. Want me to just update this PR and reset the priority change? |
Edit: as the website politely tells me right below the box, email replies don't support markdown. Whoops. The properly compiled comment is immediately below.
|
Round two: At the same time, I'm really worried that the change is going to generate a slew of new issues. By reusing the It's 100% not working as intended, so the PR should happen. It's been that way for two years, so you bet that quirk is baked into a few things. |
I've already found a potential issue. Actually using the |
Actually, this might much easier than I was making it. The readers are all very good at checking their specific options and falling back to defaults when nothing is found. Perhaps the defaults could just be skipped in // Import OptionsReadMode
import { OptionsComponent, DiscoverEvent, OptionsReadMode } from '../options';
...
// Update the last conditional in onDiscover
} else if (this.application.isCLI && event.mode === OptionsReadMode.Fetch) { |
In utils/options/readers/arguments.ts private parseArguments(event: DiscoverEvent, args?: string[]) {
...
if (files) {
event.inputFiles = files;
}
} with private parseArguments(event: DiscoverEvent, args?: string[]) {
...
if (files.length > 0) {
event.inputFiles = files;
}
} you would be fine, at least regarding the input files issue. Command line call could be
without any non-option arguments (that in fact would be treated as files by the arguments reader). At the moment, |
Previously the arguments reader would run after both the tsconfig and typedoc readers. However, both of those readers rely on event data such as "-options" that is parsed by the arguments reader which leads to issues when trying to point to a given config using a CLI argument.
@thecjharries @shlomiassaf @makana Please check out the amended commit. I think this should solve most of our problems.
|
Any update on this? This is still a breaking bug that needs to be fixed. |
Looks good to me but I haven't tried it. My understanding is that typedoc does an initial "prefetch" to read the options (from the CLI?). Then it uses the values from those options to get the tsconfig and typedoc config files. @pat841 @shlomiassaf @thecjharries @makana Have you all tested this on actual configuration? I'd like to get this out soon. |
@aciccarello Yes, I have been using my own branch with this PR on our production systems, supports both CLI and config files. |
@aciccarello I've used this patch in production. I cannot do any useful work with Presumably I cannot use 0.10.0 either, which I see has been recently released with TS 2.7 support, but without this patch. |
Previously the arguments reader would run after both the tsconfig and typedoc readers. However, both of those readers rely on event data such as "-options" that is parsed by the arguments reader which leads to issues when trying to point to a given config using a CLI argument.