diff --git a/CHANGELOG.md b/CHANGELOG.md index c5bc858c6b5e..0e64c5e290ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -398,6 +398,8 @@ `Time_Of_Day`, `Time_Zone`, and `URI` to `Text`.][6404] - [Implemented `create_database_table` allowing upload of in-memory tables.][6429] +- [Added execution context control to writing files and dry run capabilities to + `Text.write`.][6459] [debug-shortcuts]: https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug @@ -602,6 +604,7 @@ [6404]: https://github.com/enso-org/enso/pull/6404 [6347]: https://github.com/enso-org/enso/pull/6347 [6429]: https://github.com/enso-org/enso/pull/6429 +[6459]: https://github.com/enso-org/enso/pull/6459 #### Enso Compiler diff --git a/app/gui/controller/engine-protocol/src/language_server.rs b/app/gui/controller/engine-protocol/src/language_server.rs index 5ebe1784818c..9ae91a906ab3 100644 --- a/app/gui/controller/engine-protocol/src/language_server.rs +++ b/app/gui/controller/engine-protocol/src/language_server.rs @@ -157,7 +157,7 @@ trait API { /// Restart the program execution. #[MethodInput=RecomputeInput, rpc_name="executionContext/recompute"] - fn recompute(&self, context_id: ContextId, invalidated_expressions: InvalidatedExpressions, mode: Option) -> (); + fn recompute(&self, context_id: ContextId, invalidated_expressions: InvalidatedExpressions, execution_environment: Option) -> (); /// Obtain the full suggestions database. #[MethodInput=GetSuggestionsDatabaseInput, rpc_name="search/getSuggestionsDatabase"] diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso index 976093aadcb9..9ff73ff38a73 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso @@ -16,10 +16,9 @@ import project.Network.HTTP.Request.Request import project.Network.HTTP.Request_Error import project.Nothing.Nothing import project.System.File.File -import project.System.File_Format.Auto_Detect -import project.System.File_Format.File_Format from project.Data.Boolean import Boolean, True, False +from project.System.File_Format import Auto_Detect, File_Format, format_widget ## ALIAS Load, Open Reads a file into Enso. @@ -56,6 +55,7 @@ from project.Data.Boolean import Boolean, True, False import Standard.Examples example_xls_to_table = Data.read Examples.xls (Excel (Worksheet 'Dates')) +@format format_widget read : Text | File -> File_Format -> Problem_Behavior -> Any ! File_Error read path format=Auto_Detect (on_problems=Problem_Behavior.Report_Warning) = File.new path . read format on_problems @@ -81,6 +81,7 @@ read path format=Auto_Detect (on_problems=Problem_Behavior.Report_Warning) = import Standard.Examples example_read = Data.read_text Examples.csv_path +@encoding Encoding.default_widget read_text : (Text | File) -> Encoding -> Problem_Behavior -> Text read_text path (encoding=Encoding.utf_8) (on_problems=Problem_Behavior.Report_Warning) = File.new path . read_text encoding on_problems diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso index 21749c2334ad..b2478bcc5dc9 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso @@ -9,8 +9,19 @@ polyglot java import java.nio.charset.Charset polyglot java import java.nio.charset.UnsupportedCharsetException polyglot java import org.enso.base.Text_Utils +from project.Metadata.Widget import Single_Choice +from project.Metadata.Choice import Option +import project.Metadata.Display + ## Represents a character encoding. type Encoding + ## PRIVATE + Gets the default drop down option for this encoding. + default_widget : Single_Choice + default_widget = + values = [Option "UTF-8" "Encoding.utf_8", Option "ASCII" "Encoding.ascii", Option "UTF-16LE" "Encoding.utf_16_le", Option "UTF-16BE" "Encoding.utf_16_be", Option "UTF-32LE" "Encoding.utf_32_le", Option "UTF-32BE" "Encoding.utf_32_be", Option "Windows-1250" "Encoding.windows_1250", Option "Windows-1251" "Encoding.windows_1251", Option "Windows-1252" "Encoding.windows_1252", Option "Windows-1253" "Encoding.windows_1253", Option "Windows-1254" "Encoding.windows_1254", Option "Windows-1255" "Encoding.windows_1255", Option "Windows-1256" "Encoding.windows_1256", Option "Windows-1257" "Encoding.windows_1257", Option "Windows-1258" "Encoding.windows_1258"] + Single_Choice values=values display=Display.When_Modified + ## PRIVATE ADVANCED Get all available character sets from Java as Encodings. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso index d1c7918dc9fb..c36c4ba34b72 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso @@ -644,6 +644,7 @@ Text.is_whitespace self = Get the ASCII bytes of the text "Hello". "Hello".bytes (Encoding.ascii) +@encoding Encoding.default_widget Text.bytes : Encoding -> Problem_Behavior -> Vector Integer Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning = result = Encoding_Utils.get_bytes self (encoding . to_java_charset) @@ -664,6 +665,7 @@ Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning = Get the ASCII bytes of the text "Hello". "Hello".bytes (Encoding.ascii) +@encoding Encoding.default_widget Text.from_bytes : Vector Integer -> Encoding -> Problem_Behavior -> Text Text.from_bytes bytes encoding on_problems=Problem_Behavior.Report_Error = result = Encoding_Utils.from_bytes bytes.to_array (encoding . to_java_charset) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso index f509acd7b384..6f0fb3e0c146 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Errors/Common.enso @@ -336,3 +336,16 @@ type Forbidden_Operation Convert the Forbidden_Operation error to a human-readable format. to_display_text : Text to_display_text self = "Forbidden operation: "+self.operation+"." + +type Dry_Run_Operation + ## PRIVATE + A warning that the operation has only been performed in a test mode. + + Arguments: + - message: The message to be displayed. + Warning message + + ## PRIVATE + Convert the Dry_Run_Operation to a human-readable format. + to_display_text : Text + to_display_text self = self.message diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Main.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Main.enso index 3d3749e1893d..6f978b0b6fc3 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Main.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Main.enso @@ -63,7 +63,7 @@ export project.Warning.Warning from project.Data.Boolean export Boolean, True, False from project.Function export all from project.Data.Numbers export Number, Integer, Decimal -from project.System.File_Format export File_Format, Plain_Text_Format, Plain_Text, Bytes, Infer, Auto_Detect, JSON_File +from project.System.File_Format export File_Format, Plain_Text_Format, Plain_Text, Bytes, Infer, Auto_Detect, JSON_Format import project.Data import project.Data.Filter_Condition.Filter_Condition diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso index 40ecb4a4dae8..f505f80f77bb 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso @@ -1,6 +1,8 @@ import project.Any.Any import project.Data.Array.Array import project.Data.Boolean.Boolean +import project.Data.Text.Case.Case +import project.Data.Text.Extensions import project.Data.Text.Text import project.Data.Vector.Vector import project.Errors.Common.Forbidden_Operation @@ -159,7 +161,18 @@ type Context - environment: Name of the execution environment. - context: The context to enable. is_enabled : Text -> Boolean - is_enabled self environment=Runtime.current_execution_environment = @Builtin_Method "Context.is_enabled" + is_enabled self environment=Runtime.current_execution_environment = + self.is_enabled_builtin (environment.to_case Case.Lower) + + ## PRIVATE + is_enabled_builtin : Text -> Boolean + is_enabled_builtin self environment = @Builtin_Method "Context.is_enabled_builtin" + + ## PRIVATE + Run an action with the Context enabled. + with_enabled : Function -> Any + with_enabled self ~action = + with_enabled_context self Runtime.current_execution_environment action ## PRIVATE @@ -179,7 +192,8 @@ current_execution_environment = @Builtin_Method "Runtime.current_execution_envir - context: The context to enable. - action: Action to be performed with the context enabled. with_enabled_context : Context -> Text -> Function -> Any -with_enabled_context context environment=Runtime.current_execution_environment ~action = with_enabled_context_builtin context environment action +with_enabled_context context environment=Runtime.current_execution_environment ~action = + with_enabled_context_builtin context (environment.to_case Case.Lower) action ## PRIVATE ADVANCED @@ -205,7 +219,8 @@ with_enabled_context_builtin context environment ~action = @Builtin_Method "Runt - context: The context to disable. - action: Action to be performed with the context disabled. with_disabled_context : Context -> Text -> Function -> Any -with_disabled_context context environment=Runtime.current_execution_environment ~action = with_disabled_context_builtin context environment action +with_disabled_context context environment=Runtime.current_execution_environment ~action = + with_disabled_context_builtin context (environment.to_case Case.Lower) action ## PRIVATE ADVANCED diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso index 4a542edd7a60..b3447407e838 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso @@ -11,6 +11,7 @@ import project.Data.Text.Text import project.Data.Time.Time_Of_Day.Time_Of_Day import project.Data.Vector.Vector import project.Error.Error +import project.Errors.Common.Forbidden_Operation import project.Errors.Encoding_Error.Encoding_Error import project.Errors.File_Error.File_Error import project.Errors.Illegal_Argument.Illegal_Argument @@ -18,21 +19,23 @@ import project.Errors.Problem_Behavior.Problem_Behavior import project.Meta import project.Nothing.Nothing import project.Panic.Panic +import project.Runtime.Context import project.Runtime.Managed_Resource.Managed_Resource import project.System.File.File_Access.File_Access -import project.System.File_Format.Auto_Detect -import project.System.File_Format.File_Format import project.System.File.File_Permissions.File_Permissions from project.Data.Boolean import Boolean, True, False +from project.System.File_Format import Auto_Detect, File_Format, format_widget import project.Metadata.Widget from project.Metadata.Choice import Option import project.Metadata.Display +polyglot java import org.enso.base.DryRunFileManager polyglot java import org.enso.base.Encoding_Utils polyglot java import org.enso.base.encoding.ReportingStreamDecoder polyglot java import org.enso.base.encoding.ReportingStreamEncoder +polyglot java import java.io.File as Java_File polyglot java import java.io.InputStream as Java_Input_Stream polyglot java import java.io.OutputStream as Java_Output_Stream polyglot java import java.nio.file.FileSystems @@ -64,6 +67,28 @@ type File _ : File -> path _ -> Error.throw (Illegal_Argument.Error "new file should be either a File or a Text") + ## Creates a temporary file which will be deleted when Enso exits. + create_temporary_file : Text -> Text -> File + create_temporary_file prefix="temp" suffix=".tmp" = + java_file = Java_File.createTempFile prefix suffix + java_file.deleteOnExit + File.new java_file.getAbsolutePath + + ## PRIVATE + Create a dry run temporary file which will be deleted when Enso exits. + + For an absolute path the same temporary file is returned. + If this file is a temporary file that was generated by + `create_dry_run_file` on another file, it is returned as-is. + create_dry_run_file : Boolean -> File ! File_Error + create_dry_run_file self copy_original=False = + temp_path = DryRunFileManager.getTemporaryFile self.absolute.path + if temp_path.is_nothing then Error.throw (File_Error.IO_Error "Unable to create a temporary file.") else + temp = File.new temp_path + if self.exists && copy_original then + self.copy_to temp replace_existing=True + temp + ## ALIAS Current Directory Returns the current working directory (CWD) of the current program. @@ -116,7 +141,27 @@ type File file.with_output_stream [File_Access.Create, File_Access.Write] action with_output_stream : Vector File_Access -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error with_output_stream self open_options action = - Managed_Resource.bracket (self.new_output_stream open_options) (_.close) action + new_output_stream : File -> Vector File_Access -> Output_Stream ! File_Error + new_output_stream file open_options = + opts = open_options . map (_.to_java) . to_array + stream = File_Error.handle_java_exceptions file <| + file.output_stream_builtin opts + ## We re-wrap the File Not Found error to return the parent directory + instead of the file itself - because the file that is being written + may not exist and it will not be an error, it is the parent directory + that does not exist is what prevents the write operation from + succeeding. + ## Until #5792 properly fixes catch, we cannot catch + `File_Error.Not_Found` specifically, so instead we catch all + `File_Error`s and match the needed one. + stream_2 = stream.catch File_Error error-> case error of + File_Error.Not_Found file_path -> Error.throw (File_Error.Not_Found file_path.parent) + _ -> stream + resource = Managed_Resource.register stream_2 close_stream + Output_Stream.Value file resource + + if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File writing is forbidden as the Output context is disabled") else + Managed_Resource.bracket (new_output_stream self open_options) (_.close) action ## PRIVATE Creates a new output stream for this file. Recommended to use @@ -125,8 +170,8 @@ type File Arguments: - options: A vector of `File_Access` objects determining how to open the stream. These options set the access properties of the stream. - output_stream : Vector File_Access -> Output_Stream - output_stream self options = @Builtin_Method "File.output_stream" + output_stream_builtin : Vector File_Access -> Output_Stream + output_stream_builtin self options = @Builtin_Method "File.output_stream_builtin" ## PRIVATE Creates a new input stream for this file. Recommended to use @@ -196,6 +241,7 @@ type File import Standard.Examples example_xls_to_table = Examples.xls.read (Excel (Worksheet 'Dates')) + @format format_widget read : File_Format -> Problem_Behavior -> Any ! File_Error read self format=Auto_Detect (on_problems=Problem_Behavior.Report_Warning) = format.read self on_problems @@ -231,6 +277,7 @@ type File import Standard.Examples example_read = Examples.csv.read + @encoding Encoding.default_widget read_text : Encoding -> Problem_Behavior -> Text ! File_Error read_text self (encoding=Encoding.utf_8) (on_problems=Problem_Behavior.Report_Warning) = file = File.new self @@ -366,7 +413,15 @@ type File example_is_directory = (Examples.data_dir / "my_directory") . create_directory create_directory : Nothing - create_directory self = @Builtin_Method "File.create_directory" + create_directory self = + if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "Directory creation is forbidden as the Output context is disabled") else + self.create_directory_builtin + + + ## PRIVATE + Creates the directory represented by this file if it did not exist. + create_directory_builtin : Nothing + create_directory_builtin self = @Builtin_Method "File.create_directory_builtin" ## Checks whether the file exists and is a regular file. @@ -491,7 +546,8 @@ type File file.delete delete : Nothing ! File_Error delete self = - File_Error.handle_java_exceptions self self.delete_builtin + if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File deleting is forbidden as the Output context is disabled") else + File_Error.handle_java_exceptions self self.delete_builtin ## Moves the file to the specified destination. @@ -501,11 +557,12 @@ type File destination file already exists. Defaults to `False`. copy_to : File -> Boolean -> Nothing ! File_Error copy_to self destination replace_existing=False = - File_Error.handle_java_exceptions self <| case replace_existing of - True -> - copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array - self.copy_builtin destination copy_options - False -> self.copy_builtin destination Array.empty + if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File copying is forbidden as the Output context is disabled") else + File_Error.handle_java_exceptions self <| case replace_existing of + True -> + copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array + self.copy_builtin destination copy_options + False -> self.copy_builtin destination Array.empty ## Moves the file to the specified destination. @@ -515,11 +572,12 @@ type File destination file already exists. Defaults to `False`. move_to : File -> Boolean -> Nothing ! File_Error move_to self destination replace_existing=False = - File_Error.handle_java_exceptions self <| case replace_existing of - True -> - copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array - self.move_builtin destination copy_options - False -> self.move_builtin destination Array.empty + if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File moving is forbidden as the Output context is disabled") else + File_Error.handle_java_exceptions self <| case replace_existing of + True -> + copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array + self.move_builtin destination copy_options + False -> self.move_builtin destination Array.empty ## Deletes the file if it exists on disk. @@ -553,35 +611,6 @@ type File resource = Managed_Resource.register stream close_stream Input_Stream.Value self resource - ## PRIVATE - ADVANCED - Returns a new output stream for this file. - - Arguments: - - open_options: A vector of `File_Access` objects determining how to open - the stream. These options set the access properties of the stream. - - The returned stream should be closed as soon as it is not used anymore. - The `with_output_stream` method should be preferred whenever possible. - new_output_stream : Vector File_Access -> Output_Stream ! File_Error - new_output_stream self open_options = - opts = open_options . map (_.to_java) . to_array - stream = File_Error.handle_java_exceptions self <| - self.output_stream opts - ## We re-wrap the File Not Found error to return the parent directory - instead of the file itself - because the file that is being written - may not exist and it will not be an error, it is the parent directory - that does not exist is what prevents the write operation from - succeeding. - ## Until #5792 properly fixes catch, we cannot catch - `File_Error.Not_Found` specifically, so instead we catch all - `File_Error`s and match the needed one. - stream_2 = stream.catch File_Error error-> case error of - File_Error.Not_Found file_path -> Error.throw (File_Error.Not_Found file_path.parent) - _ -> stream - resource = Managed_Resource.register stream_2 close_stream - Output_Stream.Value self resource - ## PRIVATE Reads last `n` bytes from the file (or less if the file is too small) and returns a vector of bytes. @@ -711,9 +740,9 @@ type Output_Stream example_write_bytes = file = Examples.scratch_file - out_stream = file.new_output_stream [File_Access.Create, File_Access.Write] - out_stream.write_bytes "hello".utf_8 - out_stream.close + file.with_output_stream [File_Access.Create, File_Access.Write] out_stream-> + out_stream.write_bytes "hello".utf_8 + out_stream.close write_bytes : Vector File_Access -> Nothing ! File_Error write_bytes self contents = self.stream_resource . with java_stream-> File_Error.handle_java_exceptions self.file <| @@ -737,8 +766,8 @@ type Output_Stream example_write_bytes = file = Examples.scratch_file - out_stream = file.new_output_stream [File_Access.Create] - out_stream.close + file.with_output_stream [File_Access.Create] out_stream-> + out_stream.close close : Nothing close self = self.stream_resource . finalize diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso index ac3f4bd2fb54..f44213fd67a1 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso @@ -2,17 +2,21 @@ import project.Data.Text.Text import project.Data.Text.Encoding.Encoding import project.Data.Text.Extensions import project.Data.Vector.Vector -import project.Errors.Common.Unsupported_Argument_Types import project.Error.Error +import project.Errors.Common.Dry_Run_Operation +import project.Errors.Common.Unsupported_Argument_Types import project.Errors.Encoding_Error.Encoding_Error import project.Errors.File_Error.File_Error import project.Errors.Illegal_Argument.Illegal_Argument import project.Errors.Problem_Behavior.Problem_Behavior import project.Nothing.Nothing import project.Panic.Panic +import project.Runtime.Context import project.System.File.Existing_File_Behavior.Existing_File_Behavior import project.System.File.File +import project.Warning.Warning +from project.Data.Boolean import Boolean, True, False polyglot java import org.enso.base.Array_Builder @@ -37,14 +41,39 @@ polyglot java import org.enso.base.Array_Builder Otherwise, the file is created with the encoded text written to it. The method returns a `File` object for the written file. + + ? Dry Run + + If writing to Output context is not enabled (such as in "Design" mode), + then this function will write to a temporary file. This temporary file will + be automatically deleted on exit of the Enso process. + + This allows for building the workflow without affecting the real files. +@encoding Encoding.default_widget Text.write : (File|Text) -> Encoding -> Existing_File_Behavior -> Problem_Behavior -> File ! Encoding_Error | Illegal_Argument | File_Error Text.write self path encoding=Encoding.utf_8 on_existing_file=Existing_File_Behavior.Backup on_problems=Problem_Behavior.Report_Warning = bytes = self.bytes encoding on_problems - file = File.new path - r = on_existing_file.write file stream-> - bytes.if_not_error <| - stream.write_bytes bytes - r.if_not_error file + + actual = File.new path + + is_enabled = Context.Output.is_enabled + + effective_existing_behaviour = if is_enabled then on_existing_file else + case on_existing_file of + Existing_File_Behavior.Backup -> Existing_File_Behavior.Overwrite + Existing_File_Behavior.Error -> if actual.exists then Error.throw (File_Error.Already_Exists actual) else Existing_File_Behavior.Overwrite + _ -> on_existing_file + + file = if is_enabled then actual else actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append + + Context.Output.with_enabled <| + r = effective_existing_behaviour.write file stream-> + bytes.if_not_error <| + stream.write_bytes bytes + r.if_not_error <| + if is_enabled then file else + warning = Dry_Run_Operation.Warning "Only a dry run has occurred, with data written to a temporary file." + Warning.attach warning file ## Writes (or appends) the Vector of bytes into the specified file. The behavior specified in the `existing_file` parameter will be used if the file exists. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso index 5cbface4a5f6..5c70c16ed923 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso @@ -9,6 +9,7 @@ import project.Errors.File_Error.File_Error import project.Errors.Problem_Behavior.Problem_Behavior import project.Errors.Unimplemented.Unimplemented import project.Function.Function +import project.Meta import project.Network.HTTP.Response.Response import project.Network.URI.URI import project.Nothing.Nothing @@ -17,6 +18,10 @@ import project.System.File.File from project.Data.Boolean import Boolean, True, False from project.Data.Json import Invalid_JSON +from project.Metadata.Widget import Single_Choice +from project.Metadata.Choice import Option +import project.Metadata.Display + polyglot java import org.enso.base.file_format.FileFormatSPI ## PRIVATE @@ -35,6 +40,21 @@ get_format callback = @Tail_Call reader (idx + 1) reader 0 +## PRIVATE +format_widget : Single_Choice +format_widget = + all_types = [Auto_Detect] + format_types + make_ctor type_obj = + type_name = Meta.get_qualified_type_name type_obj + + ## Temporary work around to work out if need to add the constructor name + is_singleton_type = type_obj==JSON_Format || (type_name.ends_with "_Format" . not) + if is_singleton_type then type_name else + simple_name = Meta.get_simple_type_name type_obj + "(" + type_name + "." + (simple_name.replace "_Format" "") + ")" + make_name type_obj = type_obj.to_text.replace "_Format" "" . replace "_" " " + Single_Choice display=Display.Always values=(all_types.map n->(Option (make_name n) (make_ctor n))) + type Auto_Detect ## PRIVATE Implements the `File.read` for this `File_Format` @@ -127,23 +147,23 @@ type Bytes read self file _ = file.read_bytes -type JSON_File +type JSON_Format ## PRIVATE If the File_Format supports reading from the file, return a configured instance. - for_file : File -> JSON_File | Nothing + for_file : File -> JSON_Format | Nothing for_file file = case file.extension of - ".json" -> JSON_File - ".geojson" -> JSON_File + ".json" -> JSON_Format + ".geojson" -> JSON_Format _ -> Nothing ## PRIVATE If the File_Format supports reading from the web response, return a configured instance. - for_web : Text -> URI -> JSON_File | Nothing + for_web : Text -> URI -> JSON_Format | Nothing for_web content_type _ = first = content_type.split ';' . first . trim case first of - "application/json" -> JSON_File + "application/json" -> JSON_Format _ -> Nothing ## PRIVATE diff --git a/distribution/lib/Standard/Examples/0.0.0-dev/src/Main.enso b/distribution/lib/Standard/Examples/0.0.0-dev/src/Main.enso index b2447c02368f..850b7e614052 100644 --- a/distribution/lib/Standard/Examples/0.0.0-dev/src/Main.enso +++ b/distribution/lib/Standard/Examples/0.0.0-dev/src/Main.enso @@ -4,6 +4,7 @@ import Standard.Base.Data.Text.Regex.Match.Match import Standard.Base.Errors.Common.No_Such_Method import Standard.Base.Network.HTTP.Response.Response import Standard.Base.Network.HTTP.Response_Body.Response_Body +import Standard.Base.Runtime.Context from Standard.Table import Table, Column @@ -40,7 +41,7 @@ xls = url = "https://enso-data-samples.s3.us-west-1.amazonaws.com/spreadsheet.xls" file = enso_project.data / 'spreadsheet.xls' if file.exists.not then - HTTP.fetch url . to_file file + Context.Output.with_enabled <| HTTP.fetch url . to_file file file ## An example XLSX file for experimenting with Table and its APIs. @@ -55,14 +56,15 @@ xlsx = url = "https://enso-data-samples.s3.us-west-1.amazonaws.com/spreadsheet.xlsx" file = enso_project.data / 'spreadsheet.xlsx' if file.exists.not then - HTTP.fetch url . to_file file + Context.Output.with_enabled <| HTTP.fetch url . to_file file file ## A file that is used for writing temporary data as part of tests. scratch_file : File scratch_file = file = enso_project.data / "scratch_file" - if file.exists then file.delete else Nothing + if file.exists.not then Nothing else + Context.Output.with_enabled <| file.delete file ## An example duration for experimenting with duration APIs. @@ -172,7 +174,7 @@ image_file = url = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Hue_alpha_falloff.png/320px-Hue_alpha_falloff.png" file = enso_project.data / "image.png" if file.exists.not then - HTTP.fetch url . to_file file + Context.Output.with_enabled <| HTTP.fetch url . to_file file file ## A PNG image. diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table_Conversions.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table_Conversions.enso index 97769b430be9..8f8b7e67b26b 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table_Conversions.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table_Conversions.enso @@ -128,8 +128,8 @@ Text.parse_to_table self pattern="." case_sensitivity=Case_Sensitivity.Sensitive - match_columns: How to match columns between the table and the file. Not used for JSON. - on_problems: What to do if there are problems reading the file. -JSON_File.write_table : File -> Table -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> File -JSON_File.write_table self file table on_existing_file match_columns on_problems = +JSON_Format.write_table : File -> Table -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> File +JSON_Format.write_table self file table on_existing_file match_columns on_problems = _ = [match_columns, on_problems] if file.exists.not then table.to_json.write file else case on_existing_file of diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Test_Reporter.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Test_Reporter.enso index 3bc26b25ab1e..580f0e13d692 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/src/Test_Reporter.enso +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Test_Reporter.enso @@ -1,4 +1,5 @@ from Standard.Base import all +import Standard.Base.Runtime.Context import project.Suite_Config.Suite_Config import project.Test.Test @@ -18,8 +19,10 @@ wrap_junit_testsuites config builder ~action = if config.should_output_junit then builder.append '\n' - config.output_path.parent.create_directory - builder.toString.write config.output_path + + Context.Output.with_enabled <| + config.output_path.parent.create_directory + builder.toString.write config.output_path result diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java index b5d50efa8e3a..15bd5e09d427 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java @@ -11,7 +11,7 @@ @BuiltinMethod( type = "Context", - name = "is_enabled", + name = "is_enabled_builtin", description = "Check if the context is enabled in the provided execution environment.") public class ContextIsEnabledNode extends Node { private @Child ExpectStringNode expectStringNode = ExpectStringNode.build(); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java index 0841799aa5ab..3d73e1e2eb2f 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java @@ -42,7 +42,7 @@ public EnsoFile(TruffleFile truffleFile) { this.truffleFile = truffleFile; } - @Builtin.Method + @Builtin.Method(name = "output_stream_builtin") @Builtin.WrapException(from = IOException.class) @Builtin.ReturningGuestObject @CompilerDirectives.TruffleBoundary @@ -155,7 +155,7 @@ public boolean isDirectory() { return this.truffleFile.isDirectory(); } - @Builtin.Method(name = "create_directory") + @Builtin.Method(name = "create_directory_builtin") @CompilerDirectives.TruffleBoundary public void createDirectories() { try { diff --git a/std-bits/base/src/main/java/org/enso/base/DryRunFileManager.java b/std-bits/base/src/main/java/org/enso/base/DryRunFileManager.java new file mode 100644 index 000000000000..f6136568a8df --- /dev/null +++ b/std-bits/base/src/main/java/org/enso/base/DryRunFileManager.java @@ -0,0 +1,42 @@ +package org.enso.base; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class DryRunFileManager { + static final Map files = new HashMap<>(); + + /** + * Creates a temporary file for the given path. If the path is already a dry run temporary file, + * the same path will be returned. + * + * @param path the path to the file to make a temporary file of. + * @return the path to the temporary file. + */ + public static String getTemporaryFile(String path) { + return files.computeIfAbsent( + path, + k -> { + if (files.containsValue(k)) { + // Existing temporary file so return this. + return k; + } + + var filename = new File(k).getName(); + var lastDot = filename.lastIndexOf('.'); + var prefix = lastDot == -1 ? filename : filename.substring(0, lastDot); + prefix = prefix + "_ensodryrun"; + var extension = lastDot == -1 ? "" : filename.substring(lastDot); + + try { + var temp = File.createTempFile(prefix, extension); + temp.deleteOnExit(); + return temp.getAbsolutePath(); + } catch (IOException e) { + return null; + } + }); + } +} diff --git a/std-bits/base/src/main/java/org/enso/base/file_format/JSONFormatSPI.java b/std-bits/base/src/main/java/org/enso/base/file_format/JSONFormatSPI.java index 91313fb5bde9..4266b2bd42fc 100644 --- a/std-bits/base/src/main/java/org/enso/base/file_format/JSONFormatSPI.java +++ b/std-bits/base/src/main/java/org/enso/base/file_format/JSONFormatSPI.java @@ -9,6 +9,6 @@ protected String getModuleName() { @Override protected String getTypeName() { - return "JSON_File"; + return "JSON_Format"; } } diff --git a/test/Table_Tests/src/Database/SQLite_Spec.enso b/test/Table_Tests/src/Database/SQLite_Spec.enso index 241ca1f8a88a..07c47eee01be 100644 --- a/test/Table_Tests/src/Database/SQLite_Spec.enso +++ b/test/Table_Tests/src/Database/SQLite_Spec.enso @@ -1,5 +1,6 @@ from Standard.Base import all import Standard.Base.Runtime.Ref.Ref +import Standard.Base.Runtime.Context import Standard.Table.Data.Type.Value_Type.Bits from Standard.Table import Table, Value_Type @@ -154,11 +155,11 @@ sqlite_spec connection prefix = spec = enso_project.data.create_directory file = enso_project.data / "sqlite_test.db" - file.delete_if_exists + Context.Output.with_enabled <| file.delete_if_exists in_file_prefix = "[SQLite File] " sqlite_spec (Database.connect (SQLite file)) in_file_prefix Upload_Spec.spec (_ -> Database.connect (SQLite file)) in_file_prefix - file.delete + Context.Output.with_enabled <| file.delete in_memory_prefix = "[SQLite In-Memory] " sqlite_spec (Database.connect (SQLite In_Memory)) in_memory_prefix @@ -166,7 +167,7 @@ spec = SQLite_Type_Mapping_Spec.spec - Test.group "SQLite_Format should allow connecting to SQLite files" <| + Test.group "SQLite_Format should allow connecting to SQLite files" <| Context.Output.with_enabled <| file.delete_if_exists connection = Database.connect (SQLite file) diff --git a/test/Table_Tests/src/IO/Csv_Spec.enso b/test/Table_Tests/src/IO/Csv_Spec.enso index 024b3865a719..50b0392ad6e8 100644 --- a/test/Table_Tests/src/IO/Csv_Spec.enso +++ b/test/Table_Tests/src/IO/Csv_Spec.enso @@ -1,4 +1,5 @@ from Standard.Base import all +import Standard.Base.Runtime.Context from Standard.Table import Table, Column, Delimited import Standard.Table.Main as Table_Module @@ -91,7 +92,7 @@ spec = res.should_equal expected - Test.specify 'should write CSV to a file' <| + Test.specify 'should write CSV to a file' <| Context.Output.with_enabled <| varied_column = (enso_project.data / "varied_column.csv") . read out = enso_project.data / "transient" / "out.csv" out.delete_if_exists @@ -109,7 +110,7 @@ spec = out.read_text.should_equal exp out.delete_if_exists - Test.group "Integration" <| + Test.group "Integration" <| Context.Output.with_enabled <| Test.specify "should be able to round-trip a table with all kinds of weird characters to CSV and back" <| names = ['Śłąęźż");DROP TABLE Students;--', 'This;Name;;Is""Strange', 'Marcin,,', '\'', 'a\n\nb', 'a\tc', Nothing, Nothing, Nothing, '42', '💁👌🎍😍', '', 'null?\0?', 'FFFD', '\uFFFD', '\r\n', 'a\r\nb\n\rc\rd\ne', 'what about these # ?? // /* hmm */ is it included?', 'and the rare \v vertical tab?'] d = Date_Time.new 2015 10 29 23 55 49 diff --git a/test/Table_Tests/src/IO/Delimited_Read_Spec.enso b/test/Table_Tests/src/IO/Delimited_Read_Spec.enso index d5906c33664d..a51697a18805 100644 --- a/test/Table_Tests/src/IO/Delimited_Read_Spec.enso +++ b/test/Table_Tests/src/IO/Delimited_Read_Spec.enso @@ -2,6 +2,7 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument +import Standard.Base.Runtime.Context from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Delimited import Standard.Table.Data.Table_Conversions @@ -102,7 +103,7 @@ spec = r2.should_fail_with File_Error r2.catch.should_be_a File_Error.IO_Error - Test.specify "should work with all kinds of line endings" <| + Test.specify "should work with all kinds of line endings" <| Context.Output.with_enabled <| path name = enso_project.data / 'transient' / name create_file name ending_style = lines = ['a,b,c', 'd,e,f', '1,2,3'] @@ -129,7 +130,7 @@ spec = ['crlf.csv', 'lf.csv', 'cr.csv', 'mixed.csv'].each (path >> .delete) - Test.specify "should allow to override line endings style" <| + Test.specify "should allow to override line endings style" <| Context.Output.with_enabled <| file = enso_project.data / "transient" / "lf.csv" lines = ['a,b,c', 'd,e,f', '1,2,3'] text = lines.join '\n' @@ -170,7 +171,7 @@ spec = table.at '🚀b' . to_vector . should_equal ['✨🚀🚧😍😃😍😎😙😉☺'] table.at 'ć😎' . to_vector . should_equal ['แมวมีสี่ขา'] - Test.specify "should report errors when encountering malformed characters" <| + Test.specify "should report errors when encountering malformed characters" <| Context.Output.with_enabled <| utf8_file = (enso_project.data / "transient" / "utf8_invalid.csv") utf8_bytes = [97, 44, 98, 44, 99, 10, -60, -123, 44, -17, -65, -65, 44, -61, 40, -61, 40, 10] utf8_bytes.write_bytes utf8_file diff --git a/test/Table_Tests/src/IO/Delimited_Write_Spec.enso b/test/Table_Tests/src/IO/Delimited_Write_Spec.enso index 61ca23091b8c..1822c1f8b3a5 100644 --- a/test/Table_Tests/src/IO/Delimited_Write_Spec.enso +++ b/test/Table_Tests/src/IO/Delimited_Write_Spec.enso @@ -2,6 +2,7 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument +import Standard.Base.Runtime.Context from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Match_Columns, Delimited from Standard.Table.Errors import all @@ -24,7 +25,7 @@ join_lines lines trailing_newline=True = spec = line_ending_pairs = [[Line_Ending_Style.Unix, '\n'], [Line_Ending_Style.Windows, '\r\n'], [Line_Ending_Style.Mac_Legacy, '\r']] - Test.group "Delimited File Writing" <| + Test.group "Delimited File Writing" <| Context.Output.with_enabled <| Test.specify "should correctly write a simple table and return the written file object on success" <| table = Table.new [["A", [1,2,3]], ["B", [1.0,1.5,2.2]], ["C", ["x","y","z"]], ["D", ["a", 2, My_Type.Value 10]]] file = (enso_project.data / "transient" / "written.csv") diff --git a/test/Table_Tests/src/IO/Excel_Spec.enso b/test/Table_Tests/src/IO/Excel_Spec.enso index ea36ff0c278e..ac77439b0dfa 100644 --- a/test/Table_Tests/src/IO/Excel_Spec.enso +++ b/test/Table_Tests/src/IO/Excel_Spec.enso @@ -1,6 +1,7 @@ from Standard.Base import all import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument +import Standard.Base.Runtime.Context from Standard.Table import Table, Match_Columns, Excel, Excel_Range, Data_Formatter, Sheet_Names, Range_Names, Worksheet, Cell_Range, Delimited, Excel_Workbook @@ -67,7 +68,7 @@ spec_fmt header file read_method sheet_count=5 = t_3.at 'C' . to_vector . should_equal [43.2, 54] spec_write suffix test_sheet_name = - Test.group ("Write " + suffix + " Files") <| + Test.group ("Write " + suffix + " Files") <| Context.Output.with_enabled <| out = enso_project.data / ('out.' + suffix) out_bak = enso_project.data / ('out.' + suffix + '.bak') table = enso_project.data/'varied_column.csv' . read @@ -678,7 +679,7 @@ spec = r2.should_fail_with File_Error r2.catch.should_be_a File_Error.Corrupted_Format - Test.specify "should handle malformed XLS files gracefully" <| + Test.specify "should handle malformed XLS files gracefully" <| Context.Output.with_enabled <| bad_file = enso_project.data / "transient" / "malformed.xls" "not really an XLS file contents...".write bad_file on_existing_file=Existing_File_Behavior.Overwrite diff --git a/test/Table_Tests/src/IO/Formats_Spec.enso b/test/Table_Tests/src/IO/Formats_Spec.enso index af435ebc97c7..660b0380b456 100644 --- a/test/Table_Tests/src/IO/Formats_Spec.enso +++ b/test/Table_Tests/src/IO/Formats_Spec.enso @@ -1,5 +1,6 @@ from Standard.Base import all import Standard.Base.Errors.File_Error.File_Error +import Standard.Base.Runtime.Context from Standard.Table import all import Standard.Table.Errors.Invalid_JSON_Format @@ -10,7 +11,7 @@ import Standard.Test.Extensions import project.Util -spec = Test.group 'Various File Format support on Table' <| +spec = Test.group 'Various File Format support on Table' <| Context.Output.with_enabled <| t1 = Table.new [["X", [1, 2, 3]]] transient = enso_project.data / "transient" simple_empty = enso_project.data/'simple_empty.csv' . read diff --git a/test/Tests/src/System/File_Read_Spec.enso b/test/Tests/src/System/File_Read_Spec.enso index 6057e438a75d..71b7ec1f5b62 100644 --- a/test/Tests/src/System/File_Read_Spec.enso +++ b/test/Tests/src/System/File_Read_Spec.enso @@ -53,7 +53,7 @@ spec = Problems.expect_only_warning Encoding_Error <| windows_log.read (Plain_Text Encoding.ascii) - Test.group "JSON_File" <| + Test.group "JSON_Format" <| Test.specify "should be able to read a file as Json" <| f1 = enso_project.data / "sample.json" j1 = f1.read @@ -62,7 +62,7 @@ spec = j1.at "not" . should_equal Nothing f2 = enso_project.data / "sample-json.weird-extension" - j2 = f2.read JSON_File + j2 = f2.read JSON_Format j2.at 0 . at "foo" . should_equal "bar" j2.at 1 . should_equal 42 j2.at 2 . should_equal Nothing diff --git a/test/Tests/src/System/File_Spec.enso b/test/Tests/src/System/File_Spec.enso index 08a86d38eaf8..5e151ec092b0 100644 --- a/test/Tests/src/System/File_Spec.enso +++ b/test/Tests/src/System/File_Spec.enso @@ -3,6 +3,7 @@ import Standard.Base.Errors.Encoding_Error.Encoding_Error import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument import Standard.Base.Errors.Illegal_State.Illegal_State +import Standard.Base.Runtime.Context polyglot java import org.enso.base_test_helpers.FileSystemHelper @@ -18,7 +19,7 @@ spec = windows_file = enso_project.data / "windows.txt" non_existent_file = File.new "does_not_exist.txt" - Test.group "File Operations" <| + Test.group "File Operations" <| Context.Output.with_enabled <| Test.specify "should allow creating a new file" <| path = sample_file.path File.new path @@ -132,13 +133,14 @@ spec = Test.specify "should allow to read last n bytes from a file" <| file = enso_project.data / "transient" / "bytes.txt" data = [1, 0, 0, 1, 2, 100, 20] - data.write_bytes file - file.read_last_bytes 0 . should_equal [] - file.read_last_bytes 1 . should_equal [20] - file.read_last_bytes 2 . should_equal [100, 20] - file.read_last_bytes 5 . should_equal [0, 1, 2, 100, 20] - file.read_last_bytes 1000 . should_equal data - file.delete + Context.Output.with_enabled <| + data.write_bytes file + file.read_last_bytes 0 . should_equal [] + file.read_last_bytes 1 . should_equal [20] + file.read_last_bytes 2 . should_equal [100, 20] + file.read_last_bytes 5 . should_equal [0, 1, 2, 100, 20] + file.read_last_bytes 1000 . should_equal data + file.delete Test.specify "should handle exceptions when reading a non-existent file" <| file = File.new "does_not_exist.txt" @@ -203,7 +205,7 @@ spec = contents_2 = Data.read_text file contents_2.should_start_with "Cupcake ipsum dolor sit amet." - Test.group "write operations" <| + Test.group "write operations" <| Context.Output.with_enabled <| data = [32, 127, -128, 0] data_2 = [10, 15, 20, 30] diff --git a/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso b/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso index eea119f7912a..fd40c0765728 100644 --- a/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso +++ b/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso @@ -1,5 +1,6 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error +import Standard.Base.Runtime.Context polyglot java import java.nio.CharBuffer @@ -24,7 +25,7 @@ spec = f.delete f.exists.should_be_false - Test.specify "should work correctly when reading chunks of varying sizes" <| + Test.specify "should work correctly when reading chunks of varying sizes" <| Context.Output.with_enabled <| f = enso_project.data / "transient" / "varying_chunks.txt" fragment = 'Hello 😎🚀🚧!' contents = 1.up_to 1000 . map _->fragment . join '\n' diff --git a/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso b/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso index 42cee53b6e34..163a1362c878 100644 --- a/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso +++ b/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso @@ -1,6 +1,7 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error import Standard.Base.Errors.Illegal_State.Illegal_State +import Standard.Base.Runtime.Context polyglot java import org.enso.base.Encoding_Utils polyglot java import java.nio.CharBuffer @@ -9,7 +10,7 @@ from Standard.Test import Test, Test_Suite, Problems import Standard.Test.Extensions spec = - Test.group "ReportingStreamEncoder" <| + Test.group "ReportingStreamEncoder" <| Context.Output.with_enabled <| Test.specify "should allow writing a file codepoint by codepoint" <| f = enso_project.data / "transient" / "char-by-char.txt" f.delete_if_exists diff --git a/test/Visualization_Tests/src/Table_Spec.enso b/test/Visualization_Tests/src/Table_Spec.enso index ccf9b2e1878e..8b69831b4c42 100644 --- a/test/Visualization_Tests/src/Table_Spec.enso +++ b/test/Visualization_Tests/src/Table_Spec.enso @@ -1,4 +1,5 @@ from Standard.Base import all +import Standard.Base.Runtime.Context from Standard.Table import Table, Aggregate_Column, Value_Type @@ -99,7 +100,7 @@ visualization_spec connection = Visualization.prepare_visualization Value_Type.Char . should_equal (make_json Value_Type.Char) Visualization.prepare_visualization Value_Type.Unsupported_Data_Type . should_equal (make_json Value_Type.Unsupported_Data_Type) -spec = +spec = Context.Output.with_enabled <| enso_project.data.create_directory file = enso_project.data / "sqlite_test.db" file.delete_if_exists diff --git a/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso b/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso index 8120f266f04a..208f0e0dcfda 100644 --- a/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso +++ b/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso @@ -23,7 +23,12 @@ type Context if self.is_enabled environment then action else Panic.throw (Forbidden_Operation.Error self.name) is_enabled : Text -> Boolean - is_enabled self environment="design" = @Builtin_Method "Context.is_enabled" + is_enabled self environment="design" = + self.is_enabled_builtin environment + + ## PRIVATE + is_enabled_builtin : Text -> Boolean + is_enabled_builtin self environment = @Builtin_Method "Context.is_enabled_builtin" current_execution_environment : Text current_execution_environment = @Builtin_Method "Runtime.current_execution_environment"