Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "Project.h"
8#include "HackStudio.h"
9#include <LibCore/DeprecatedFile.h>
10
11namespace HackStudio {
12
13Project::Project(DeprecatedString const& root_path)
14 : m_root_path(root_path)
15{
16 m_model = GUI::FileSystemModel::create(root_path, GUI::FileSystemModel::Mode::FilesAndDirectories);
17}
18
19OwnPtr<Project> Project::open_with_root_path(DeprecatedString const& root_path)
20{
21 if (!Core::DeprecatedFile::is_directory(root_path))
22 return {};
23 return adopt_own(*new Project(root_path));
24}
25
26template<typename Callback>
27static void traverse_model(const GUI::FileSystemModel& model, const GUI::ModelIndex& index, Callback callback)
28{
29 if (index.is_valid())
30 callback(index);
31 auto row_count = model.row_count(index);
32 if (!row_count)
33 return;
34 for (int row = 0; row < row_count; ++row) {
35 auto child_index = model.index(row, GUI::FileSystemModel::Column::Name, index);
36 traverse_model(model, child_index, callback);
37 }
38}
39
40void Project::for_each_text_file(Function<void(ProjectFile const&)> callback) const
41{
42 traverse_model(model(), {}, [&](auto& index) {
43 auto file = create_file(model().full_path(index));
44 callback(*file);
45 });
46}
47
48NonnullRefPtr<ProjectFile> Project::create_file(DeprecatedString const& path) const
49{
50 auto full_path = to_absolute_path(path);
51 return ProjectFile::construct_with_name(full_path);
52}
53
54DeprecatedString Project::to_absolute_path(DeprecatedString const& path) const
55{
56 if (LexicalPath { path }.is_absolute()) {
57 return path;
58 }
59 return LexicalPath { DeprecatedString::formatted("{}/{}", m_root_path, path) }.string();
60}
61
62bool Project::project_is_serenity() const
63{
64 // FIXME: Improve this heuristic
65 // Running "Meta/serenity.sh copy-src" installs the serenity repository at this path in the home directory
66 return m_root_path.ends_with("Source/serenity"sv);
67}
68
69NonnullOwnPtr<ProjectConfig> Project::config() const
70{
71 auto config_or_error = ProjectConfig::try_load_project_config(LexicalPath::absolute_path(m_root_path, config_file_path));
72 if (config_or_error.is_error())
73 return ProjectConfig::create_empty();
74
75 return config_or_error.release_value();
76}
77
78}