-
-
Notifications
You must be signed in to change notification settings - Fork 738
General correction of glob patterns and config file locating #742
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
- Also allowed it to take multiple path expressions
Looks great! Thanks for the contribution. I had started working on getting the typedoc.json file working again a while ago but never finished. I'll take a little more time to look this over before merging but from what I see, it looks great! |
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.
Love the cleanup of file loading. I don't fully understand the changes to where minimatch is being used?
Also, the files have a 4 space indent style already so new code should probably stick with that. There should be some tooling to apply that already.
package.json
Outdated
@@ -33,34 +33,34 @@ | |||
"@types/fs-extra": "5.0.1", | |||
"@types/handlebars": "4.0.36", | |||
"@types/highlight.js": "9.12.2", | |||
"@types/lodash": "4.14.104", | |||
"@types/lodash": "4.14.106", |
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.
Next time, avoid updating dependencies unnecessarially. It creates merge conflicts with other contributions.
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.
ok got it... I will revert it
const { config } = ts.readConfigFile(fileName, ts.sys.readFile); | ||
if (config === undefined) { | ||
event.addError('The tsconfig file %s does not contain valid JSON.', fileName); | ||
event.addError('No valid tsconfig file found.', fileName); |
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 changed the text since it now is used when there is no file as well as an invalid file
src/lib/utils/paths.ts
Outdated
return new Minimatch(pattern.replace(/[\\]/g, '/'), { dot: true }); | ||
} | ||
|
||
export function pathToMinimatch(pattern: string | string[]): IMinimatch | IMinimatch[] { |
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.
Is this function really needed? From the usage I saw, it seems that createMinimatch
would be sufficient. The overloading of a parameter that is sometimes an array means that you frequently need to cast the result.
I'd prefer to inline the arr.map(createMinimatch)
in files.
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.
It is true that the two methods could be combined. I separated them in an attempt to make the code less bulky and easier to read. But if you prefer to combine them I can. It is also a bit slower to recreate a function inside a function, so there is also a minor performance gain of having them separate.
EDIT
So reading my code again I Remember why I made it as a separate function. It is to keep the given pattern argument as a string or Array which ever format it has. So I use the same method in two different scenarios.
But if you want I can do a method override to make it clearer.
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.
regarding the pattern: string | string[]
is because the given path can be one or several paths (as parsed from the CLI arguments). When only one path is given it is just a string otherwise an array of strings is given, hence the double type definition.
src/lib/utils/paths.ts
Outdated
import { Minimatch, IMinimatch } from 'minimatch'; | ||
|
||
function createMinimatch(pattern: string): IMinimatch { | ||
if (pattern[0] === '.' || pattern[0] === '/' || /^\w+(?!:)($|[/\\])/.test(pattern)) { |
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.
Can you explain this regex? I don't have the skills to understand it.
Is there any of this that Minimatch handles already?
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.
Ok so this if
is to check if a path like these:
./some/path
../some/path
some/path
path
Which are all relative paths and should be resolved relative to process.cwd()
(Path.resolve(path)
).
The regex is to test that windows absolute paths like C:/some/path
wont be confused for a relative path like c/some/path
. So I use a negative look ahead to ensure there is no :
after the letters in the first part of the path (path/
will be a relative path and path:/
won't)
I could have used one regex to test for all of these cases, but it is a lot faster to do the simple tests first and only do the regex if really needed.
The main issue is that generally in other libraries that uses GLOB expressions you can just type ./some/path
and that would be treated as relative to the project root, but this have not been the case for this project where **/some/path
was needed to ensure correct path matching, which has been counter-intuitive for many developers.
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.
But I can see I made a mistake: pattern[0] === '/'
would match /some/path
as relative, which isn't the case. I will fix this.
// Used to ensure uniform path cross OS | ||
const absolutePath = (path: string) => Path.resolve(path).replace(/[\\]/g, '/'); | ||
|
||
describe('Paths', () => { |
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.
Thanks for writing tests!
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.
sure thing
I created the general function for the minimatch to uniform the the way the minimatching is done (right now it is used in two places), so the change is basically to allow paths to be written as relative to the project root ( I will check up on the indentation as well. |
This reverts commit 7728227.
- Renamed from `pathToMinimatch` - Added overload methods for easier usage (no need for explicit casting) and clarification - Updated how absolute and relative paths are checked - Fixed indentation
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.
Looks good! The createMinimatch code is a lot easier to understand. Still a couple questions
src/lib/utils/paths.ts
Outdated
// Ensure uniform absolute path cross OS | ||
// (POSIX would resolve c:/path to /path/to/repo/c:/path without this check) | ||
if (Path.isAbsolute(pattern) && Path.sep === '/') { | ||
pattern = pattern.replace(/^\w:/, ''); |
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.
If the drive letter is removed, does this break access to other drives (e.g. d:/path
) or was that already broken?
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.
No it shouldn't.
At least to my knowledge. As far as I understand it the drive letter notation is really a windows only thing and on other systems rather use names for different drives like /externaldrive/some/path
or /drive2/some/path
.
Therefore any drive notation is stripped on these systems, but mostly as a precaution, as you never know how people write their paths.
However drive notated paths on Windows systems are kept intact (thanks to the Path.sep === '/'
check which ensures this is only done on non Windows machines).
You could argue that the check is redundant, as people probably wouldn't use the drive notation anyway. But I am just so used to try and foresee stupid errors that I added it.
Let me know if you think we keep it or not.
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.
Okay, thanks for explaining. We can leave it.
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.
Just an update on the UNIX pathing system. I asked around and for UNIX systems (Linxus + MAC) you change drive by typing something like /volumes/drive
. So absolute paths always start with a '/' on those systems. So it should be good like this.
src/lib/utils/paths.ts
Outdated
|
||
export function createMinimatch(pattern: string[]): IMinimatch[]; | ||
export function createMinimatch(pattern: string): IMinimatch; | ||
export function createMinimatch(pattern: string | string[]): IMinimatch | IMinimatch[] { |
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.
since all usages are IMinimatch[]
and to avoid overloaded functions, please remove this function and inline x.map(convertToMinimatch)
where createMinimatch
was being used.
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.
ok... if you prefer, I can remove the overloads, but as the function is used two places already (which is why I created it in the first place), so I prefer to keep the function it self to avoid having duplicate the code in the code base.
And it is easier to unit test the method used if it is isolated like this.
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.
okay, that sounds good to me
src/lib/utils/paths.ts
Outdated
pattern = pattern.replace(/^\w:/, ''); | ||
} | ||
|
||
if (pattern[0] !== '*') { |
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.
Should this be checking for **
? If the path is not resolved for */test.js
then I think it won't work with /project/base/*/test.js
which is what I would expect
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.
hm... yeah you might be right... I will correct it.
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.
Great! Thanks for iterating on this with me. I'll merge after I get some issues with tests on master fixed.
Sure thing! Thanks for your input. |
There we go. Tests are passing now. |
Strict null checks required a few changes to code changed by this PR.
Thanks for the contribution! I'm sorry this took so long to merge. |
this.load(event, Path.resolve(event.data[TSConfigReader.OPTIONS_KEY])); | ||
const tsconfig = event.data[TSConfigReader.OPTIONS_KEY]; | ||
|
||
if (/tsconfig\.json$/.test(tsconfig)) { |
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 think that this line is responsible for making typedoc 0.14 a breaking change for my projects.
The path that I use for my config file is something like node_modules/my-config-project/config/typedoc.config.json
This worked fine in 0.13 but breaks in 0.14.
I now need to update the path on 60+ projects..
This PR main purpose is to optimize the options that uses glob patterns, as they were not working optimally, as well as making sure config files are found correctly.
(unit test added for the general Minimatch function)
Glob pattern options
--externalPattern
and--exclude
options now behaves according to expectations of many developers../my/path/**
,../my/path/**
andmy/path/**
all correctly matches paths relative to the project root./unix-style/path/**
,C:/win-style/path/**
and**/my/path/**
all still matches full paths as before.{ dot: true }
has been added to the Minimatch as per PR Allow exclusion of directories starting with a dot #711typedoc.js(on)
--options
option anytypedoc.js
ortypedoc.json
will automatically be searched for in the root of the project (withtypedoc.js
taking precedence).--options
option anytypedoc.js
ortypedoc.json
in the root of that directory will be searched for (withtypedoc.js
taking precedence). If no file is found in the directory an error is raised.tsconfig.json
Original functionality has not been altered, but
--tsconfig
can now also take a directory path instead of only a directtsconfig.json
path.