Skip to content

Commit 8e5efa5

Browse files
committed
fix(index): migrate mcpplibs index URL to mcpplibs org (#267-A)
The index repo moved from mcpp-community to the mcpplibs org; the old URL only worked via GitHub's repo redirect. Centralize the canonical/legacy URLs as constants, rewrite the URL in canonicalize_legacy_index_names (URL first, so legacy name entries still match and legacy/default entries fold in dedup), heal persisted config.toml/.xlings.json via the existing text migrations, and update the publish fork hint + docs links. canonicalize_legacy_index_names is now exported so ordering stays tested.
1 parent 9d1a046 commit 8e5efa5

8 files changed

Lines changed: 117 additions & 26 deletions

File tree

‎docs/00-getting-started.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Declare dependencies in `mcpp.toml`:
9595
```
9696

9797
`mcpp build` automatically resolves SemVer constraints against the
98-
[mcpp-index](https://github.com/mcpp-community/mcpp-index), fetches the source,
98+
[mcpp-index](https://github.com/mcpplibs/mcpp-index), fetches the source,
9999
and adds it to the build graph. For a complete example, see `02-with-deps` in
100100
[01 — Examples](01-examples.md).
101101

‎docs/04-build-from-source.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,5 @@ mcpp is in early iteration and its interfaces may change. Before submitting a PR
9393

9494
- [Community forum](https://forum.d2learn.org/category/20)
9595
- Chat group QQ: 1067245099
96-
- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — the default package index
96+
- [mcpp-index](https://github.com/mcpplibs/mcpp-index) — the default package index
9797
- [mcpplibs](https://github.com/mcpplibs) — the companion collection of modular C++ libraries

‎docs/zh/00-getting-started.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ mcpp test # 编译并运行 tests/**/*.cpp(gtest 风格)
9696
```
9797

9898
`mcpp build` 将自动从
99-
[mcpp-index](https://github.com/mcpp-community/mcpp-index) 解析 SemVer
99+
[mcpp-index](https://github.com/mcpplibs/mcpp-index) 解析 SemVer
100100
约束、拉取源码并加入编译图。完整示例参见
101101
[01 — 示例项目](01-examples.md) 中的 `02-with-deps`。
102102

‎docs/zh/04-build-from-source.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,5 @@ mcpp 处于早期迭代阶段,接口可能调整,提交 PR 前请注意:
100100

101101
- [社区论坛](https://forum.d2learn.org/category/20)
102102
- 交流群 QQ: 1067245099
103-
- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — 默认包索引
103+
- [mcpp-index](https://github.com/mcpplibs/mcpp-index) — 默认包索引
104104
- [mcpplibs](https://github.com/mcpplibs) — 配套的模块化 C++ 库集合

‎src/config.cppm‎

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ struct IndexRepo {
3838
std::string url;
3939
};
4040

41+
// Canonical mcpplibs index coordinates. The index repository moved from the
42+
// mcpp-community org to the mcpplibs org (#267) — the legacy URL only works
43+
// through GitHub's repo redirect, which breaks silently if the old name is
44+
// ever re-taken. The artifact base is the release mirror consumed by
45+
// xlings >= 0.4.68 per-repo artifact sync (#269); older xlings ignores it.
46+
inline constexpr std::string_view kMcpplibsIndexUrl =
47+
"https://github.com/mcpplibs/mcpp-index.git";
48+
inline constexpr std::string_view kMcpplibsIndexUrlLegacy =
49+
"https://github.com/mcpp-community/mcpp-index.git";
50+
inline constexpr std::string_view kMcpplibsIndexArtifact =
51+
"https://github.com/xlings-res/mcpp-index";
52+
4153
struct GlobalConfig {
4254
// Resolved paths
4355
std::filesystem::path mcppHome; // ~/.mcpp/
@@ -251,6 +263,12 @@ std::expected<GlobalConfig, ConfigError> load_or_init(
251263
// Pretty-print resolved config for `mcpp env` command.
252264
void print_env(const GlobalConfig& cfg);
253265

266+
// Normalize legacy index naming in a loaded config (exported for tests):
267+
// org migration mcpp-community/mcpp-index -> mcpplibs/mcpp-index, index name
268+
// mcpp-index -> mcpplibs, then name+url dedup. Order matters: URL first, so
269+
// old-config name entries still match and legacy/default entries fold.
270+
void canonicalize_legacy_index_names(GlobalConfig& cfg);
271+
254272
// M5.5: persist [toolchain].default to config.toml.
255273
std::expected<void, ConfigError>
256274
write_default_toolchain(const GlobalConfig& cfg, std::string_view spec);
@@ -357,7 +375,7 @@ home = ""
357375
default = "mcpplibs"
358376
359377
[index.repos."mcpplibs"]
360-
url = "https://github.com/mcpp-community/mcpp-index.git"
378+
url = "https://github.com/mcpplibs/mcpp-index.git"
361379
# xlings auto-adds xim / awesome / scode / d2x as defaults.
362380
363381
[cache]
@@ -396,25 +414,8 @@ bool write_default_xlings_json(const std::filesystem::path& path,
396414
}
397415

398416
// Migration helpers delegated to mcpp.fallback.config_migration.
399-
400-
void canonicalize_legacy_index_names(GlobalConfig& cfg) {
401-
if (cfg.defaultIndex == "mcpp-index")
402-
cfg.defaultIndex = "mcpplibs";
403-
404-
std::vector<IndexRepo> normalized;
405-
for (auto r : cfg.indexRepos) {
406-
if (r.name == "mcpp-index"
407-
&& r.url == "https://github.com/mcpp-community/mcpp-index.git") {
408-
r.name = "mcpplibs";
409-
}
410-
bool duplicate = std::any_of(normalized.begin(), normalized.end(),
411-
[&](const IndexRepo& existing) {
412-
return existing.name == r.name && existing.url == r.url;
413-
});
414-
if (!duplicate) normalized.push_back(std::move(r));
415-
}
416-
cfg.indexRepos = std::move(normalized);
417-
}
417+
// canonicalize_legacy_index_names is exported (declared above, defined after
418+
// this helper namespace) so its ordering rules stay under unit test.
418419

419420
// Xlings binary acquisition delegated to mcpp.fallback.xlings_binary.
420421

@@ -454,6 +455,29 @@ void ensure_sandbox_patchelf(const GlobalConfig& cfg, bool quiet,
454455

455456
} // namespace
456457

458+
void canonicalize_legacy_index_names(GlobalConfig& cfg) {
459+
if (cfg.defaultIndex == "mcpp-index")
460+
cfg.defaultIndex = "mcpplibs";
461+
462+
std::vector<IndexRepo> normalized;
463+
for (auto r : cfg.indexRepos) {
464+
// ① Org migration first — later steps (name match, dedup) key on the
465+
// canonical URL, so legacy entries fold instead of surviving as dupes.
466+
if (r.url == kMcpplibsIndexUrlLegacy)
467+
r.url = std::string(kMcpplibsIndexUrl);
468+
// ② Legacy index name. The URL condition keeps a user's unrelated
469+
// repo that happens to be named "mcpp-index" untouched.
470+
if (r.name == "mcpp-index" && r.url == kMcpplibsIndexUrl)
471+
r.name = "mcpplibs";
472+
bool duplicate = std::any_of(normalized.begin(), normalized.end(),
473+
[&](const IndexRepo& existing) {
474+
return existing.name == r.name && existing.url == r.url;
475+
});
476+
if (!duplicate) normalized.push_back(std::move(r));
477+
}
478+
cfg.indexRepos = std::move(normalized);
479+
}
480+
457481
std::expected<GlobalConfig, ConfigError> load_or_init(
458482
bool quiet,
459483
BootstrapProgressCallback onBootstrapProgress,
@@ -572,7 +596,7 @@ std::expected<GlobalConfig, ConfigError> load_or_init(
572596
for (auto& r : cfg.indexRepos) if (r.name == name) return;
573597
cfg.indexRepos.push_back({ std::string(name), std::string(url) });
574598
};
575-
add_default("mcpplibs", "https://github.com/mcpp-community/mcpp-index.git");
599+
add_default("mcpplibs", kMcpplibsIndexUrl);
576600
canonicalize_legacy_index_names(cfg);
577601

578602
// 5. Seed registry/.xlings.json if missing; migrate legacy cached

‎src/fallback/config_migration.cppm‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ bool migrate_config_toml_index_names(const std::filesystem::path& path) {
6262

6363
replace_all(updated, "default = \"mcpp-index\"", "default = \"mcpplibs\"");
6464
replace_all(updated, "[index.repos.\"mcpp-index\"]", "[index.repos.\"mcpplibs\"]");
65+
// Org migration (#267): the index repo moved to the mcpplibs org.
66+
replace_all(updated, "https://github.com/mcpp-community/mcpp-index.git",
67+
"https://github.com/mcpplibs/mcpp-index.git");
6568

6669
return write_text_if_changed(path, original, updated);
6770
}
@@ -76,6 +79,9 @@ bool migrate_xlings_json_index_names(const std::filesystem::path& path) {
7679

7780
replace_all(updated, "\"name\": \"mcpp-index\"", "\"name\": \"mcpplibs\"");
7881
replace_all(updated, "\"name\":\"mcpp-index\"", "\"name\":\"mcpplibs\"");
82+
// Org migration (#267): the index repo moved to the mcpplibs org.
83+
replace_all(updated, "https://github.com/mcpp-community/mcpp-index.git",
84+
"https://github.com/mcpplibs/mcpp-index.git");
7985

8086
return write_text_if_changed(path, original, updated);
8187
}

‎src/publish/pipeline.cppm‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export int publish_package(bool dry_run, bool allow_dirty) {
155155
std::println(" Attach: {}", tarball.string());
156156
std::println("");
157157
std::println(" 3. Open a PR to mcpp-index:");
158-
std::println(" Fork: https://github.com/mcpp-community/mcpp-index");
158+
std::println(" Fork: https://github.com/mcpplibs/mcpp-index");
159159
std::println(" Add: pkgs/{}/{}.lua", first, pkg.name);
160160
std::println(" (file content is in {})", xpkgPath.string());
161161
std::println("");

‎tests/unit/test_config.cpp‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import std;
77
import mcpp.config;
8+
import mcpp.fallback.config_migration;
89
import mcpp.pm.index_spec;
910

1011
namespace {
@@ -162,3 +163,63 @@ TEST(Config, ProjectLocalIndexStaleCacheIsRemoved) {
162163

163164
std::filesystem::remove_all(project);
164165
}
166+
167+
// ── #267-A/#269: index org migration + artifact adoption ────────────────────
168+
169+
namespace {
170+
171+
std::string read_all(const std::filesystem::path& p) {
172+
std::stringstream ss;
173+
ss << std::ifstream(p).rdbuf();
174+
return ss.str();
175+
}
176+
177+
} // namespace
178+
179+
TEST(ConfigIndexMigration, CanonicalizeRewritesOrgAndName) {
180+
mcpp::config::GlobalConfig cfg;
181+
cfg.defaultIndex = "mcpp-index";
182+
cfg.indexRepos.push_back({ "mcpp-index",
183+
std::string(mcpp::config::kMcpplibsIndexUrlLegacy) });
184+
mcpp::config::canonicalize_legacy_index_names(cfg);
185+
ASSERT_EQ(cfg.indexRepos.size(), 1u);
186+
EXPECT_EQ(cfg.defaultIndex, "mcpplibs");
187+
EXPECT_EQ(cfg.indexRepos[0].name, "mcpplibs");
188+
EXPECT_EQ(cfg.indexRepos[0].url, mcpp::config::kMcpplibsIndexUrl);
189+
}
190+
191+
TEST(ConfigIndexMigration, CanonicalizeFoldsLegacyAndDefaultEntries) {
192+
mcpp::config::GlobalConfig cfg;
193+
cfg.indexRepos.push_back({ "mcpplibs",
194+
std::string(mcpp::config::kMcpplibsIndexUrlLegacy) });
195+
cfg.indexRepos.push_back({ "mcpplibs",
196+
std::string(mcpp::config::kMcpplibsIndexUrl) });
197+
mcpp::config::canonicalize_legacy_index_names(cfg);
198+
EXPECT_EQ(cfg.indexRepos.size(), 1u);
199+
}
200+
201+
TEST(ConfigIndexMigration, CanonicalizeLeavesForeignReposAlone) {
202+
mcpp::config::GlobalConfig cfg;
203+
cfg.indexRepos.push_back({ "other", "https://example.com/other-index.git" });
204+
mcpp::config::canonicalize_legacy_index_names(cfg);
205+
ASSERT_EQ(cfg.indexRepos.size(), 1u);
206+
EXPECT_EQ(cfg.indexRepos[0].name, "other");
207+
EXPECT_EQ(cfg.indexRepos[0].url, "https://example.com/other-index.git");
208+
}
209+
210+
TEST(ConfigIndexMigration, MigrateConfigTomlRewritesOrgUrlIdempotently) {
211+
auto dir = make_tempdir("mcpp-migrate-toml");
212+
auto p = dir / "config.toml";
213+
{
214+
std::ofstream os(p);
215+
os << "[index]\ndefault = \"mcpplibs\"\n\n[index.repos.\"mcpplibs\"]\n"
216+
"url = \"https://github.com/mcpp-community/mcpp-index.git\"\n";
217+
}
218+
EXPECT_TRUE(mcpp::fallback::migrate_config_toml_index_names(p));
219+
auto text = read_all(p);
220+
EXPECT_NE(text.find("github.com/mcpplibs/mcpp-index.git"), std::string::npos);
221+
EXPECT_EQ(text.find("mcpp-community/mcpp-index"), std::string::npos);
222+
EXPECT_FALSE(mcpp::fallback::migrate_config_toml_index_names(p)); // idempotent
223+
EXPECT_EQ(read_all(p), text);
224+
std::filesystem::remove_all(dir);
225+
}

0 commit comments

Comments
 (0)