From fc29ec649adbdfe194c9fc3ab8fbd07a4bf2b34e Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Thu, 27 Nov 2025 22:11:08 +0100 Subject: [PATCH 1/3] Bump Scriban to net8.0 --- src/Scriban.Benchmarks/Scriban.Benchmarks.csproj | 2 +- src/Scriban.DelegateCodeGen/Scriban.DelegateCodeGen.csproj | 2 +- src/Scriban.DocGen/Scriban.DocGen.csproj | 2 +- src/Scriban.Tests/Scriban.Tests.csproj | 2 +- src/Scriban/Scriban.props | 4 ++-- src/liquid2scriban/liquid2scriban.csproj | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Scriban.Benchmarks/Scriban.Benchmarks.csproj b/src/Scriban.Benchmarks/Scriban.Benchmarks.csproj index 65e79289..251fd8ab 100644 --- a/src/Scriban.Benchmarks/Scriban.Benchmarks.csproj +++ b/src/Scriban.Benchmarks/Scriban.Benchmarks.csproj @@ -1,7 +1,7 @@ Exe - net8.0 + net10.0 false diff --git a/src/Scriban.DelegateCodeGen/Scriban.DelegateCodeGen.csproj b/src/Scriban.DelegateCodeGen/Scriban.DelegateCodeGen.csproj index f03f2068..d5342053 100644 --- a/src/Scriban.DelegateCodeGen/Scriban.DelegateCodeGen.csproj +++ b/src/Scriban.DelegateCodeGen/Scriban.DelegateCodeGen.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 false diff --git a/src/Scriban.DocGen/Scriban.DocGen.csproj b/src/Scriban.DocGen/Scriban.DocGen.csproj index f3292fb8..e3deef9b 100644 --- a/src/Scriban.DocGen/Scriban.DocGen.csproj +++ b/src/Scriban.DocGen/Scriban.DocGen.csproj @@ -1,7 +1,7 @@ Exe - net8.0 + net10.0 false diff --git a/src/Scriban.Tests/Scriban.Tests.csproj b/src/Scriban.Tests/Scriban.Tests.csproj index 6072196a..c2e4f994 100644 --- a/src/Scriban.Tests/Scriban.Tests.csproj +++ b/src/Scriban.Tests/Scriban.Tests.csproj @@ -1,6 +1,6 @@ - net8.0 + net10.0 false diff --git a/src/Scriban/Scriban.props b/src/Scriban/Scriban.props index 0d707a03..c6a978bc 100644 --- a/src/Scriban/Scriban.props +++ b/src/Scriban/Scriban.props @@ -4,10 +4,10 @@ Scriban is a fast, powerful, safe and lightweight scripting language and engine for .NET, which was primarily developed for text templating with a compatibility mode for parsing liquid templates. Alexandre Mutel en-US - 8.0 $(DefineConstants);SCRIBAN_PUBLIC Alexandre Mutel - netstandard2.0;net7.0 + netstandard2.0;net8.0 + 8.0 templating;handlebars;liquid scriban.png readme.md diff --git a/src/liquid2scriban/liquid2scriban.csproj b/src/liquid2scriban/liquid2scriban.csproj index 6cbe6f48..bc69598e 100644 --- a/src/liquid2scriban/liquid2scriban.csproj +++ b/src/liquid2scriban/liquid2scriban.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 false From 577e2d4782dc86c87abaad6451b3039a705ce3f4 Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Wed, 18 Feb 2026 07:56:35 +0100 Subject: [PATCH 2/3] Fix setting variable in a scope while it is also declared in an outer scope This behavior was counterintuitive and leading to awful bugs when used with "with" syntax for example --- ...105-assign-readonly-builtin-error1.out.txt | 1 - ...-assign-readonly-builtin-no-error1.out.txt | 3 ++ ...105-assign-readonly-builtin-no-error1.txt} | 0 .../105-assign-readonly-error2.out.txt | 1 - .../105-assign-readonly-error2.txt | 8 ----- .../105-assign-readonly-no-error2.out.txt | 0 .../105-assign-readonly-no-error2.txt | 8 +++++ src/Scriban/TemplateContext.Variables.cs | 36 +++++++------------ 8 files changed, 23 insertions(+), 34 deletions(-) delete mode 100644 src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-error1.out.txt create mode 100644 src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-no-error1.out.txt rename src/Scriban.Tests/TestFiles/100-expressions/{105-assign-readonly-builtin-error1.txt => 105-assign-readonly-builtin-no-error1.txt} (100%) delete mode 100644 src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.out.txt delete mode 100644 src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.txt create mode 100644 src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-no-error2.out.txt create mode 100644 src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-no-error2.txt diff --git a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-error1.out.txt b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-error1.out.txt deleted file mode 100644 index 71ff92f4..00000000 --- a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-error1.out.txt +++ /dev/null @@ -1 +0,0 @@ -text(4,4) : error : Cannot set the builtin readonly variable `string` \ No newline at end of file diff --git a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-no-error1.out.txt b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-no-error1.out.txt new file mode 100644 index 00000000..4135032d --- /dev/null +++ b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-no-error1.out.txt @@ -0,0 +1,3 @@ +# Cannot assign to a builtin variable +string = null +=== diff --git a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-error1.txt b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-no-error1.txt similarity index 100% rename from src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-error1.txt rename to src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-builtin-no-error1.txt diff --git a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.out.txt b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.out.txt deleted file mode 100644 index 3cf3a971..00000000 --- a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.out.txt +++ /dev/null @@ -1 +0,0 @@ -text(6,5) : error : Cannot set the readonly variable `x` \ No newline at end of file diff --git a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.txt b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.txt deleted file mode 100644 index adca7da8..00000000 --- a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-error2.txt +++ /dev/null @@ -1,8 +0,0 @@ -{{ -x = 5 -readonly x -y = {} -with y - x = 6 # We should not be able to set a variable here that is declared readonly above -end -}} \ No newline at end of file diff --git a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-no-error2.out.txt b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-no-error2.out.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-no-error2.txt b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-no-error2.txt new file mode 100644 index 00000000..dfc58be4 --- /dev/null +++ b/src/Scriban.Tests/TestFiles/100-expressions/105-assign-readonly-no-error2.txt @@ -0,0 +1,8 @@ +{{ +x = 5 +readonly x +y = {} +with y + x = 6 # We should be able to set a variable here even if it is declared readonly above +end +}} \ No newline at end of file diff --git a/src/Scriban/TemplateContext.Variables.cs b/src/Scriban/TemplateContext.Variables.cs index 1a81eead..00760af3 100644 --- a/src/Scriban/TemplateContext.Variables.cs +++ b/src/Scriban/TemplateContext.Variables.cs @@ -4,6 +4,11 @@ #nullable disable +using Scriban.Functions; +using Scriban.Helpers; +using Scriban.Parsing; +using Scriban.Runtime; +using Scriban.Syntax; using System; using System.Collections; using System.Collections.Generic; @@ -14,11 +19,7 @@ using System.Reflection; // Leave this as it is required by some .NET targets using System.Text; using System.Threading.Tasks; -using Scriban.Functions; -using Scriban.Helpers; -using Scriban.Parsing; -using Scriban.Runtime; -using Scriban.Syntax; +using System.Xml.Linq; namespace Scriban { @@ -319,31 +320,18 @@ private IScriptObject GetStoreForWrite(ScriptVariable variable) switch (scope) { case ScriptVariableScope.Global: - // In scientific we always resolve to local storage first - IScriptObject storeWithVariable = null; - var name = variable.Name; int lastStoreIndex = _globalContexts.Count - 1; var items = _globalContexts.Items; - for (int i = lastStoreIndex; i >= 0; i--) + finalStore = items[lastStoreIndex].LocalObject; + // We check that for upper store, we actually can write a variable with this name + // otherwise we don't allow to create a variable with the same name as a readonly variable + if (!finalStore.CanWrite(name)) { - var store = items[i].LocalObject; - if (storeWithVariable == null && store.Contains(name)) - { - storeWithVariable = store; - } - - // We check that for upper store, we actually can write a variable with this name - // otherwise we don't allow to create a variable with the same name as a readonly variable - if (!store.CanWrite(name)) - { - var variableType = store == BuiltinObject ? "builtin " : string.Empty; - throw new ScriptRuntimeException(variable.Span, $"Cannot set the {variableType}readonly variable `{variable}`"); - } + var variableType = finalStore == BuiltinObject ? "builtin " : string.Empty; + throw new ScriptRuntimeException(variable.Span, $"Cannot set the {variableType}readonly variable `{variable}`"); } - // If we have a store for this variable name use it, otherwise use the first store available. - finalStore = storeWithVariable ?? items[lastStoreIndex].LocalObject; break; case ScriptVariableScope.Local: if (_currentLocalContext.LocalObject != null) From f00a6bbfb3fb5b3ee1a537cff36d7e101b7c45e5 Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Wed, 18 Feb 2026 07:56:51 +0100 Subject: [PATCH 3/3] Update date.now in tests for 2026 --- doc/builtins.md | 2 +- license.txt | 2 +- src/Scriban/Functions/DateTimeFunctions.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/builtins.md b/doc/builtins.md index 9255b915..c9dbf185 100644 --- a/doc/builtins.md +++ b/doc/builtins.md @@ -785,7 +785,7 @@ Returns a datetime object of the current time, including the hour, minutes, seco ``` > **output** ```html -2025 +2026 ``` [:top:](#builtins) diff --git a/license.txt b/license.txt index 75862165..f508d411 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2016-2024, Alexandre Mutel +Copyright (c) 2016-2026, Alexandre Mutel All rights reserved. Redistribution and use in source and binary forms, with or without modification diff --git a/src/Scriban/Functions/DateTimeFunctions.cs b/src/Scriban/Functions/DateTimeFunctions.cs index d56e7fb7..b71fe5f1 100644 --- a/src/Scriban/Functions/DateTimeFunctions.cs +++ b/src/Scriban/Functions/DateTimeFunctions.cs @@ -128,7 +128,7 @@ public string Format /// {{ date.now.year }} /// ``` /// ```html - /// 2025 + /// 2026 /// ``` /// public static DateTime Now() => DateTime.Now;