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

Adds glob-style pattern matching for file specifications using new "include" property in tsconfig.json #3232

Closed
wants to merge 11 commits into from

Conversation

rbuckton
Copy link
Member

Adds support for expanding glob-like patterns in "include" and "exclude" properties of tsconfig.json. The following patterns are supported:

  • * - Matches zero or more characters, excluding directory separators.
  • ? - Matches any one character, excluding directory separators.
  • [abc] - Matches any one character in the set { "a", "b", "c" }.
  • [a-z] - Matches any one character in between "a" and "z".
  • [!abc] - Matches any one character not in the set { "a", "b", "c" }.
  • **/ - Recursively matches any subdirectory.

At this time, character escape sequences are not supported, as there is no standard cross-platform convention. The standard escape sequence in a Unix shell is prefixed with \, which is reserved as a directory separator on Windows, and is normalized to / by TypeScript.

This does not use the glob module, as TypeScript runs in more host environments than just NodeJS, and this would need interoperate with the language service host.

{
    "compilerOptions": {
        "out": "test.js"
    },
    "files": [
      "literal.ts"
    ],
    "include": [
        "**/*.ts"
    ],
    "exclude": [
        "node_modules",
        "tests/**/*.spec.ts",
        "utils/t2.ts"
    ]
}
  • Files in the "files" list are always added to the list of files.
  • The "exclude" list only applies to files matched via "include".
  • If neither "files" nor "include" are present, "include" defaults to "**/*.ts". This preserves the existing behavior.

@rbuckton
Copy link
Member Author

This differs slightly from #3188, as to how to exclude a directory. The pattern matching here is expecting to match files, so to exclude a directory you would have to change the example from #3188 to the following:

{
    "compilerOptions": {
        "out": "test.js"
    },
    "exclude": [
        "node_modules/**/*",
        "test.ts",
        "utils/t2.ts"
    ]
}

It would, however, be feasible to change the implementation of createExcludePattern to be less restrictive.

Edit: This is now supported. You should be able to do the following:

{
    "compilerOptions": {
        "out": "test.js"
    },
    "exclude": [
        "node_modules",
        "test.ts",
        "utils/t2.ts"
    ]
}

@ahejlsberg
Copy link
Member

Looks interesting. The question here is whether the delta between the simple exclude list and this PR is worth another 500 lines of non-trivial code (plus we'd have to add tests for all the wildcard features). I do think the vast majority of use cases are covered with just a simple list. Also, the simple list solution has the advantage that it never even enumerates excluded subfolders whereas this code appears to enumerate them and the subsequently eliminates all the files. This could be significant from a performance perspective. And obviously it's fixable with some extra work.

@rbuckton
Copy link
Member Author

In the simple list case, if there are no wildcards in the file list, no directories are enumerated. I agree that a small change can avoid enumerating excluded directories in the case where there is a wildcard in the list, by checking the base path against the exclusion list prior to descending into a directory in both expandWildcard and expandRecursiveDirectory.

@rbuckton
Copy link
Member Author

I've made a few changes, for your consideration:

  • The "files" property no longer supports wildcard matching, files in the "files" array are always added.
  • The "exclude" property no longer applies to "files", which is consistent with Support "exclude" property in tsconfig.json #3188.
  • Added an "include" property, which supports wildcards.
  • A literal file specification in the "include" array will be skipped if it is not present on disk.
  • If neither "files" nor "include" are present in in the file, "include" would have the default value of ["**/*.ts"], which preserves the existing behavior when "files" is not present.

I've also added a number of tests to cover this feature.

@rbuckton rbuckton changed the title Adds glob pattern matching for files in tsconfig.json Adds glob-style pattern matching for file specifications using new "include" property in tsconfig.json May 21, 2015
@rbuckton rbuckton changed the title Adds glob-style pattern matching for file specifications using new "include" property in tsconfig.json Adds glob-style pattern matching for file specifications using new "include" property in tsconfig.json May 21, 2015
@MicahZoltu
Copy link
Contributor

Is it safe to assume that the pattern matching is relative to the directory the tsconfig.json file is located in? What if the user specifies the --rootDir compiler option? Will the paths be relative to the supplied root directory?

I assume the pattern matching is on the full (relative) path? foo.ts would not match bar/foo.ts?

* @param isLiteralFile A value indicating whether the file to be added is
* a literal file, or the result of matching a file specification.
*/
function includeFile(file: string, isLiteralFile: boolean): void {

Choose a reason for hiding this comment

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

It's better to add the output array as a function parameter to decouple this function from expandFiles instead using a closure to access output. This increases readability, decoupling, testing and performance of the function. This same comment probably applies to other functions defined in expandFiles too.

@scottwio
Copy link

Is this still happening seems to have stalled

@mhegazy
Copy link
Contributor

mhegazy commented Jul 30, 2015

@rbuckton got busy with other changes. i would say it is open for others to pick it up if anyone is interested.

@nickroberts
Copy link

Would love to see this, or something like the atom-typescript filesGlob property. We can't get everyone to use Atom, so this would be great if it was native.

I know the community is yearning for glob support!

@Dashue
Copy link

Dashue commented Oct 5, 2015

+1

@dsebastien
Copy link

+1 million, this will make things much easier for some Angular/RxJS users who don't simply have the hello world example file structure :)

@chrsmrtn-
Copy link

+1 as well. Can hobble along without, but this would make things a lot easier for me. Started using Aurelia which includes it's own d.ts files. They track versions in the file path for the definition file. So I can see each time I update, i'll have to manually update all references into the framework so typescript can find the definition files. With this in, then I can path match to ignore the version part of the path so typescript will always find the updated definition file.

@glen-84
Copy link

glen-84 commented Nov 29, 2015

I spent over 4 hours last night trying to get this to run on top of the latest code. First with a rebase, which had about 8 or 9 conflicted files, where I was able to resolve all but one of those (commandLineParser.ts), which was just too confusing for me. Then I aborted that, and tried to reconstruct the branch manually, but I quickly ran into issues with the test system (which is what I tried to start with). So, I gave up. I just don't know enough about the code and the testing system. :(

@rbuckton, do you think that you will ever find time to finish this, or at least rebase it, or will it have to be picked up by someone else?

@chrsmrtn-, one option is to use exclude instead of files, but it's not ideal.

@Codier
Copy link

Codier commented Dec 2, 2015

Really need this +million

@scottwio
Copy link

scottwio commented Dec 2, 2015

It's crazy that this is pretty much being ignored, editors are adding file globs into them and people are creating modules just to do this task clearly the community want this feature. As a work around I currently have a watch with https://github.com/wjohnsto/tsconfig-glob and tsc, you could also go down the route of grunt-ts.

@rbuckton
Copy link
Member Author

rbuckton commented Dec 3, 2015

@scottwio: Actually, I'm about to close this PR and open a new one with an updated implementation.

@scottwio
Copy link

scottwio commented Dec 3, 2015

@rbuckton in that case your my hero

@rbuckton
Copy link
Member Author

rbuckton commented Dec 7, 2015

Closed in favor of #5980.

@rbuckton rbuckton closed this Dec 7, 2015
@mhegazy mhegazy deleted the glob branch December 7, 2015 23:05
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.