Skip to content
Merged
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
3 changes: 3 additions & 0 deletions src/Terrabuild.Common/String.fs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ let startsWith (start: string) (s: string) =

let trim (s: string) =
s.Trim()

let replace (substring: string) (value: string) (s: string) =
s.Replace(substring, value)
1 change: 1 addition & 0 deletions src/Terrabuild.Configuration.Tests/TestFiles/WORKSPACE2
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ configuration {
secret2: $list.2
secret3: !false + !true
secret4: format("1", 2, $toto, true, nothing)
secret5: tostring(42)
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/Terrabuild.Configuration.Tests/Workspace.fs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ let parseWorkspace2() =
Expr.Number 2
Expr.Variable "toto"
Expr.Bool true
Expr.Nothing
]) ] }
Expr.Nothing ])
"secret5", Expr.Function (Function.ToString, [Expr.Number 42])
] }

let extDotnet =
{ Container = Some "mcr.microsoft.com/dotnet/sdk:8.0.101"
Expand Down
299 changes: 159 additions & 140 deletions src/Terrabuild.Configuration/Gen/ProjectLexer.fs

Large diffs are not rendered by default.

496 changes: 257 additions & 239 deletions src/Terrabuild.Configuration/Gen/ProjectParser.fs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Terrabuild.Configuration/Gen/ProjectParser.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type token =
| COUNT
| VERSION
| FORMAT
| TOSTRING
| MINUS
| PLUS
| COMMA
Expand Down Expand Up @@ -84,6 +85,7 @@ type tokenId =
| TOKEN_COUNT
| TOKEN_VERSION
| TOKEN_FORMAT
| TOKEN_TOSTRING
| TOKEN_MINUS
| TOKEN_PLUS
| TOKEN_COMMA
Expand Down
285 changes: 152 additions & 133 deletions src/Terrabuild.Configuration/Gen/WorkspaceLexer.fs

Large diffs are not rendered by default.

454 changes: 236 additions & 218 deletions src/Terrabuild.Configuration/Gen/WorkspaceParser.fs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Terrabuild.Configuration/Gen/WorkspaceParser.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type token =
| COUNT
| VERSION
| FORMAT
| TOSTRING
| MINUS
| PLUS
| COMMA
Expand Down Expand Up @@ -78,6 +79,7 @@ type tokenId =
| TOKEN_COUNT
| TOKEN_VERSION
| TOKEN_FORMAT
| TOKEN_TOSTRING
| TOKEN_MINUS
| TOKEN_PLUS
| TOKEN_COMMA
Expand Down
1 change: 1 addition & 0 deletions src/Terrabuild.Configuration/ProjectParser/Lexer.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ rule token = parse
| "count" { COUNT }
| "version" { VERSION }
| "format" { FORMAT }
| "tostring" { TOSTRING }
| "??" { DOUBLE_QUESTION }
| "?" { QUESTION }
| ".?" { DOT_QUESTION }
Expand Down
3 changes: 2 additions & 1 deletion src/Terrabuild.Configuration/ProjectParser/Parser.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let debugPrint s = ignore s
%token EQUAL DOUBLE_EQUAL NOT_EQUAL
%token COMMA
%token MINUS PLUS
%token TRIM UPPER LOWER REPLACE COUNT VERSION FORMAT
%token TRIM UPPER LOWER REPLACE COUNT VERSION FORMAT TOSTRING
%token DOUBLE_QUESTION QUESTION COLON BANG
%token EOF
%token PROJECT EXTENSION TARGET
Expand Down Expand Up @@ -149,6 +149,7 @@ Expr:
| COUNT ExprTuple { Expr.Function (Function.Count, $2)}
| VERSION ExprTuple { Expr.Function (Function.Version, $2) }
| FORMAT ExprTuple { Expr.Function (Function.Format, $2) }
| TOSTRING ExprTuple { Expr.Function (Function.ToString, $2) }
| Expr DOUBLE_QUESTION Expr { Expr.Function (Function.Coalesce, [$1; $3]) }
| Expr QUESTION Expr COLON Expr { Expr.Function (Function.Ternary, [$1; $3; $5] ) }
| BANG Expr { Expr.Function (Function.Not, [$2]) }
Expand Down
1 change: 1 addition & 0 deletions src/Terrabuild.Configuration/WorkspaceParser/Lexer.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ rule token = parse
| "count" { COUNT }
| "version" { VERSION }
| "format" { FORMAT }
| "tostring" { TOSTRING }
| "??" { DOUBLE_QUESTION }
| "?" { QUESTION }
| ".?" { DOT_QUESTION }
Expand Down
3 changes: 2 additions & 1 deletion src/Terrabuild.Configuration/WorkspaceParser/Parser.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let debugPrint s = ignore s
%token EQUAL DOUBLE_EQUAL NOT_EQUAL
%token COMMA
%token MINUS PLUS
%token TRIM UPPER LOWER REPLACE COUNT VERSION FORMAT
%token TRIM UPPER LOWER REPLACE COUNT VERSION FORMAT TOSTRING
%token DOUBLE_QUESTION QUESTION COLON BANG
%token EOF
%token WORKSPACE TARGET CONFIGURATION EXTENSION
Expand Down Expand Up @@ -134,6 +134,7 @@ Expr:
| COUNT ExprTuple { Expr.Function (Function.Count, $2)}
| VERSION ExprTuple { Expr.Function (Function.Version, $2) }
| FORMAT ExprTuple { Expr.Function (Function.Format, $2) }
| TOSTRING ExprTuple { Expr.Function (Function.ToString, $2) }
| Expr DOUBLE_QUESTION Expr { Expr.Function (Function.Coalesce, [$1; $3]) }
| Expr QUESTION Expr COLON Expr { Expr.Function (Function.Ternary, [$1; $3; $5] ) }
| BANG Expr { Expr.Function (Function.Not, [$2]) }
Expand Down
25 changes: 23 additions & 2 deletions src/Terrabuild.Expressions.Tests/Eval.fs
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,17 @@ let version() =
result |> should equal expected

[<Test>]
let format() =
let expected = Value.String "\\o/42truetiti"
let formatList() =
let expected = Value.String "\\o/THIS42ISAtrueTEMPLATEtiti"
let expectedUsedVars = Set [ "toto" ]

let context = { evaluationContext
with Variables = Map ["toto", Value.String "\\o/" |> mkVar] }

// format("{0}THIS{1}IS{2}A{3}TEMPLATE{4}", $toto, 42, nothing, true, "titi")
let result, varUsed =
eval context (Expr.Function (Function.Format, [
Expr.String "{0}THIS{1}IS{2}A{3}TEMPLATE{4}"
Expr.Variable "toto"
Expr.Number 42
Expr.Nothing
Expand All @@ -183,6 +185,25 @@ let format() =
varUsed |> should equal expectedUsedVars
result |> should equal expected

[<Test>]
let formatMap() =
let expected = Value.String "THIS\\o/IS42ATEMPLATEtrue"
let expectedUsedVars = Set [ "args" ]

let context = { evaluationContext
with Variables = Map ["args", Value.Map (Map [ "string", Value.String "\\o/"
"number", Value.Number 42
"nothing", Value.Nothing
"bool", Value.Bool true ]) |> mkVar ] }

// format("THIS{string}IS{number}A{nothing}TEMPLATE{bool}", $args)
let result, varUsed =
eval context (Expr.Function (Function.Format, [
Expr.String "THIS{string}IS{number}A{nothing}TEMPLATE{bool}"
Expr.Variable "args" ]))
varUsed |> should equal expectedUsedVars
result |> should equal expected


[<Test>]
let listItem() =
Expand Down
55 changes: 43 additions & 12 deletions src/Terrabuild.Expressions/Eval.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ type EvaluationContext = {
}

let rec eval (context: EvaluationContext) (expr: Expr) =
let valueToString v =
match v with
| Value.Nothing -> ""
| Value.Bool b -> if b then "true" else "false"
| Value.Number n -> $"{n}"
| Value.String s -> s
| _ -> TerrabuildException.Raise($"Unsupported type for format {v}")

let rec eval (expr: Expr) =
match expr with
| Expr.Nothing -> Value.Nothing, Set.empty
Expand Down Expand Up @@ -76,18 +84,41 @@ let rec eval (context: EvaluationContext) (expr: Expr) =
| Some version -> Value.String version
| _ -> TerrabuildException.Raise($"Unknown project reference '{str}'")

| Function.Format, values ->
let formatValue v =
match v with
| Value.Nothing -> ""
| Value.Bool b -> if b then "true" else "false"
| Value.Number n -> $"{n}"
| Value.String s -> s
| _ -> TerrabuildException.Raise($"Unsupported type for format {v}")

values
|> List.fold (fun acc value -> $"{acc}{formatValue value}") ""
|> Value.String
| Function.ToString, [value] -> valueToString value |> Value.String

| Function.Format, [Value.String template; Value.Map values] ->
let rec replaceAll template =
match template with
| String.Regex "{([^}]+)}" [name] ->
let value =
match values |> Map.tryFind name with
| Some value -> valueToString value
| _ -> TerrabuildException.Raise($"Field {name} does not exist")
template
|> String.replace $"{{{name}}}" value
|> replaceAll
| _ -> template

replaceAll template |> Value.String

| Function.Format, Value.String template :: values ->
let values = values |> List.map valueToString

let rec replaceAll template =
match template with
| String.Regex "{([^}]+)}" [index] ->
let value =
match System.Int32.TryParse index with
| (true, index) ->
if 0 <= index && index < values.Length then values[index]
else TerrabuildException.Raise($"Format index is out of range")
| _ -> TerrabuildException.Raise($"Format index is not a number")
template
|> String.replace $"{{{index}}}" value
|> replaceAll
| _ -> template

replaceAll template |> Value.String

| Function.Item, [Value.Map map; Value.String key] ->
match map |> Map.tryFind key with
Expand Down
1 change: 1 addition & 0 deletions src/Terrabuild.Expressions/Expr.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type Function =
| Count
| Version
| Format
| ToString
| Item
| TryItem
| Coalesce
Expand Down
Loading