Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions internal/tsoptions/wildcarddirectories.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package tsoptions

import (
"regexp"
"strings"

"github.com/dlclark/regexp2"
Expand All @@ -28,13 +27,13 @@ func getWildcardDirectories(include []string, exclude []string, comparePathsOpti
}

rawExcludeRegex := vfs.GetRegularExpressionForWildcard(exclude, comparePathsOptions.CurrentDirectory, "exclude")
var excludeRegex *regexp.Regexp
var excludeRegex *regexp2.Regexp
if rawExcludeRegex != "" {
options := ""
flags := regexp2.ECMAScript
if !comparePathsOptions.UseCaseSensitiveFileNames {
options = "(?i)"
flags |= regexp2.IgnoreCase
}
excludeRegex = regexp.MustCompile(options + rawExcludeRegex)
excludeRegex = regexp2.MustCompile(rawExcludeRegex, regexp2.RegexOptions(flags))
}

wildcardDirectories := make(map[string]bool)
Expand All @@ -44,8 +43,10 @@ func getWildcardDirectories(include []string, exclude []string, comparePathsOpti

for _, file := range include {
spec := tspath.NormalizeSlashes(tspath.CombinePaths(comparePathsOptions.CurrentDirectory, file))
if excludeRegex != nil && excludeRegex.MatchString(spec) {
continue
if excludeRegex != nil {
if matched, _ := excludeRegex.MatchString(spec); matched {
continue
}
}

match := getWildcardDirectoryFromSpec(spec, comparePathsOptions.UseCaseSensitiveFileNames)
Expand Down
65 changes: 65 additions & 0 deletions internal/tsoptions/wildcarddirectories_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package tsoptions

import (
"testing"

"github.com/microsoft/typescript-go/internal/tspath"
)

func TestGetWildcardDirectories_NonASCIICharacters(t *testing.T) {
t.Parallel()

tests := []struct {
name string
include []string
exclude []string
currentDirectory string
useCaseSensitiveFileNames bool
}{
{
name: "Norwegian character æ in path",
include: []string{"src/**/*.test.ts", "src/**/*.stories.ts", "src/**/*.mdx"},
exclude: []string{"node_modules"},
currentDirectory: "C:/Users/TobiasLægreid/dev/app/frontend/packages/react",
useCaseSensitiveFileNames: false,
},
{
name: "Japanese characters in path",
include: []string{"src/**/*.ts"},
exclude: []string{"テスト"},
currentDirectory: "/Users/ユーザー/プロジェクト",
useCaseSensitiveFileNames: true,
},
{
name: "Chinese characters in path",
include: []string{"源代码/**/*.js"},
exclude: []string{"节点模块"},
currentDirectory: "/home/用户/项目",
useCaseSensitiveFileNames: true,
},
{
name: "Various Unicode characters",
include: []string{"src/**/*.ts"},
exclude: []string{"node_modules"},
currentDirectory: "/Users/Müller/café/naïve/résumé",
useCaseSensitiveFileNames: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

comparePathsOptions := tspath.ComparePathsOptions{
CurrentDirectory: tt.currentDirectory,
UseCaseSensitiveFileNames: tt.useCaseSensitiveFileNames,
}

result := getWildcardDirectories(tt.include, tt.exclude, comparePathsOptions)

if result == nil {
t.Fatalf("expected non-nil result")
}
})
}
}
8 changes: 4 additions & 4 deletions internal/vfs/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ func IsImplicitGlob(lastPathComponent string) bool {
return !strings.ContainsAny(lastPathComponent, ".*?")
}

// Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
// It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
// proof.
// Reserved characters - only escape actual regex metacharacters.
// Go's regexp doesn't support \x escape sequences for arbitrary characters,
// so we only escape characters that have special meaning in regex.
var (
reservedCharacterPattern *regexp.Regexp = regexp.MustCompile(`[^\w\s/]`)
reservedCharacterPattern *regexp.Regexp = regexp.MustCompile(`[\\.\+*?()\[\]{}^$|#]`)
Copy link
Member

Choose a reason for hiding this comment

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

The goal of suggesting regex2 was to avoid making this particular change. If we still want to restrict the characters, it makes me think we should just use QuoteMeta and not change anything else.

wildcardCharCodes = []rune{'*', '?'}
)

Expand Down