From 305f62d20fd5ea4c1f4f2a50e3ce4472abb5b074 Mon Sep 17 00:00:00 2001 From: Yuri Goncharuk Date: Sat, 22 Aug 2026 21:42:18 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20CLI-=D1=84=D0=BB=D0=B0=D0=B3=20-c=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D0=B2=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=B8=D0=B7=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/oscript/BehaviorSelector.cs | 1 + src/oscript/ExecuteCodeBehavior.cs | 75 ++++++++++++++++++++++++++++++ src/oscript/ShowUsageBehavior.cs | 2 + tests/cli-eval.os | 73 +++++++++++++++++++++++++++++ tests/process.os | 2 + 5 files changed, 153 insertions(+) create mode 100644 src/oscript/ExecuteCodeBehavior.cs create mode 100644 tests/cli-eval.os diff --git a/src/oscript/BehaviorSelector.cs b/src/oscript/BehaviorSelector.cs index 264cfb64f..be49228eb 100644 --- a/src/oscript/BehaviorSelector.cs +++ b/src/oscript/BehaviorSelector.cs @@ -44,6 +44,7 @@ private static AppBehavior SelectParametrized(CmdLineHelper helper) initializers.Add("-cgi", h => new CgiBehavior()); initializers.Add("-version", h => new ShowVersionBehavior()); initializers.Add("-v", h => new ShowVersionBehavior()); + initializers.Add("-c", ExecuteCodeBehavior.Create); initializers.Add("-encoding", ProcessEncodingKey); initializers.Add("-codestat", EnableCodeStatistics); initializers.Add("-debug", DebugBehavior.Create); diff --git a/src/oscript/ExecuteCodeBehavior.cs b/src/oscript/ExecuteCodeBehavior.cs new file mode 100644 index 000000000..1180ab9d7 --- /dev/null +++ b/src/oscript/ExecuteCodeBehavior.cs @@ -0,0 +1,75 @@ +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ +using System; +using System.IO; +using OneScript.StandardLibrary; +using ScriptEngine; +using ScriptEngine.HostedScript; +using ScriptEngine.Hosting; +using ScriptEngine.Machine; + +namespace oscript +{ + internal class ExecuteCodeBehavior(string code, string[] args) : AppBehavior, IHostApplication, ISystemLogWriter + { + private readonly string _code = code; + private readonly string[] _scriptArgs = args; + + public static AppBehavior Create(CmdLineHelper helper) + { + var code = helper.Next(); + if (string.IsNullOrEmpty(code)) + return null; + + return new ExecuteCodeBehavior(code, helper.Tail()); + } + + public override int Execute() + { + SystemLogger.SetWriter(this); + + var configPath = Path.Combine(Environment.CurrentDirectory, CfgFileConfigProvider.CONFIG_FILE_NAME); + var builder = ConsoleHostBuilder.Create(configPath); + var hostedScript = ConsoleHostBuilder.Build(builder); + var source = hostedScript.Loader.FromString(_code); + + Process process; + try + { + process = hostedScript.CreateProcess(this, source); + } + catch (Exception e) + { + ShowExceptionInfo(e); + return 1; + } + + var result = process.Start(); + hostedScript.Dispose(); + return result; + } + + #region IHostApplication Members + + public void Echo(string text, MessageStatusEnum status = MessageStatusEnum.Ordinary) + => ConsoleHostImpl.Echo(text, status); + + public void ShowExceptionInfo(Exception exc) + => ConsoleHostImpl.ShowExceptionInfo(exc); + + public bool InputString(out string result, string prompt, int maxLen, bool multiline) + => ConsoleHostImpl.InputString(out result, prompt, maxLen, multiline); + + public string[] GetCommandLineArguments() + => _scriptArgs; + + #endregion + + public void Write(string text) + => Console.Error.WriteLine(text); + } +} diff --git a/src/oscript/ShowUsageBehavior.cs b/src/oscript/ShowUsageBehavior.cs index ee1c26a57..d3bf00470 100644 --- a/src/oscript/ShowUsageBehavior.cs +++ b/src/oscript/ShowUsageBehavior.cs @@ -15,6 +15,7 @@ public override int Execute() Output.WriteLine(); Output.WriteLine("Usage:"); Output.WriteLine(" oscript.exe [options] [script_arguments...]"); + Output.WriteLine(" oscript.exe [options] -c [script_arguments...]"); Output.WriteLine(" oscript.exe [mode_options] [script_arguments...]"); Output.WriteLine(); @@ -34,6 +35,7 @@ public override int Execute() Output.WriteLine($" {"",modeWidth} {"-port=",subOptionWidth} Debugger port (default is 2801)."); Output.WriteLine($" {"",modeWidth} {"-noWait",subOptionWidth} Do not wait for debugger connection."); + Output.WriteLine($" {"-c",modeWidth} Execute code from command line."); Output.WriteLine($" {"-version, -v",modeWidth} Output version string."); Output.WriteLine(); diff --git a/tests/cli-eval.os b/tests/cli-eval.os new file mode 100644 index 000000000..2d0d92903 --- /dev/null +++ b/tests/cli-eval.os @@ -0,0 +1,73 @@ +Перем юТест; + +Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт + + юТест = ЮнитТестирование; + + ВсеТесты = Новый Массив; + ВсеТесты.Добавить("ТестДолжен_ВыполнитьКодЧерезФлагC"); + ВсеТесты.Добавить("ТестДолжен_ПередатьАргументыПослеКода"); + ВсеТесты.Добавить("ТестДолжен_ПоказатьUsageЕслиНетКода"); + ВсеТесты.Добавить("ТестДолжен_РаботатьСEncoding"); + + Возврат ВсеТесты; + +КонецФункции + +Функция ПутьОСкрипт() + Возврат "dotnet """ + ОбъединитьПути(КаталогПрограммы(), "oscript.dll") + """"; +КонецФункции + +Функция НормализоватьВывод(Знач Текст) + Текст = СтрЗаменить(Текст, Символы.ВК, ""); + Возврат СокрЛП(Текст); +КонецФункции + +Функция ЗапуститьОскрипт(Знач Аргументы) + + Процесс = СоздатьПроцесс(ПутьОСкрипт() + " " + Аргументы, , Истина, , КодировкаТекста.UTF8); + Процесс.Запустить(); + Процесс.ОжидатьЗавершения(); + + Результат = Новый Структура; + Результат.Вставить("КодВозврата", Процесс.КодВозврата); + Результат.Вставить("Вывод", НормализоватьВывод(Процесс.ПотокВывода.Прочитать())); + Возврат Результат; + +КонецФункции + +Процедура ТестДолжен_ВыполнитьКодЧерезФлагC() Экспорт + + Результат = ЗапуститьОскрипт("-c ""Сообщить(1+2)"""); + + юТест.ПроверитьРавенство(0, Результат.КодВозврата, "Код возврата"); + юТест.ПроверитьРавенство("3", Результат.Вывод, "Вывод выражения"); + +КонецПроцедуры + +Процедура ТестДолжен_ПередатьАргументыПослеКода() Экспорт + + Результат = ЗапуститьОскрипт("-c ""Сообщить(АргументыКоманднойСтроки[0])"" hello"); + + юТест.ПроверитьРавенство(0, Результат.КодВозврата, "Код возврата"); + юТест.ПроверитьРавенство("hello", Результат.Вывод, "Аргумент скрипта"); + +КонецПроцедуры + +Процедура ТестДолжен_ПоказатьUsageЕслиНетКода() Экспорт + + Результат = ЗапуститьОскрипт("-c"); + + юТест.ПроверитьРавенство(0, Результат.КодВозврата, "Код возврата usage"); + юТест.ПроверитьИстину(СтрНайти(Результат.Вывод, "-c") > 0, "В usage должен быть флаг -c"); + +КонецПроцедуры + +Процедура ТестДолжен_РаботатьСEncoding() Экспорт + + Результат = ЗапуститьОскрипт("-encoding=utf-8 -c ""Сообщить(""""привет"""")"""); + + юТест.ПроверитьРавенство(0, Результат.КодВозврата, "Код возврата"); + юТест.ПроверитьРавенство("привет", Результат.Вывод, "Вывод с -encoding"); + +КонецПроцедуры diff --git a/tests/process.os b/tests/process.os index 44da651b5..f8db0b823 100644 --- a/tests/process.os +++ b/tests/process.os @@ -145,6 +145,7 @@ | |Usage: | oscript.exe [options] [script_arguments...] + | oscript.exe [options] -c [script_arguments...] | oscript.exe [mode_options] [script_arguments...] | |Modes: @@ -158,6 +159,7 @@ | Options: | -port= Debugger port (default is 2801). | -noWait Do not wait for debugger connection. + | -c Execute code from command line. | -version, -v Output version string. | |Options: From 2fea849f08b34d0e8919057718b7d0dcc402e9d3 Mon Sep 17 00:00:00 2001 From: Yuri Goncharuk Date: Sat, 22 Aug 2026 23:34:58 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A3=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=B4=D1=83=D0=B1=D0=BB=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20IHostApplication=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=B6=D0=B4=D1=83=20behaviors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/oscript/ConsoleApplicationHost.cs | 51 +++++++++++++++++++++ src/oscript/ExecuteCodeBehavior.cs | 50 +++------------------ src/oscript/ExecuteScriptBehavior.cs | 64 ++++----------------------- 3 files changed, 66 insertions(+), 99 deletions(-) create mode 100644 src/oscript/ConsoleApplicationHost.cs diff --git a/src/oscript/ConsoleApplicationHost.cs b/src/oscript/ConsoleApplicationHost.cs new file mode 100644 index 000000000..45b2bc11c --- /dev/null +++ b/src/oscript/ConsoleApplicationHost.cs @@ -0,0 +1,51 @@ +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ + +using System; +using OneScript.Sources; +using OneScript.StandardLibrary; +using ScriptEngine; +using ScriptEngine.HostedScript; + +namespace oscript +{ + internal class ConsoleApplicationHost(string[] args) : IHostApplication, ISystemLogWriter + { + public void Echo(string text, MessageStatusEnum status = MessageStatusEnum.Ordinary) + => ConsoleHostImpl.Echo(text, status); + + public void ShowExceptionInfo(Exception exc) + => ConsoleHostImpl.ShowExceptionInfo(exc); + + public bool InputString(out string result, string prompt, int maxLen, bool multiline) + => ConsoleHostImpl.InputString(out result, prompt, maxLen, multiline); + + public string[] GetCommandLineArguments() + => args; + + public void Write(string text) + => Console.Error.WriteLine(text); + + public int RunProcess(HostedScriptEngine engine, SourceCode source) + { + SystemLogger.SetWriter(this); + + Process process; + try + { + process = engine.CreateProcess(this, source); + } + catch (Exception e) + { + ShowExceptionInfo(e); + return 1; + } + + return process.Start(); + } + } +} diff --git a/src/oscript/ExecuteCodeBehavior.cs b/src/oscript/ExecuteCodeBehavior.cs index 1180ab9d7..0e943e5e2 100644 --- a/src/oscript/ExecuteCodeBehavior.cs +++ b/src/oscript/ExecuteCodeBehavior.cs @@ -4,20 +4,16 @@ This Source Code Form is subject to the terms of the was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------------------------------------------------------*/ + using System; using System.IO; -using OneScript.StandardLibrary; -using ScriptEngine; using ScriptEngine.HostedScript; -using ScriptEngine.Hosting; -using ScriptEngine.Machine; namespace oscript { - internal class ExecuteCodeBehavior(string code, string[] args) : AppBehavior, IHostApplication, ISystemLogWriter + internal class ExecuteCodeBehavior(string code, string[] args) : AppBehavior { - private readonly string _code = code; - private readonly string[] _scriptArgs = args; + private readonly ConsoleApplicationHost _host = new(args); public static AppBehavior Create(CmdLineHelper helper) { @@ -30,46 +26,12 @@ public static AppBehavior Create(CmdLineHelper helper) public override int Execute() { - SystemLogger.SetWriter(this); - var configPath = Path.Combine(Environment.CurrentDirectory, CfgFileConfigProvider.CONFIG_FILE_NAME); var builder = ConsoleHostBuilder.Create(configPath); - var hostedScript = ConsoleHostBuilder.Build(builder); - var source = hostedScript.Loader.FromString(_code); - - Process process; - try - { - process = hostedScript.CreateProcess(this, source); - } - catch (Exception e) - { - ShowExceptionInfo(e); - return 1; - } + using var hostedScript = ConsoleHostBuilder.Build(builder); + var source = hostedScript.Loader.FromString(code); - var result = process.Start(); - hostedScript.Dispose(); - return result; + return _host.RunProcess(hostedScript, source); } - - #region IHostApplication Members - - public void Echo(string text, MessageStatusEnum status = MessageStatusEnum.Ordinary) - => ConsoleHostImpl.Echo(text, status); - - public void ShowExceptionInfo(Exception exc) - => ConsoleHostImpl.ShowExceptionInfo(exc); - - public bool InputString(out string result, string prompt, int maxLen, bool multiline) - => ConsoleHostImpl.InputString(out result, prompt, maxLen, multiline); - - public string[] GetCommandLineArguments() - => _scriptArgs; - - #endregion - - public void Write(string text) - => Console.Error.WriteLine(text); } } diff --git a/src/oscript/ExecuteScriptBehavior.cs b/src/oscript/ExecuteScriptBehavior.cs index 49cbc29c4..0d77883db 100644 --- a/src/oscript/ExecuteScriptBehavior.cs +++ b/src/oscript/ExecuteScriptBehavior.cs @@ -4,25 +4,23 @@ This Source Code Form is subject to the terms of the was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------------------------------------------------------*/ -using System; -using OneScript.StandardLibrary; -using ScriptEngine; -using ScriptEngine.HostedScript; + +using System.IO; using ScriptEngine.Hosting; using ScriptEngine.Machine; using ScriptEngine.Machine.Debugger; namespace oscript { - class ExecuteScriptBehavior : AppBehavior, IHostApplication, ISystemLogWriter + class ExecuteScriptBehavior : AppBehavior { - protected string[] _scriptArgs; protected string _path; + private readonly ConsoleApplicationHost _host; public ExecuteScriptBehavior(string path, string[] args) { - _scriptArgs = args; _path = path; + _host = new ConsoleApplicationHost(args); } public IDebugger DebugController { get; set; } = new DisabledDebugger(); @@ -33,14 +31,12 @@ public ExecuteScriptBehavior(string path, string[] args) public override int Execute() { - if (!System.IO.File.Exists(_path)) + if (!File.Exists(_path)) { - Echo($"Script file is not found '{_path}'"); + _host.Echo($"Script file is not found '{_path}'"); return 2; } - SystemLogger.SetWriter(this); - var builder = ConsoleHostBuilder.Create(_path); builder.WithDebugger(DebugController); CodeStatProcessor codeStatProcessor = null; @@ -50,22 +46,9 @@ public override int Execute() builder.Services.RegisterSingleton(codeStatProcessor); } - var hostedScript = ConsoleHostBuilder.Build(builder); - + using var hostedScript = ConsoleHostBuilder.Build(builder); var source = hostedScript.Loader.FromFile(_path); - Process process; - try - { - process = hostedScript.CreateProcess(this, source); - } - catch (Exception e) - { - ShowExceptionInfo(e); - return 1; - } - - var result = process.Start(); - hostedScript.Dispose(); + var result = _host.RunProcess(hostedScript, source); if (codeStatProcessor != null) { @@ -77,34 +60,5 @@ public override int Execute() return result; } - - #region IHostApplication Members - - public void Echo(string text, MessageStatusEnum status = MessageStatusEnum.Ordinary) - { - ConsoleHostImpl.Echo(text, status); - } - - public void ShowExceptionInfo(Exception exc) - { - ConsoleHostImpl.ShowExceptionInfo(exc); - } - - public bool InputString(out string result, string prompt, int maxLen, bool multiline) - { - return ConsoleHostImpl.InputString(out result, prompt, maxLen, multiline); - } - - public string[] GetCommandLineArguments() - { - return _scriptArgs; - } - - #endregion - - public void Write(string text) - { - Console.Error.WriteLine(text); - } } }