From 4784ad66b29dc30fa27e0bd528b5cf85f5287b4b Mon Sep 17 00:00:00 2001 From: Karol Kosek Date: Sun, 18 Dec 2022 19:36:23 +0100 Subject: [PATCH] HackStudio: Port to `Core::Stream::File` :^) --- Userland/DevTools/HackStudio/Editor.cpp | 14 ++++-- .../DevTools/HackStudio/Git/GitWidget.cpp | 13 ++--- .../DevTools/HackStudio/HackStudioWidget.cpp | 33 ++++++++----- .../HackStudio/LanguageServers/FileDB.cpp | 48 ++++++++----------- .../HackStudio/LanguageServers/FileDB.h | 7 +-- .../DevTools/HackStudio/ProjectBuilder.cpp | 8 ++-- .../DevTools/HackStudio/ProjectConfig.cpp | 9 ++-- Userland/DevTools/HackStudio/ProjectFile.cpp | 6 +-- 8 files changed, 72 insertions(+), 66 deletions(-) diff --git a/Userland/DevTools/HackStudio/Editor.cpp b/Userland/DevTools/HackStudio/Editor.cpp index 3c9b012b92..1a8b8eb41b 100644 --- a/Userland/DevTools/HackStudio/Editor.cpp +++ b/Userland/DevTools/HackStudio/Editor.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -231,14 +232,19 @@ void Editor::show_documentation_tooltip_if_available(DeprecatedString const& hov } dbgln_if(EDITOR_DEBUG, "opening {}", it->value); - auto file = Core::File::construct(it->value); - if (!file->open(Core::OpenMode::ReadOnly)) { - dbgln("failed to open {}, {}", it->value, file->error_string()); + auto file_or_error = Core::Stream::File::open(it->value, Core::Stream::OpenMode::Read); + if (file_or_error.is_error()) { + dbgln("Failed to open {}, {}", it->value, file_or_error.error()); return; } - auto man_document = Markdown::Document::parse(file->read_all()); + auto buffer_or_error = file_or_error.release_value()->read_until_eof(); + if (buffer_or_error.is_error()) { + dbgln("Couldn't read file: {}", buffer_or_error.error()); + return; + } + auto man_document = Markdown::Document::parse(buffer_or_error.release_value()); if (!man_document) { dbgln("failed to parse markdown"); return; diff --git a/Userland/DevTools/HackStudio/Git/GitWidget.cpp b/Userland/DevTools/HackStudio/Git/GitWidget.cpp index 6223dee459..dd47d4227e 100644 --- a/Userland/DevTools/HackStudio/Git/GitWidget.cpp +++ b/Userland/DevTools/HackStudio/Git/GitWidget.cpp @@ -8,6 +8,7 @@ #include "../Dialogs/Git/GitCommitDialog.h" #include "GitFilesModel.h" #include +#include #include #include #include @@ -156,15 +157,9 @@ void GitWidget::set_view_diff_callback(ViewDiffCallback callback) void GitWidget::show_diff(DeprecatedString const& file_path) { if (!m_git_repo->is_tracked(file_path)) { - auto file = Core::File::construct(file_path); - if (!file->open(Core::OpenMode::ReadOnly)) { - perror("open"); - VERIFY_NOT_REACHED(); - } - - auto content = file->read_all(); - DeprecatedString content_string((char*)content.data(), content.size()); - m_view_diff_callback("", Diff::generate_only_additions(content_string)); + auto file = Core::Stream::File::open(file_path, Core::Stream::OpenMode::Read).release_value_but_fixme_should_propagate_errors(); + auto content = file->read_until_eof().release_value_but_fixme_should_propagate_errors(); + m_view_diff_callback("", Diff::generate_only_additions(content)); return; } auto const& original_content = m_git_repo->original_file_content(file_path); diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp index 2487ca351b..ca43e64bef 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp +++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -550,9 +551,9 @@ NonnullRefPtr HackStudioWidget::create_new_file_action(DeprecatedSt filepath = DeprecatedString::formatted("{}{}", filepath, filename); - auto file = Core::File::construct(filepath); - if (!file->open((Core::OpenMode)(Core::OpenMode::WriteOnly | Core::OpenMode::MustBeNew))) { - GUI::MessageBox::show(window(), DeprecatedString::formatted("Failed to create '{}'", filepath), "Error"sv, GUI::MessageBox::Type::Error); + auto file_or_error = Core::Stream::File::open(filepath, Core::Stream::OpenMode::Write | Core::Stream::OpenMode::MustBeNew); + if (file_or_error.is_error()) { + GUI::MessageBox::show_error(window(), DeprecatedString::formatted("Failed to create '{}': {}", filepath, file_or_error.error())); return; } open_file(filepath); @@ -1731,21 +1732,31 @@ NonnullRefPtr HackStudioWidget::create_open_project_configuration_a auto parent_directory = LexicalPath::dirname(Project::config_file_path); auto absolute_config_file_path = LexicalPath::absolute_path(m_project->root_path(), Project::config_file_path); - if (!Core::File::exists(absolute_config_file_path)) { + DeprecatedString formatted_error_string_holder; + auto save_configuration_or_error = [&]() -> ErrorOr { + if (Core::File::exists(absolute_config_file_path)) + return {}; + if (Core::File::exists(parent_directory) && !Core::File::is_directory(parent_directory)) { - GUI::MessageBox::show_error(window(), DeprecatedString::formatted("Cannot create the '{}' directory because there is already a file with that name", parent_directory)); - return; + formatted_error_string_holder = DeprecatedString::formatted("Cannot create directory the '{}' directory because there is already a file with that name", parent_directory); + return Error::from_string_view(formatted_error_string_holder); } - mkdir(LexicalPath::absolute_path(m_project->root_path(), parent_directory).characters(), 0755); + auto maybe_error = Core::System::mkdir(LexicalPath::absolute_path(m_project->root_path(), parent_directory), 0755); + if (maybe_error.is_error() && maybe_error.error().code() != EEXIST) + return maybe_error.error(); - auto file = Core::File::open(absolute_config_file_path, Core::OpenMode::WriteOnly); - file.value()->write( + auto file = TRY(Core::Stream::File::open(absolute_config_file_path, Core::Stream::OpenMode::Write)); + TRY(file->write_entire_buffer( "{\n" " \"build_command\": \"your build command here\",\n" " \"run_command\": \"your run command here\"\n" - "}\n"sv); - file.value()->close(); + "}\n"sv.bytes())); + return {}; + }(); + if (save_configuration_or_error.is_error()) { + GUI::MessageBox::show_error(window(), DeprecatedString::formatted("Saving configuration failed: {}.", save_configuration_or_error.error())); + return; } open_file(Project::config_file_path); diff --git a/Userland/DevTools/HackStudio/LanguageServers/FileDB.cpp b/Userland/DevTools/HackStudio/LanguageServers/FileDB.cpp index d318d01632..dad71ef73d 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/FileDB.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/FileDB.cpp @@ -8,7 +8,6 @@ #include #include -#include namespace LanguageServers { @@ -37,10 +36,12 @@ Optional FileDB::get_or_read_from_filesystem(StringView filena if (document) return document->text(); - document = create_from_filesystem(absolute_path); - if (document) - return document->text(); - return {}; + auto document_or_error = create_from_filesystem(absolute_path); + if (document_or_error.is_error()) { + dbgln("Failed to create document '{}': {}", absolute_path, document_or_error.error()); + return {}; + } + return document_or_error.value()->text(); } bool FileDB::is_open(DeprecatedString const& filename) const @@ -50,11 +51,13 @@ bool FileDB::is_open(DeprecatedString const& filename) const bool FileDB::add(DeprecatedString const& filename, int fd) { - auto document = create_from_fd(fd); - if (!document) + auto document_or_error = create_from_fd(fd); + if (document_or_error.is_error()) { + dbgln("Failed to create document: {}", document_or_error.error()); return false; + } - m_open_files.set(to_absolute_path(filename), document.release_nonnull()); + m_open_files.set(to_absolute_path(filename), document_or_error.release_value()); return true; } @@ -68,26 +71,16 @@ DeprecatedString FileDB::to_absolute_path(DeprecatedString const& filename) cons return LexicalPath { DeprecatedString::formatted("{}/{}", m_project_root, filename) }.string(); } -RefPtr FileDB::create_from_filesystem(DeprecatedString const& filename) const +ErrorOr> FileDB::create_from_filesystem(DeprecatedString const& filename) const { - auto file = Core::File::open(to_absolute_path(filename), Core::OpenMode::ReadOnly); - if (file.is_error()) { - dbgln("failed to create document for {} from filesystem", filename); - return nullptr; - } - return create_from_file(*file.value()); + auto file = TRY(Core::Stream::File::open(to_absolute_path(filename), Core::Stream::OpenMode::Read)); + return create_from_file(move(file)); } -RefPtr FileDB::create_from_fd(int fd) const +ErrorOr> FileDB::create_from_fd(int fd) const { - auto file = Core::File::construct(); - if (!file->open(fd, Core::OpenMode::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes)) { - errno = file->error(); - perror("open"); - dbgln("Failed to open project file"); - return nullptr; - } - return create_from_file(*file); + auto file = TRY(Core::Stream::File::adopt_fd(fd, Core::Stream::OpenMode::Read)); + return create_from_file(move(file)); } class DefaultDocumentClient final : public GUI::TextDocument::Client { @@ -107,12 +100,11 @@ public: }; static DefaultDocumentClient s_default_document_client; -RefPtr FileDB::create_from_file(Core::File& file) const +ErrorOr> FileDB::create_from_file(NonnullOwnPtr file) const { - auto content = file.read_all(); - StringView content_view(content); + auto content = TRY(file->read_until_eof()); auto document = GUI::TextDocument::create(&s_default_document_client); - document->set_text(content_view); + document->set_text(content); return document; } diff --git a/Userland/DevTools/HackStudio/LanguageServers/FileDB.h b/Userland/DevTools/HackStudio/LanguageServers/FileDB.h index 20b9638ac3..86cbaf4357 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/FileDB.h +++ b/Userland/DevTools/HackStudio/LanguageServers/FileDB.h @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace LanguageServers { @@ -31,9 +32,9 @@ public: bool is_open(DeprecatedString const& filename) const; private: - RefPtr create_from_filesystem(DeprecatedString const& filename) const; - RefPtr create_from_fd(int fd) const; - RefPtr create_from_file(Core::File&) const; + ErrorOr> create_from_filesystem(DeprecatedString const& filename) const; + ErrorOr> create_from_fd(int fd) const; + ErrorOr> create_from_file(NonnullOwnPtr) const; static RefPtr create_with_content(DeprecatedString const&); private: diff --git a/Userland/DevTools/HackStudio/ProjectBuilder.cpp b/Userland/DevTools/HackStudio/ProjectBuilder.cpp index 3365619819..2c63b20f19 100644 --- a/Userland/DevTools/HackStudio/ProjectBuilder.cpp +++ b/Userland/DevTools/HackStudio/ProjectBuilder.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -111,7 +112,8 @@ ErrorOr ProjectBuilder::build_serenity_component() ErrorOr ProjectBuilder::component_name(StringView cmake_file_path) { - auto content = TRY(Core::File::open(cmake_file_path, Core::OpenMode::ReadOnly))->read_all(); + auto file = TRY(Core::Stream::File::open(cmake_file_path, Core::Stream::OpenMode::Read)); + auto content = TRY(file->read_until_eof()); static Regex const component_name(R"~~~(serenity_component\([\s]*(\w+)[\s\S]*\))~~~"); RegexResult result; @@ -133,8 +135,8 @@ ErrorOr ProjectBuilder::initialize_build_directory() if (Core::File::exists(cmake_file_path)) MUST(Core::File::remove(cmake_file_path, Core::File::RecursionMode::Disallowed, false)); - auto cmake_file = TRY(Core::File::open(cmake_file_path, Core::OpenMode::WriteOnly)); - cmake_file->write(generate_cmake_file_content()); + auto cmake_file = TRY(Core::Stream::File::open(cmake_file_path, Core::Stream::OpenMode::Write)); + TRY(cmake_file->write_entire_buffer(generate_cmake_file_content().bytes())); TRY(m_terminal->run_command(DeprecatedString::formatted("cmake -S {} -DHACKSTUDIO_BUILD=ON -DHACKSTUDIO_BUILD_CMAKE_FILE={}" " -DENABLE_UNICODE_DATABASE_DOWNLOAD=OFF", diff --git a/Userland/DevTools/HackStudio/ProjectConfig.cpp b/Userland/DevTools/HackStudio/ProjectConfig.cpp index e52edc380d..c119dafb4c 100644 --- a/Userland/DevTools/HackStudio/ProjectConfig.cpp +++ b/Userland/DevTools/HackStudio/ProjectConfig.cpp @@ -6,7 +6,7 @@ #include "ProjectConfig.h" #include -#include +#include namespace HackStudio { @@ -17,11 +17,10 @@ ProjectConfig::ProjectConfig(JsonObject config) ErrorOr> ProjectConfig::try_load_project_config(DeprecatedString path) { - auto file = TRY(Core::File::open(path, Core::OpenMode::ReadOnly)); - auto file_contents = file->read_all(); - file->close(); + auto file = TRY(Core::Stream::File::open(path, Core::Stream::OpenMode::Read)); + auto file_contents = TRY(file->read_until_eof()); - auto json = TRY(JsonValue::from_string(StringView { file_contents })); + auto json = TRY(JsonValue::from_string(file_contents)); if (!json.is_object()) return Error::from_string_literal("The topmost JSON element is not an object"); diff --git a/Userland/DevTools/HackStudio/ProjectFile.cpp b/Userland/DevTools/HackStudio/ProjectFile.cpp index 5fcdb21dea..a7c5129347 100644 --- a/Userland/DevTools/HackStudio/ProjectFile.cpp +++ b/Userland/DevTools/HackStudio/ProjectFile.cpp @@ -5,7 +5,7 @@ */ #include "ProjectFile.h" -#include +#include namespace HackStudio { @@ -54,7 +54,7 @@ void ProjectFile::create_document_if_needed() const return; m_document = CodeDocument::create(m_name); - auto file_or_error = Core::File::open(m_name, Core::OpenMode::ReadOnly); + auto file_or_error = Core::Stream::File::open(m_name, Core::Stream::OpenMode::Read); if (file_or_error.is_error()) { warnln("Couldn't open '{}': {}", m_name, file_or_error.error()); // This is okay though, we'll just go with an empty document and create the file when saving. @@ -62,7 +62,7 @@ void ProjectFile::create_document_if_needed() const } auto& file = *file_or_error.value(); - m_could_render_text = m_document->set_text(file.read_all()); + m_could_render_text = m_document->set_text(file.read_until_eof().release_value_but_fixme_should_propagate_errors()); } }