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: