Commit: 39987a890adf3dbd3ed88f2ec774564881294946
Author: Julian Eisel
Date:   Tue Sep 27 15:30:02 2022 +0200
Branches: blender-projects-basics
https://developer.blender.org/rB39987a890adf3dbd3ed88f2ec774564881294946

Add create, dummy load function and tests for project settings directory

===================================================================

A       source/blender/blenkernel/BKE_project_settings.hh
M       source/blender/blenkernel/CMakeLists.txt
A       source/blender/blenkernel/intern/project_settings.cc
A       source/blender/blenkernel/intern/project_settings_test.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_project_settings.hh 
b/source/blender/blenkernel/BKE_project_settings.hh
new file mode 100644
index 00000000000..536df0dd18e
--- /dev/null
+++ b/source/blender/blenkernel/BKE_project_settings.hh
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ */
+
+#pragma once
+
+#include <memory>
+
+#include "BLI_string_ref.hh"
+
+namespace blender::bke {
+
+class ProjectSettings {
+  std::string project_root_path_;
+
+ public:
+  inline static const StringRefNull SETTINGS_DIRNAME = ".blender_project";
+
+  /**
+   * Initializes a blender project by creating a .blender_project directory at 
the given \a
+   * project_root_path.
+   * \return True if the settings directory was created, or already existed. 
False on failure.
+   */
+  static auto create_settings_directory(StringRef project_root_path) -> bool;
+
+  /**
+   * Read project settings from the given \a project_path, which may be either 
a project root
+   * directory or the .blender_project directory.
+   * \return The read project settings or null in case of failure.
+   */
+  static auto load_from_disk [[nodiscard]] (StringRef project_path)
+  -> std::unique_ptr<ProjectSettings>;
+
+  explicit ProjectSettings(StringRef project_root_path);
+
+  auto project_root_path [[nodiscard]] () const -> StringRefNull;
+};
+
+}  // namespace blender::bke
diff --git a/source/blender/blenkernel/CMakeLists.txt 
b/source/blender/blenkernel/CMakeLists.txt
index 877407a644c..314f11357c5 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -254,6 +254,7 @@ set(SRC
   intern/pointcache.c
   intern/pointcloud.cc
   intern/preferences.c
+  intern/project_settings.cc
   intern/report.c
   intern/rigidbody.c
   intern/scene.cc
@@ -452,6 +453,7 @@ set(SRC
   BKE_pointcache.h
   BKE_pointcloud.h
   BKE_preferences.h
+  BKE_project_settings.hh
   BKE_report.h
   BKE_rigidbody.h
   BKE_scene.h
@@ -843,6 +845,7 @@ if(WITH_GTESTS)
     intern/lib_id_remapper_test.cc
     intern/lib_id_test.cc
     intern/lib_remap_test.cc
+    intern/project_settings_test.cc
     intern/tracking_test.cc
   )
   set(TEST_INC
diff --git a/source/blender/blenkernel/intern/project_settings.cc 
b/source/blender/blenkernel/intern/project_settings.cc
new file mode 100644
index 00000000000..8645f0e63d4
--- /dev/null
+++ b/source/blender/blenkernel/intern/project_settings.cc
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BKE_project_settings.hh"
+
+#include "BLI_fileops.h"
+
+namespace blender::bke {
+
+ProjectSettings::ProjectSettings(StringRef project_root_path)
+    : project_root_path_(project_root_path)
+{
+}
+
+bool ProjectSettings::create_settings_directory(StringRef project_root_path)
+{
+  return BLI_dir_create_recursive(std::string(project_root_path + "/" + 
SETTINGS_DIRNAME).c_str());
+}
+
+std::unique_ptr<ProjectSettings> ProjectSettings::load_from_disk(StringRef 
project_path)
+{
+  if (!BLI_exists(std::string(project_path).c_str())) {
+    return nullptr;
+  }
+
+  StringRef project_root_path = project_path;
+
+  const int64_t pos_before_trailing_slash = 
project_path.find_last_not_of("\\/");
+  const StringRef path_no_trailing_slashes = (pos_before_trailing_slash == 
StringRef::not_found) ?
+                                                 project_path :
+                                                 project_path.substr(
+                                                     0, 
pos_before_trailing_slash + 1);
+  if (path_no_trailing_slashes.endswith(SETTINGS_DIRNAME)) {
+    project_root_path = project_path.drop_suffix(SETTINGS_DIRNAME.size() + 1);
+  }
+
+  return std::make_unique<ProjectSettings>(project_root_path);
+}
+
+StringRefNull ProjectSettings::project_root_path() const
+{
+  return project_root_path_;
+}
+
+}  // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/project_settings_test.cc 
b/source/blender/blenkernel/intern/project_settings_test.cc
new file mode 100644
index 00000000000..ccd9ca26812
--- /dev/null
+++ b/source/blender/blenkernel/intern/project_settings_test.cc
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+#include "BKE_appdir.h"
+#include "BKE_project_settings.hh"
+
+#include "BLI_fileops.h"
+
+#include "testing/testing.h"
+
+namespace blender::bke::tests {
+
+class ProjectSettingsTest : public testing::Test {
+ public:
+  std::string temp_project_root_path_;
+
+  void TearDown() override
+  {
+    if (!temp_project_root_path_.empty()) {
+      BLI_delete(temp_project_root_path_.c_str(), true, true);
+      temp_project_root_path_ = "";
+    }
+  }
+
+  StringRefNull create_temp_project_path()
+  {
+    BKE_tempdir_init("");
+    const std::string tempdir = BKE_tempdir_session();
+    temp_project_root_path_ = tempdir + "test-temporary-project-root";
+
+    /** Assert would be preferable but that would only run in debug builds, 
and #ASSERT_TRUE()
+     * doesn't support printing a message. */
+    if (BLI_exists(temp_project_root_path_.c_str())) {
+      throw std::runtime_error("Can't execute test, temporary path '" + 
temp_project_root_path_ +
+                               "' already exists");
+    }
+
+    BLI_dir_create_recursive(temp_project_root_path_.c_str());
+    if (!BLI_exists(temp_project_root_path_.c_str())) {
+      throw std::runtime_error("Can't execute test, failed to create path '" +
+                               temp_project_root_path_ + "'");
+    }
+    return temp_project_root_path_;
+  }
+};
+
+TEST_F(ProjectSettingsTest, create)
+{
+  StringRefNull project_path = create_temp_project_path();
+
+  if (!ProjectSettings::create_settings_directory(project_path)) {
+    /* Not a regular test failure, this may fail if there is a permission 
issue for example. */
+    FAIL() << "Failed to create project directory in '" << project_path << "', 
check permissions";
+  }
+  std::string project_settings_dir = project_path + "/" + 
ProjectSettings::SETTINGS_DIRNAME;
+  EXPECT_TRUE(BLI_exists(project_settings_dir.c_str()))
+      << project_settings_dir + " was not created";
+}
+
+/* Load the project by pointing to the project root directory (as opposed to 
the .blender_project
+ * directory). */
+TEST_F(ProjectSettingsTest, load_project_root)
+{
+  StringRefNull project_path = create_temp_project_path();
+  ProjectSettings::create_settings_directory(project_path);
+
+  std::unique_ptr project_settings = 
ProjectSettings::load_from_disk(project_path);
+  EXPECT_NE(project_settings, nullptr);
+  EXPECT_EQ(project_settings->project_root_path(), project_path);
+}
+
+/* Load the project by pointing to the .blender_project directory (ass opposed 
to the project root
+ * directory). */
+TEST_F(ProjectSettingsTest, load_project_settings_dir)
+{
+  StringRefNull project_path = create_temp_project_path();
+  ProjectSettings::create_settings_directory(project_path);
+
+  std::unique_ptr project_settings = ProjectSettings::load_from_disk(
+      project_path + "/" + ProjectSettings::SETTINGS_DIRNAME);
+  EXPECT_NE(project_settings, nullptr);
+  EXPECT_EQ(project_settings->project_root_path(), project_path);
+}
+
+}  // namespace blender::bke::tests

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to