Skip to content

Commit

Permalink
Merge pull request #11 from flagship-io/fix/regex
Browse files Browse the repository at this point in the history
Fix/regex
  • Loading branch information
Chadiii authored Feb 20, 2023
2 parents d3b9a5d + 57777e6 commit 3a4935c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 71 deletions.
36 changes: 22 additions & 14 deletions internal/files/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ func GetFlagType(defaultValue string) (string, string) {
var flagType string = "string"
var flagTypeInterface interface{}

r, _ := regexp.Compile(`[^\w#]`)
r, _ := regexp.Compile(`[\{\}\[\]]`)

json.Unmarshal([]byte(defaultValue), &flagTypeInterface)

if match := r.MatchString(defaultValue); match {
flagType = "unknown"
}

if defaultValue[0:1] == "\"" {
defaultValue = strings.Trim(defaultValue, "\"")
if (defaultValue[0:1] == "\"" || defaultValue[0:1] == "'") && (defaultValue[len(defaultValue)-1:] == "\"" || defaultValue[len(defaultValue)-1:] == "'") {
flagType = "string"
}

Expand Down Expand Up @@ -86,30 +85,34 @@ func SearchFiles(cfg *config.Config, path string, resultChannel chan model.FileS

// Add default regex for flags in commentaries
flagRegexes = append(flagRegexes, model.FlagRegex{
FunctionRegex: `(?s)fs:flag:(\w+)`,
FieldRegex: `fs:flag:(.+)`,
FieldRegex: `fs:flag:(.+)`,
})

results := []model.SearchResult{}

flagIndexes := [][]int{}
for _, flagRegex := range flagRegexes {
regxp := regexp.MustCompile(flagRegex.FunctionRegex)
regxp := regexp.MustCompile(flagRegex.FieldRegex)
flagLineIndexes := regxp.FindAllStringIndex(fileContentStr, -1)

for _, flagLineIndex := range flagLineIndexes {
submatch := fileContentStr[flagLineIndex[0]:flagLineIndex[1]]
regxp := regexp.MustCompile(flagRegex.FieldRegex)

submatchIndexes := regxp.FindAllStringSubmatchIndex(submatch, -1)

for k, submatchIndex := range submatchIndexes {
if len(submatchIndex) < 6 {
for _, submatchIndex := range submatchIndexes {
if len(submatchIndex) < 3 {
log.Printf("Did not find the flag key in file %s. Code : %s", path, submatch)
continue
}
if !flagRegex.HasMultipleKeys && k > 0 {
break

if len(submatchIndex) < 6 {
log.Printf("Did not find the flag default value in file %s. Code : %s", path, submatch)
flagIndexes = append(flagIndexes, []int{
flagLineIndex[0] + submatchIndex[2],
flagLineIndex[0] + submatchIndex[3],
})
continue
}

flagIndexes = append(flagIndexes, []int{
Expand All @@ -124,11 +127,18 @@ func SearchFiles(cfg *config.Config, path string, resultChannel chan model.FileS

for _, flagIndex := range flagIndexes {
// Extract the code with a certain number of lines
defaultValue_ := ""
flagType := "unknown"
firstLineIndex := getSurroundingLineIndex(fileContentStr, flagIndex[0], true, cfg.NbLineCodeEdges)
lastLineIndex := getSurroundingLineIndex(fileContentStr, flagIndex[1], false, cfg.NbLineCodeEdges)
code := fileContentStr[firstLineIndex:lastLineIndex]
key := fileContentStr[flagIndex[0]:flagIndex[1]]
defaultValue := fileContentStr[flagIndex[2]:flagIndex[3]]

if len(flagIndex) >= 3 {
defaultValue := fileContentStr[flagIndex[2]:flagIndex[3]]
flagType, defaultValue_ = GetFlagType(defaultValue)
}

// Better value wrapper for code highlighting (5 chars wrapping)
keyWrapper := key
nbCharsWrapping := 5
Expand All @@ -139,8 +149,6 @@ func SearchFiles(cfg *config.Config, path string, resultChannel chan model.FileS
lineNumber := getLineFromPos(fileContentStr, flagIndex[0])
codeLineHighlight := getLineFromPos(code, strings.Index(code, keyWrapper))

flagType, defaultValue_ := GetFlagType(defaultValue)

results = append(results, model.SearchResult{
FlagKey: key,
FlagDefaultValue: defaultValue_,
Expand Down
10 changes: 5 additions & 5 deletions internal/files/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ func TestSearchFiles(t *testing.T) {
{name: "btnSizeInt", lineNumber: 25, codeLineHighlight: 6},
},
},
/* {
{
filePath: "../../example/src/ios/SDK_V3/sample.swift",
flags: []flag{
{name: "btnColor", lineNumber: 9, codeLineHighlight: 5},
{name: "displayVipFeature", lineNumber: 10, codeLineHighlight: 5},
{name: "vipFeature", lineNumber: 11, codeLineHighlight: 5},
{name: "btnColor", lineNumber: 9, codeLineHighlight: 6},
{name: "displayVipFeature", lineNumber: 10, codeLineHighlight: 6},
{name: "vipFeature", lineNumber: 11, codeLineHighlight: 6},
},
}, */
},
{
filePath: "../../example/src/java/SDK_V2/sample.java",
flags: []flag{
Expand Down
69 changes: 20 additions & 49 deletions internal/model/language_regexes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,143 +11,114 @@ type LanguageRegex struct {
}

type FlagRegex struct {
FunctionRegex string `json:"function_regex"`
FieldRegex string `json:"field_regex"`
HasMultipleKeys bool `json:"has_multiple_keys"`
FieldRegex string `json:"field_regex"`
}

var LanguageRegexes = []LanguageRegex{
{
ExtensionRegex: `\.[jt]sx?$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)useFsModifications\(.+?\)`, // SDK React V2
FieldRegex: `['"]?key['"]?\s*\:\s*['"](.+?)['"](?:.*\s*)['"]?defaultValue['"]?\s*\:\s*['"]?(.+?)['"]?\s*[\"\,]`,
HasMultipleKeys: true,
FieldRegex: `useFsFlag[(](?:\s*['"](.*)['"]\s*,\s*(["'].*\s*[^"]*["']|[^)]*))\s*[)]`, // SDK React V3
},
{
FunctionRegex: `(?s)useFsFlag\(.+?\)`, // SDK React V3
FieldRegex: `useFsFlag\(['"]?\s*(.+?)['"](?:.\s*)['"]?(.+?)['"]?\s*[\"\)]`,
HasMultipleKeys: true,
FieldRegex: `['"]?key['"]?\s*\:\s*['"](.+?)['"](?:.*\s*)['"]?defaultValue['"]?\s*\:\s*(['"].*['"]|[^\r\n\t\f\v,}]+).*[},]?`, // SDK JS V2 && SDK React V2
},
{
FunctionRegex: `(?s)\.getModifications\(.+?\].+?\)`, // SDK JS V2
FieldRegex: `['"]?key['"]?\s*\:\s*['"](.+?)['"](?:.*\s*)['"]?defaultValue['"]?\s*\:\s*['"]?(.+?)['"]?\s*[\"\,]`,
HasMultipleKeys: true,
},
{
FunctionRegex: `(?s)getFlag\(.+?\)`, // SDK JS V3
FieldRegex: `getFlag\(['"]?\s*(.+?)['"](?:.\s*)['"]?(.+?)['"]?\s*[\"\)\,]`,
HasMultipleKeys: true,
FieldRegex: `getFlag[(](?:\s*["'](.*)["']\s*,\s*(["'].*\s*[^"]*["']|[^)]*))\s*[)]`, // SDK JS V3
},
},
},
{
ExtensionRegex: `\.go$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\.GetModification(String|Number|Bool|Object|Array)\(.+?\)`, // SDK GO V2
FieldRegex: `\s*['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\,]`,
FieldRegex: `\.GetModification(?:String|Number|Bool|Object|Array)\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK GO V2
},
},
},
{
ExtensionRegex: `\.py$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\.get_modification\(.+?\)`, // SDK PYTHON V2
FieldRegex: `\s*['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\)\,]`,
FieldRegex: `\.get_modification\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|True|False|\d+|"[^"]*"))?\s*\)`, // SDK PYTHON V2
},
},
},
{
ExtensionRegex: `\.java$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\.getModification\(.+?\)`, // SDK JAVA V2
FieldRegex: `\s*['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\)\,]`,
FieldRegex: `\.getModification\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK JAVA V2
},
{
FunctionRegex: `(?s)\.getFlag\(.+?\)`, // SDK JAVA V3
FieldRegex: `(?s)\.getFlag\(['"](.+?)['"](?:.\s*)['"]?(.+?)['"]?\s*[\"\)\,]`,
FieldRegex: `\.getFlag[(](?:\s*["'](.*)["']\s*,\s*(["'].*\s*[^"]*["']|[^)]*))\s*[)]`, // SDK JAVA V3
},
},
},
{
ExtensionRegex: `\.php$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\-\>getModification\(.+?\)`, // SDK PHP V2
FieldRegex: `\s*['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\)\,]`,
FieldRegex: `\-\>getModification\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK PHP V1 && SDK PHP V2
},
{
FunctionRegex: `(?s)\-\>getFlag\(.+?\)`, // SDK PHP V3
FieldRegex: `(?s)\-\>getFlag\(['"](.+?)['"](?:.\s*)['"]?(.+?)['"]?\s*[\"\)\,]`,
FieldRegex: `\-\>getFlag[(](?:\s*["'](.*)["']\s*,\s*(["'].*\s*[^"]*["']|[^)]*))\s*[)]`, // SDK PHP V3
},
},
},
{
ExtensionRegex: `\.kt$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\.getModification\(.+?\)`, // SDK ANDROID V2
FieldRegex: `\s*['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\)\,]`,
FieldRegex: `\.getModification\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK ANDROID V2
},
{
FunctionRegex: `(?s)\.getFlag\(.+?\)`, // SDK ANDROID V3
FieldRegex: `(?s)\.getFlag\(['"](.+?)['"](?:.\s*)['"]?(.+?)['"]?\s*[\"\)\,]`,
FieldRegex: `\.getFlag[(](?:\s*["'](.*)["']\s*,\s*(["'].*\s*[^"]*["']|[^)]*))\s*[)]`, // SDK ANDROID V3
},
},
},
{
ExtensionRegex: `\.swift$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\.getModification\(.+?\)`, // SDK iOS V2
FieldRegex: `\s*['"](.+?)['"](?:,\s*)['"]?default(?:String|Double|Bool|Float|Int|Json|Array)['"]?\s*\:\s*['"]?(.+?)['"]?\s*[\"\,]`,
FieldRegex: `\.getModification\(\s*["'](\w+)['"]\s*,\s*default(?:String|Double|Float|Int|Bool|Json|Array)\s*:\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)\s*(?:,\s*activate\s*:\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK iOS V2
},
{
FunctionRegex: `(?s)\.getFlag\(key: ['"](.+?)['"]`, // SDK iOS V3
FieldRegex: `['"]?key['"]?\s*\:\s*['"](.+?)['"](?:.*\s*)['"]?defaultValue['"]?\s*\:\s*['"]?(.+?)['"]?\s*[\)]`,
FieldRegex: `\.getFlag[(]\s*key\s*:\s*(?:\s*["'](.*)["']\s*,\s*defaultValue\s*:\s*(["'].*\s*[^"]*["']|[^)]*))\s*[)]`, // SDK iOS V3
},
},
},
{
ExtensionRegex: `\.m$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\]\s*getModification:@.+?\]`, // SDK iOS V2
FieldRegex: `\s*['"](.+?)['"](?:\s*)default(?:String|Double|Bool|Float|Int|Json|Array):\@?\s*(['"](.+?)['"]|YES|NO|TRUE|FALSE|true|false|\d*\.?\d+)?`,
FieldRegex: `getModification\s*:\s*@\s*['"](.+?)['"](?:\s*)default(?:String|Double|Bool|Float|Int|Json|Array):\@?\s*(['"].+?['"]|YES|NO|TRUE|FALSE|true|false|[+-]?(?:\d*[.])?\d+)?`, // SDK iOS V2
},
{
FunctionRegex: `(?s)\s*getFlagWithKey:@.+?\]`, // SDK iOS V3
FieldRegex: `\s*getFlagWithKey:@['"](.+?)['"](?:\s*)['"]?defaultValue['"]?\s*\:\@?\s*['"]?(.+?)['"]?\s*[\]]`,
FieldRegex: `getFlagWithKey\s*:\s*\@['"](.+?)['"](?:\s*)['"]?defaultValue['"]?\s*\:\s*\@?\s*(.+?)\s*[\]]`, // SDK iOS V3
},
},
},
{
ExtensionRegex: `\.[fc]s$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\.GetModification\(.+?\)`, // SDK .NET V1
FieldRegex: `(?s)\.GetModification\(['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\)\,]`,
FieldRegex: `\.GetModification\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK .NET V1
},
{
FunctionRegex: `(?s)\.GetFlag\(.+?\)`, // SDK .NET V3
FieldRegex: `(?s)\.GetFlag\(['"](.+?)['"](?:.\s*)['"]?(.+?)['"]?\s*[\"\)\,]`,
FieldRegex: `\.GetFlag\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK .NET V3
},
},
},
{
ExtensionRegex: `\.vb$`,
FlagRegexes: []FlagRegex{
{
FunctionRegex: `(?s)\.GetModification\(.+?\)`, // SDK .NET V1
FieldRegex: `(?s)\.GetModification\(['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\)\,]`,
FieldRegex: `\.GetModification\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|True|false|False|\d+|"[^"]*"))?\s*\)`, // SDK .NET V1
},
{
FunctionRegex: `(?s)\.GetFlag\(.+?\)`, // SDK .NET V3
FieldRegex: `(?s)\.GetFlag\(['"](.+?)['"](?:,\s*)['"]?(.+?)['"]?\s*[\)\,]`,
FieldRegex: `\.GetFlag\(\s*["']([\w\-]+)['"]\s*,\s*(["'][^"]*['"]|[+-]?(?:\d*[.])?\d+|true|false|False|True)(?:\s*,\s*(?:true|false|\d+|"[^"]*"))?\s*\)`, // SDK .NET V3
},
},
},
Expand Down
4 changes: 1 addition & 3 deletions internal/model/language_regexes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func TestCustomRegex(t *testing.T) {
AddCustomRegexes(`[{"extension_regex":".tsx?","flag_regexes":[{"function_regex":"(?s)useFlagShipActivation\\(.+?\\)","field_regex":"\\s*['\"](.+?)['\"]","has_multiple_keys":true}]}]`)
AddCustomRegexes(`[{"extension_regex":".tsx?","flag_regexes":[{"field_regex":"\\s*['\"](.+?)['\"]"}]}]`)

found := funk.Find(LanguageRegexes, func(languageRegex LanguageRegex) bool {
return languageRegex.ExtensionRegex == ".tsx?"
Expand All @@ -22,7 +22,5 @@ func TestCustomRegex(t *testing.T) {

assert.Equal(t, ".tsx?", foundLanguageRegex.ExtensionRegex)
assert.Equal(t, 1, len(foundLanguageRegex.FlagRegexes))
assert.Equal(t, "(?s)useFlagShipActivation\\(.+?\\)", foundLanguageRegex.FlagRegexes[0].FunctionRegex)
assert.Equal(t, "\\s*['\"](.+?)['\"]", foundLanguageRegex.FlagRegexes[0].FieldRegex)
assert.Equal(t, true, foundLanguageRegex.FlagRegexes[0].HasMultipleKeys)
}

0 comments on commit 3a4935c

Please sign in to comment.