Browse Source

AK: Make LexicalPath::relative_path() fallible

stasoid 8 months ago
parent
commit
31bf40b659

+ 3 - 5
AK/LexicalPath.cpp

@@ -147,12 +147,10 @@ ByteString LexicalPath::absolute_path(ByteString dir_path, ByteString target)
     return LexicalPath::canonicalized_path(join(dir_path, target).string());
 }
 
-ByteString LexicalPath::relative_path(StringView a_path, StringView a_prefix)
+Optional<ByteString> LexicalPath::relative_path(StringView a_path, StringView a_prefix)
 {
-    if (!a_path.starts_with('/') || !a_prefix.starts_with('/')) {
-        // FIXME: This should probably VERIFY or return an Optional<ByteString>.
-        return ""sv;
-    }
+    if (!a_path.starts_with('/') || !a_prefix.starts_with('/'))
+        return {};
 
     if (a_path == a_prefix)
         return ".";

+ 1 - 1
AK/LexicalPath.h

@@ -46,7 +46,7 @@ public:
 
     [[nodiscard]] static ByteString canonicalized_path(ByteString);
     [[nodiscard]] static ByteString absolute_path(ByteString dir_path, ByteString target);
-    [[nodiscard]] static ByteString relative_path(StringView absolute_path, StringView absolute_prefix);
+    [[nodiscard]] static Optional<ByteString> relative_path(StringView absolute_path, StringView absolute_prefix);
 
     template<typename... S>
     [[nodiscard]] static LexicalPath join(StringView first, S&&... rest)

+ 2 - 2
AK/LexicalPathWindows.cpp

@@ -115,11 +115,11 @@ ByteString LexicalPath::absolute_path(ByteString dir_path, ByteString target)
 }
 
 // Returns relative version of abs_path (relative to abs_prefix), such that join(abs_prefix, rel_path) == abs_path.
-ByteString LexicalPath::relative_path(StringView abs_path, StringView abs_prefix)
+Optional<ByteString> LexicalPath::relative_path(StringView abs_path, StringView abs_prefix)
 {
     if (!is_absolute_path(abs_path) || !is_absolute_path(abs_prefix)
         || abs_path[0] != abs_prefix[0]) // different drives
-        return "";
+        return {};
 
     auto path = canonicalized_path(abs_path);
     auto prefix = canonicalized_path(abs_prefix);

+ 1 - 1
Ladybird/Headless/Test.cpp

@@ -390,7 +390,7 @@ ErrorOr<void> run_tests(Core::AnonymousBuffer const& theme, Gfx::IntSize window_
         outln("Found {} tests...", tests.size());
 
         for (auto const& [i, test] : enumerate(tests))
-            outln("{}/{}: {}", i + 1, tests.size(), LexicalPath::relative_path(test.input_path, app.test_root_path));
+            outln("{}/{}: {}", i + 1, tests.size(), *LexicalPath::relative_path(test.input_path, app.test_root_path));
 
         return {};
     }

+ 1 - 1
Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp

@@ -295,7 +295,7 @@ static void generate_include_for(auto& generator, auto& path)
     for (auto& search_path : g_header_search_paths) {
         if (!path.starts_with(search_path))
             continue;
-        auto relative_path = LexicalPath::relative_path(path, search_path);
+        auto relative_path = *LexicalPath::relative_path(path, search_path);
         if (relative_path.length() < path_string.length())
             path_string = relative_path;
     }

+ 2 - 2
Tests/AK/TestLexicalPath.cpp

@@ -17,8 +17,8 @@ TEST_CASE(relative_path)
     EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/"sv), "tmp/abc.txt"sv);
     EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/usr"sv), "../tmp/abc.txt"sv);
 
-    EXPECT_EQ(LexicalPath::relative_path("/tmp/foo.txt"sv, "tmp"sv), ""sv);
-    EXPECT_EQ(LexicalPath::relative_path("tmp/foo.txt"sv, "/tmp"sv), ""sv);
+    EXPECT(!LexicalPath::relative_path("/tmp/foo.txt"sv, "tmp"sv).has_value());
+    EXPECT(!LexicalPath::relative_path("tmp/foo.txt"sv, "/tmp"sv).has_value());
 
     EXPECT_EQ(LexicalPath::relative_path("/tmp/foo/bar/baz.txt"sv, "/tmp/bar/foo/"sv), "../../foo/bar/baz.txt"sv);
 }

+ 1 - 1
Tests/LibJS/test-js.cpp

@@ -186,7 +186,7 @@ TESTJS_RUN_FILE_FUNCTION(ByteString const& test_file, JS::Realm& realm, JS::Exec
     }
 
     auto test_result = test_passed ? Test::Result::Pass : Test::Result::Fail;
-    auto test_path = LexicalPath::relative_path(test_file, Test::JS::g_test_root);
+    auto test_path = *LexicalPath::relative_path(test_file, Test::JS::g_test_root);
     auto duration_ms = Test::get_time_in_ms() - start_time;
     return Test::JS::JSFileResult {
         test_path,

+ 1 - 1
Userland/Libraries/LibTest/TestRunner.h

@@ -245,7 +245,7 @@ inline void TestRunner::print_test_results_as_json() const
                 if (name == "__$$TOP_LEVEL$$__"sv)
                     name = ByteString::empty();
 
-                auto path = LexicalPath::relative_path(suite.path, m_test_root);
+                auto path = *LexicalPath::relative_path(suite.path, m_test_root);
 
                 tests.set(ByteString::formatted("{}/{}::{}", path, name, case_.name), result_name);
             }