This is an automated email from the ASF dual-hosted git repository.

imbajin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hugegraph-toolchain.git


The following commit(s) were added to refs/heads/master by this push:
     new 43d9447b refactor(client): add graphRequired option in 
HugeClientBuilder (#718)
43d9447b is described below

commit 43d9447b0b19646634378f71c97f94ea48bcbe16
Author: Frosty <[email protected]>
AuthorDate: Sun Apr 26 02:10:35 2026 +0800

    refactor(client): add graphRequired option in HugeClientBuilder (#718)
    
    * refactor(client): replace skipRequiredChecks bool param with chainable 
graphRequired() method
    
    - Move url/graph validation from constructor to build() for true null 
support
    - Replace boolean constructor param with fluent .graphRequired(false) chain 
method
    - Rename field to graphRequired (default true) for clearer semantics
    - Clean up HugeClient javadoc: remove redundant class/constructor comments
    
    ---------
    
    Co-authored-by: imbajin <[email protected]>
---
 .serena/project.yml                                | 125 ++++++++++++++-------
 .../org/apache/hugegraph/driver/HugeClient.java    |  11 +-
 .../apache/hugegraph/driver/HugeClientBuilder.java |  21 ++--
 .../org/apache/hugegraph/structure/auth/User.java  |   6 +-
 .../hugegraph/functional/HugeClientHttpsTest.java  |   4 +-
 .../hugegraph/unit/HugeClientBuilderTest.java      |  78 +++++++++++++
 6 files changed, 187 insertions(+), 58 deletions(-)

diff --git a/.serena/project.yml b/.serena/project.yml
index 7cea692f..edbab574 100644
--- a/.serena/project.yml
+++ b/.serena/project.yml
@@ -1,15 +1,26 @@
+
+
 # list of languages for which language servers are started; choose from:
-#   al               bash             clojure          cpp              csharp 
          csharp_omnisharp
-#   dart             elixir           elm              erlang           
fortran          go
-#   haskell          java             julia            kotlin           lua    
          markdown
-#   nix              perl             php              python           
python_jedi      r
-#   rego             ruby             ruby_solargraph  rust             scala  
          swift
-#   terraform        typescript       typescript_vts   zig
+#   al                  bash                clojure             cpp            
     csharp
+#   csharp_omnisharp    dart                elixir              elm            
     erlang
+#   fortran             fsharp              go                  groovy         
     haskell
+#   haxe                java                julia               kotlin         
     lua
+#   markdown
+#   matlab              nix                 pascal              perl           
     php
+#   php_phpactor        powershell          python              python_jedi    
     r
+#   rego                ruby                ruby_solargraph     rust           
     scala
+#   swift               terraform           toml                typescript     
     typescript_vts
+#   vue                 yaml                zig
+#   (This list may be outdated. For the current list, see values of Language 
enum here:
+#   https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
+#   For some languages, there are alternative language servers, e.g. 
csharp_omnisharp, ruby_solargraph.)
 # Note:
 #   - For C, use cpp
 #   - For JavaScript, use typescript
+#   - For Free Pascal/Lazarus, use pascal
 # Special requirements:
-#   - csharp: Requires the presence of a .sln file in the project folder.
+#   Some languages require additional setup/installations.
+#   See here for details: 
https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
 # When using multiple languages, the first language server that supports a 
given file will be used for that file.
 # The first language is the default language and the respective language 
server will be used as a fallback.
 # Note that when using the JetBrains backend, language servers are not used 
and this list is correspondingly ignored.
@@ -20,14 +31,12 @@ languages:
 # For a list of possible encodings, see 
https://docs.python.org/3.11/library/codecs.html#standard-encodings
 encoding: "utf-8"
 
-# whether to use the project's gitignore file to ignore files
-# Added on 2025-04-07
+# whether to use project's .gitignore files to ignore files
 ignore_all_files_in_gitignore: true
 
-# list of additional paths to ignore
-# same syntax as gitignore, so you can use * and **
-# Was previously called `ignored_dirs`, please update your config if you are 
using that.
-# Added (renamed) on 2025-04-07
+# list of additional paths to ignore in this project.
+# Same syntax as gitignore, so you can use * and **.
+# Note: global ignored_paths from serena_config.yml are also applied 
additively.
 ignored_paths: []
 
 # whether the project is in read-only mode
@@ -35,45 +44,48 @@ ignored_paths: []
 # Added on 2025-04-18
 read_only: false
 
-# list of tool names to exclude. We recommend not excluding any tools, see the 
readme for more details.
+# list of tool names to exclude.
+# This extends the existing exclusions (e.g. from the global configuration)
+#
 # Below is the complete list of tools for convenience.
 # To make sure you have the latest list of tools, and to view their 
descriptions, 
 # execute `uv run scripts/print_tool_overview.py`.
 #
-#  * `activate_project`: Activates a project by name.
+#  * `activate_project`: Activates a project based on the project name or path.
 #  * `check_onboarding_performed`: Checks whether project onboarding was 
already performed.
 #  * `create_text_file`: Creates/overwrites a file in the project directory.
-#  * `delete_lines`: Deletes a range of lines within a file.
-#  * `delete_memory`: Deletes a memory from Serena's project-specific memory 
store.
+#  * `delete_memory`: Delete a memory file. Should only happen if a user asks 
for it explicitly,
+#       for example by saying that the information retrieved from a memory 
file is no longer correct
+#       or no longer relevant for the project.
+#  * `edit_memory`: Replaces content matching a regular expression in a memory.
 #  * `execute_shell_command`: Executes a shell command.
-#  * `find_referencing_code_snippets`: Finds code snippets in which the symbol 
at the given location is referenced.
-#  * `find_referencing_symbols`: Finds symbols that reference the symbol at 
the given location (optionally filtered by type).
-#  * `find_symbol`: Performs a global (or local) search for symbols 
with/containing a given name/substring (optionally filtered by type).
+#  * `find_file`: Finds files in the given relative paths
+#  * `find_referencing_symbols`: Finds symbols that reference the given symbol 
using the language server backend
+#  * `find_symbol`: Performs a global (or local) search using the language 
server backend.
 #  * `get_current_config`: Prints the current configuration of the agent, 
including the active and available projects, tools, contexts, and modes.
 #  * `get_symbols_overview`: Gets an overview of the top-level symbols defined 
in a given file.
-#  * `initial_instructions`: Gets the initial instructions for the current 
project.
-#     Should only be used in settings where the system prompt cannot be set,
-#     e.g. in clients you have no control over, like Claude Desktop.
+#  * `initial_instructions`: Provides instructions Serena usage (i.e. the 
'Serena Instructions Manual')
+#       for clients that do not read the initial instructions when the MCP 
server is connected.
 #  * `insert_after_symbol`: Inserts content after the end of the definition of 
a given symbol.
-#  * `insert_at_line`: Inserts content at a given line in a file.
 #  * `insert_before_symbol`: Inserts content before the beginning of the 
definition of a given symbol.
 #  * `list_dir`: Lists files and directories in the given directory 
(optionally with recursion).
-#  * `list_memories`: Lists memories in Serena's project-specific memory store.
+#  * `list_memories`: List available memories. Any memory can be read using 
the `read_memory` tool.
 #  * `onboarding`: Performs onboarding (identifying the project structure and 
essential tasks, e.g. for testing or building).
-#  * `prepare_for_new_conversation`: Provides instructions for preparing for a 
new conversation (in order to continue with the necessary context).
 #  * `read_file`: Reads a file within the project directory.
-#  * `read_memory`: Reads the memory with the given name from Serena's 
project-specific memory store.
-#  * `remove_project`: Removes a project from the Serena configuration.
-#  * `replace_lines`: Replaces a range of lines within a file with new content.
-#  * `replace_symbol_body`: Replaces the full definition of a symbol.
-#  * `restart_language_server`: Restarts the language server, may be necessary 
when edits not through Serena happen.
+#  * `read_memory`: Read the content of a memory file. This tool should only 
be used if the information
+#       is relevant to the current task. You can infer whether the information
+#       is relevant from the memory file name.
+#       You should not read the same memory file multiple times in the same 
conversation.
+#  * `rename_memory`: Renames or moves a memory. Moving between project and 
global scope is supported
+#       (e.g., renaming "global/foo" to "bar" moves it from global to project 
scope).
+#  * `rename_symbol`: Renames a symbol throughout the codebase using language 
server refactoring capabilities.
+#       For JB, we use a separate tool.
+#  * `replace_content`: Replaces content in a file (optionally using regular 
expressions).
+#  * `replace_symbol_body`: Replaces the full definition of a symbol using the 
language server backend.
+#  * `safe_delete_symbol`:
 #  * `search_for_pattern`: Performs a search for a pattern in the project.
-#  * `summarize_changes`: Provides instructions for summarizing the changes 
made to the codebase.
-#  * `switch_modes`: Activates modes by providing a list of their names
-#  * `think_about_collected_information`: Thinking tool for pondering the 
completeness of collected information.
-#  * `think_about_task_adherence`: Thinking tool for determining whether the 
agent is still on track with the current task.
-#  * `think_about_whether_you_are_done`: Thinking tool for determining whether 
the task is truly completed.
-#  * `write_memory`: Writes a named memory (for future reference) to Serena's 
project-specific memory store.
+#  * `write_memory`: Write some information (utf-8-encoded) about this project 
that can be useful for future tasks to a memory in md format.
+#       The memory name should be meaningful.
 excluded_tools: []
 
 # initial prompt for the project. It will always be given to the LLM upon 
activating the project
@@ -82,7 +94,8 @@ initial_prompt: ""
 # the name by which the project can be referenced within Serena
 project_name: "toolchain"
 
-# list of tools to include that would otherwise be disabled (particularly 
optional tools that are disabled by default)
+# list of tools to include that would otherwise be disabled (particularly 
optional tools that are disabled by default).
+# This extends the existing inclusions (e.g. from the global configuration).
 included_optional_tools: []
 
 # list of mode names to that are always to be included in the set of active 
modes
@@ -103,3 +116,39 @@ default_modes: []
 # fixed set of tools to use as the base tool set (if non-empty), replacing 
Serena's default set of tools.
 # This cannot be combined with non-empty excluded_tools or 
included_optional_tools.
 fixed_tools: []
+
+# time budget (seconds) per tool call for the retrieval of additional symbol 
information
+# such as docstrings or parameter information.
+# This overrides the corresponding setting in the global configuration; see 
the documentation there.
+# If null or missing, use the setting from the global configuration.
+symbol_info_budget:
+
+# The language backend to use for this project.
+# If not set, the global setting from serena_config.yml is used.
+# Valid values: LSP, JetBrains
+# Note: the backend is fixed at startup. If a project with a different backend
+# is activated post-init, an error will be returned.
+language_backend:
+
+# line ending convention to use when writing source files.
+# Possible values: unset (use global setting), "lf", "crlf", or "native" 
(platform default)
+# This does not affect Serena's own files (e.g. memories and configuration 
files), which always use native line endings.
+line_ending:
+
+# list of regex patterns which, when matched, mark a memory entry as read‑only.
+# Extends the list from the global configuration, merging the two lists.
+read_only_memory_patterns: []
+
+# list of regex patterns for memories to completely ignore.
+# Matching memories will not appear in list_memories or activate_project output
+# and cannot be accessed via read_memory or write_memory.
+# To access ignored memory files, use the read_file tool on the raw file path.
+# Extends the list from the global configuration, merging the two lists.
+# Example: ["_archive/.*", "_episodes/.*"]
+ignored_memory_patterns: []
+
+# advanced configuration option allowing to configure language server-specific 
options.
+# Maps the language key to the options.
+# Have a look at the docstring of the constructors of the LS implementations 
within solidlsp (e.g., for C# or PHP) to see which options are available.
+# No documentation on options means no options are available.
+ls_specific_settings: {}
diff --git 
a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java 
b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java
index 091e38fc..c681a76a 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClient.java
@@ -32,9 +32,8 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Strings;
 
 /**
- * The HugeClient class is the main entry point for interacting with a 
HugeGraph server.
- * It provides methods for managing graphs, schemas, jobs, tasks, and other 
resources.
- * It also implements the Closeable interface, so it can be used in a 
try-with-resources statement.
+ * Main entry point for HugeGraph server operations.
+ * Use {@link #builder(String, String, String)} to create an instance.
  */
 public class HugeClient implements Closeable {
 
@@ -72,11 +71,6 @@ public class HugeClient implements Closeable {
     private WhiteIpListManager whiteIpListManager;
     private VermeerManager vermeerManager;
 
-    /**
-     * Constructs a new HugeClient using the provided builder.
-     *
-     * @param builder the HugeClientBuilder to use for configuration
-     */
     public HugeClient(HugeClientBuilder builder) {
         this.borrowedClient = false;
         this.graphSpaceName = builder.graphSpace();
@@ -111,7 +105,6 @@ public class HugeClient implements Closeable {
         }
     }
 
-    // QUESTION: add gs to method param?
     public HugeClient(HugeClient client, String graphSpace, String graph) {
         this.borrowedClient = true;
         this.client = client.client;
diff --git 
a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClientBuilder.java
 
b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClientBuilder.java
index 9b9c03b9..2b5d547b 100644
--- 
a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClientBuilder.java
+++ 
b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/HugeClientBuilder.java
@@ -50,13 +50,9 @@ public class HugeClientBuilder {
     /** Set them null by default to keep compatibility with 'timeout' */
     private Integer connectTimeout;
     private Integer readTimeout;
+    private boolean graphRequired = true;
 
     public HugeClientBuilder(String url, String graphSpace, String graph) {
-        E.checkArgument(url != null && !url.isEmpty(),
-                        "Expect a string value as the url parameter argument, 
but got: %s", url);
-        E.checkArgument(graph != null && !graph.isEmpty(),
-                        "Expect a string value as the graph name parameter 
argument, but got: %s",
-                        graph);
         this.url = url;
         this.graphSpace = graphSpace;
         this.graph = graph;
@@ -76,11 +72,22 @@ public class HugeClientBuilder {
     }
 
     public HugeClient build() {
-        E.checkArgument(this.url != null, "The url parameter can't be null");
-        E.checkArgument(this.graph != null, "The graph parameter can't be 
null");
+        if (this.graphRequired) {
+            E.checkArgument(this.url != null && !this.url.isEmpty(),
+                            "Expect a string value as the url parameter 
argument, but got: %s",
+                            this.url);
+            E.checkArgument(this.graph != null && !this.graph.isEmpty(),
+                            "Expect a string value as the graph name parameter 
argument, but got: %s",
+                            this.graph);
+        }
         return new HugeClient(this);
     }
 
+    public HugeClientBuilder graphRequired(boolean graphRequired) {
+        this.graphRequired = graphRequired;
+        return this;
+    }
+
     public HugeClientBuilder configGraphSpace(String graphSpace) {
         this.graphSpace = graphSpace;
         return this;
diff --git 
a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java 
b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java
index 3f7ba4c6..3de439ae 100644
--- 
a/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java
+++ 
b/hugegraph-client/src/main/java/org/apache/hugegraph/structure/auth/User.java
@@ -155,9 +155,11 @@ public class User extends AuthElement {
 
         // Mapping of: graphSpace -> graph -> permission -> resourceType -> 
resources
         @JsonProperty("roles")
-        private Map<String, Map<String, Map<HugePermission, Map<String, 
List<HugeResource>>>>> roles;
+        private Map<String, Map<String, Map<HugePermission, Map<String,
+                List<HugeResource>>>>> roles;
 
-        public Map<String, Map<String, Map<HugePermission, Map<String, 
List<HugeResource>>>>> roles() {
+        public Map<String, Map<String, Map<HugePermission, Map<String,
+                List<HugeResource>>>>> roles() {
             return Collections.unmodifiableMap(this.roles);
         }
 
diff --git 
a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/HugeClientHttpsTest.java
 
b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/HugeClientHttpsTest.java
index 25b11fc1..3ad10481 100644
--- 
a/hugegraph-client/src/test/java/org/apache/hugegraph/functional/HugeClientHttpsTest.java
+++ 
b/hugegraph-client/src/test/java/org/apache/hugegraph/functional/HugeClientHttpsTest.java
@@ -139,7 +139,7 @@ public class HugeClientHttpsTest extends BaseFuncTest {
                       .configSSL("", "")
                       .build();
         }, e -> {
-            Assert.assertContains("The url parameter can't be null",
+            Assert.assertContains("Expect a string value as the url parameter 
argument",
                                   e.getMessage());
         });
     }
@@ -153,7 +153,7 @@ public class HugeClientHttpsTest extends BaseFuncTest {
                       .configSSL("", "")
                       .build();
         }, e -> {
-            Assert.assertContains("The graph parameter can't be null",
+            Assert.assertContains("Expect a string value as the graph name 
parameter argument",
                                   e.getMessage());
         });
     }
diff --git 
a/hugegraph-client/src/test/java/org/apache/hugegraph/unit/HugeClientBuilderTest.java
 
b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/HugeClientBuilderTest.java
new file mode 100644
index 00000000..c1379218
--- /dev/null
+++ 
b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/HugeClientBuilderTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hugegraph.unit;
+
+import org.apache.hugegraph.driver.HugeClient;
+import org.apache.hugegraph.driver.HugeClientBuilder;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class HugeClientBuilderTest {
+
+    @Test
+    public void testConstructorAcceptsNullUrlAndGraph() {
+        HugeClientBuilder builder = new HugeClientBuilder(null, "DEFAULT", 
null);
+        Assert.assertNotNull(builder);
+    }
+
+    @Test
+    public void testGraphRequiredFalseSkipsBuildValidation() {
+        // graphRequired(false) must skip IllegalArgumentException — only 
connection-level
+        // failure is expected since no server is available in unit tests
+        try {
+            HugeClient.builder(null, "DEFAULT", 
null).graphRequired(false).build();
+            Assert.fail("Expected connection-level exception");
+        } catch (IllegalArgumentException e) {
+            Assert.fail("Should not throw IllegalArgumentException — 
validation must be skipped");
+        } catch (Exception e) {
+            // Expected: validation was skipped, failed at HTTP connection as 
intended
+        }
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildFailsWithNullUrl() {
+        HugeClient.builder(null, "DEFAULT", "hugegraph").build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildFailsWithNullGraph() {
+        HugeClient.builder("http://127.0.0.1:8080";, "DEFAULT", null).build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildFailsWithEmptyUrl() {
+        HugeClient.builder("", "DEFAULT", "hugegraph").build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildFailsWithEmptyGraph() {
+        HugeClient.builder("http://127.0.0.1:8080";, "DEFAULT", "").build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildFailsAfterConfigGraphNull() {
+        HugeClient.builder("http://127.0.0.1:8080";, "DEFAULT", "hugegraph")
+                  .configGraph(null).build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testBuildFailsAfterConfigUrlNull() {
+        HugeClient.builder("http://127.0.0.1:8080";, "DEFAULT", "hugegraph")
+                  .configUrl(null).build();
+    }
+}

Reply via email to