66 "fmt"
77 "os"
88 "strings"
9+
10+ "github.com/github/codeql-go/extractor/util"
911)
1012
1113// ProjectLayout describes a very simple project layout rewriting paths starting
@@ -16,7 +18,7 @@ import (
1618// # to
1719// from//
1820type ProjectLayout struct {
19- from , to string
21+ From , To string
2022}
2123
2224// normaliseSlashes adds an initial slash to `path` if there isn't one, and trims
@@ -28,6 +30,25 @@ func normaliseSlashes(path string) string {
2830 return strings .TrimSuffix (path , "/" )
2931}
3032
33+ // LoadProjectLayoutFromEnv loads a project layout from the file referenced by the
34+ // {CODEQL,SEMMLE}_PATH_TRANSFORMER environment variable. If neither env var is set, returns nil. If
35+ // the file cannot be read or does not have the right format, it returns an error.
36+ func LoadProjectLayoutFromEnv () (* ProjectLayout , error ) {
37+ pt := util .Getenv ("CODEQL_PATH_TRANSFORMER" , "SEMMLE_PATH_TRANSFORMER" )
38+ if pt == "" {
39+ return nil , nil
40+ }
41+ ptf , err := os .Open (pt )
42+ if err != nil {
43+ return nil , err
44+ }
45+ pathTransformer , err = LoadProjectLayout (ptf )
46+ if err != nil {
47+ return nil , err
48+ }
49+ return pathTransformer , nil
50+ }
51+
3152// LoadProjectLayout loads a project layout from the given file, returning an error
3253// if the file does not have the right format
3354func LoadProjectLayout (file * os.File ) (* ProjectLayout , error ) {
@@ -41,7 +62,7 @@ func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
4162 if ! strings .HasPrefix (line , "#" ) {
4263 return nil , fmt .Errorf ("first line of project layout should start with #, but got %s" , line )
4364 }
44- res .to = normaliseSlashes (strings .TrimSpace (strings .TrimPrefix (line , "#" )))
65+ res .To = normaliseSlashes (strings .TrimSpace (strings .TrimPrefix (line , "#" )))
4566
4667 if ! scanner .Scan () {
4768 return nil , errors .New ("empty section in project-layout file" )
@@ -57,7 +78,7 @@ func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
5778 if strings .HasPrefix (line , "-" ) || strings .Contains (line , "*" ) || strings .Contains (line , "//" ) {
5879 return nil , errors .New ("unsupported project-layout feature" )
5980 }
60- res .from = normaliseSlashes (line )
81+ res .From = normaliseSlashes (line )
6182
6283 for scanner .Scan () {
6384 if strings .TrimSpace (scanner .Text ()) != "" {
@@ -71,11 +92,11 @@ func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
7192// transformString transforms `str` as specified by the project layout: if it starts with the `from`
7293// prefix, that prefix is relaced by `to`; otherwise the string is returned unchanged
7394func (p * ProjectLayout ) transformString (str string ) string {
74- if str == p .from {
75- return p .to
95+ if str == p .From {
96+ return p .To
7697 }
77- if strings .HasPrefix (str , p .from + "/" ) {
78- return p .to + "/" + str [len (p .from )+ 1 :]
98+ if strings .HasPrefix (str , p .From + "/" ) {
99+ return p .To + "/" + str [len (p .From )+ 1 :]
79100 }
80101 return str
81102}
0 commit comments