Skip to content

Commit dd58a37

Browse files
committed
Merge branch 'dev'
2 parents 33ff98b + 93b62ce commit dd58a37

2 files changed

Lines changed: 102 additions & 80 deletions

File tree

Makefile

Lines changed: 97 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,122 @@
1-
# =========================
2-
# Vix.cpp — CLI: Release Makefile (safe & linear)
3-
# =========================
1+
VERSION ?= v0.1.0
2+
BRANCH_DEV = dev
3+
BRANCH_MAIN = main
4+
RETRIES ?= 3
5+
SLEEP ?= 2
46

5-
VERSION ?= v0.1.0
6-
REMOTE = origin
7-
BRANCH_DEV = dev
8-
BRANCH_MAIN = main
9-
10-
.PHONY: help status guard-clean guard-gh sync ffmerge merge-or-pr changelog commit push merge tag release test
7+
.PHONY: help release commit push push_main merge tag test changelog return_dev
118

129
help:
1310
@echo "Available commands:"
14-
@echo " make status - Show divergence between $(REMOTE)/$(BRANCH_MAIN) and $(REMOTE)/$(BRANCH_DEV)"
15-
@echo " make sync - Rebase $(BRANCH_DEV) on $(REMOTE)/$(BRANCH_MAIN) and align local $(BRANCH_MAIN)"
16-
@echo " make ffmerge - Fast-forward merge $(BRANCH_DEV) -> $(BRANCH_MAIN) and push"
17-
@echo " make merge-or-pr - FF merge if possible; otherwise open a PR (requires gh)"
18-
@echo " make changelog - Update CHANGELOG.md using script"
19-
@echo " make commit - Commit local changes on $(BRANCH_DEV)"
20-
@echo " make push - Push $(BRANCH_DEV)"
21-
@echo " make tag VERSION=vX.Y.Z - Create and push annotated tag"
22-
@echo " make release VERSION=vX.Y.Z - changelog + commit + push + sync + ffmerge + tag"
23-
@echo " make test - Run tests (ctest)"
24-
25-
status:
26-
@git fetch $(REMOTE) --tags
27-
@echo "== Divergence =="
28-
@echo "* Commits on $(BRANCH_DEV) not in $(BRANCH_MAIN):"
29-
@git log --oneline $(REMOTE)/$(BRANCH_MAIN)..$(REMOTE)/$(BRANCH_DEV) || true
30-
@echo
31-
@echo "* Commits on $(BRANCH_MAIN) not in $(BRANCH_DEV):"
32-
@git log --oneline $(REMOTE)/$(BRANCH_DEV)..$(REMOTE)/$(BRANCH_MAIN) || true
33-
@echo
34-
@echo "== Heads =="
35-
@git rev-parse --short $(REMOTE)/$(BRANCH_MAIN)
36-
@git rev-parse --short $(REMOTE)/$(BRANCH_DEV)
37-
38-
guard-clean:
39-
@if [ -n "$$(git status --porcelain)" ]; then \
40-
echo "❌ Working tree not clean. Commit or stash first."; \
41-
git status --porcelain; \
42-
exit 1; \
11+
@echo " make commit - Add and commit all files (on $(BRANCH_DEV) branch)"
12+
@echo " make push - Push the $(BRANCH_DEV) branch (with retry)"
13+
@echo " make push_main - Push the $(BRANCH_MAIN) branch (with retry)"
14+
@echo " make merge - Merge $(BRANCH_DEV) into $(BRANCH_MAIN) and push"
15+
@echo " make tag VERSION=vX.Y.Z - Create and push a Git tag (default: $(VERSION), with retry)"
16+
@echo " make release VERSION=vX.Y.Z - Full release workflow"
17+
@echo " make test - Run tests"
18+
@echo " make changelog - Update CHANGELOG.md"
19+
20+
return_dev:
21+
@current=$$(git rev-parse --abbrev-ref HEAD); \
22+
if [ "$$current" != "$(BRANCH_DEV)" ]; then \
23+
echo "↩️ Returning to $(BRANCH_DEV)..."; \
24+
git checkout $(BRANCH_DEV); \
4325
fi
4426

45-
guard-gh:
46-
@command -v gh >/dev/null 2>&1 || { echo "❌ GitHub CLI (gh) not found. Install gh or use 'make ffmerge'."; exit 1; }
47-
48-
sync: ## rebase dev on origin/main; align local main with origin/main
49-
@git fetch $(REMOTE) --tags
50-
@git switch $(BRANCH_DEV)
51-
@git rebase $(REMOTE)/$(BRANCH_MAIN) || { echo "❌ Rebase failed. Resolve conflicts then 'git rebase --continue'."; exit 1; }
52-
@git push --force-with-lease $(REMOTE) $(BRANCH_DEV)
53-
@git switch $(BRANCH_MAIN)
54-
@git reset --hard $(REMOTE)/$(BRANCH_MAIN)
55-
56-
ffmerge: ## fast-forward only merge dev -> main
57-
@git switch $(BRANCH_MAIN)
58-
@git merge --ff-only $(BRANCH_DEV)
59-
@git push $(REMOTE) $(BRANCH_MAIN)
60-
61-
merge-or-pr: ## ff-only else open PR
62-
@git switch $(BRANCH_MAIN)
63-
@git merge --ff-only $(BRANCH_DEV) || ( \
64-
echo "ℹ️ FF impossible, creating PR…"; \
65-
$(MAKE) guard-gh; \
66-
gh pr create -B $(BRANCH_MAIN) -H $(BRANCH_DEV) -t "Merge $(BRANCH_DEV) into $(BRANCH_MAIN)" -b "Auto-PR from Makefile (FF not possible)"; \
67-
)
68-
69-
changelog:
70-
bash scripts/update_changelog.sh
71-
7227
commit:
73-
@git switch $(BRANCH_DEV)
28+
@git checkout $(BRANCH_DEV)
7429
@if [ -n "$$(git status --porcelain)" ]; then \
75-
echo "📝 Committing changes"; \
30+
echo "📝 Committing changes on $(BRANCH_DEV)..."; \
7631
git add .; \
7732
git commit -m "chore(release): prepare $(VERSION)"; \
7833
else \
79-
echo "✅ Nothing to commit."; \
34+
echo "✅ Nothing to commit on $(BRANCH_DEV)."; \
8035
fi
36+
@$(MAKE) return_dev
8137

8238
push:
83-
@git push $(REMOTE) $(BRANCH_DEV)
39+
@echo "⬆️ Pushing $(BRANCH_DEV) to origin (with retry, $(RETRIES)x max)..."
40+
@git checkout $(BRANCH_DEV)
41+
@n=0; \
42+
until [ $$n -ge $(RETRIES) ]; do \
43+
if git push origin $(BRANCH_DEV); then \
44+
echo "✅ Push of $(BRANCH_DEV) succeeded."; \
45+
break; \
46+
fi; \
47+
n=$$((n+1)); \
48+
echo "⚠️ Push failed. Retry $$n/$(RETRIES) in $(SLEEP)s..."; \
49+
sleep $(SLEEP); \
50+
done; \
51+
if [ $$n -ge $(RETRIES) ]; then \
52+
echo "❌ Push of $(BRANCH_DEV) failed after $(RETRIES) attempts."; \
53+
exit 1; \
54+
fi
55+
@$(MAKE) return_dev
56+
57+
push_main:
58+
@echo "⬆️ Pushing $(BRANCH_MAIN) to origin (with retry, $(RETRIES)x max)..."
59+
@git checkout $(BRANCH_MAIN)
60+
@n=0; \
61+
until [ $$n -ge $(RETRIES) ]; do \
62+
if git push origin $(BRANCH_MAIN); then \
63+
echo "✅ Push of $(BRANCH_MAIN) succeeded."; \
64+
break; \
65+
fi; \
66+
n=$$((n+1)); \
67+
echo "⚠️ Push failed. Retry $$n/$(RETRIES) in $(SLEEP)s..."; \
68+
sleep $(SLEEP); \
69+
done; \
70+
if [ $$n -ge $(RETRIES) ]; then \
71+
echo "❌ Push of $(BRANCH_MAIN) failed after $(RETRIES) attempts."; \
72+
exit 1; \
73+
fi
74+
@$(MAKE) return_dev
75+
76+
merge:
77+
@echo "🔀 Merging $(BRANCH_DEV) into $(BRANCH_MAIN)..."
78+
@git checkout $(BRANCH_MAIN)
79+
@git merge --no-ff --no-edit $(BRANCH_DEV)
80+
@$(MAKE) push_main
81+
@$(MAKE) return_dev
8482

8583
tag:
8684
@if git rev-parse $(VERSION) >/dev/null 2>&1; then \
8785
echo "❌ Tag $(VERSION) already exists."; \
8886
exit 1; \
8987
else \
90-
echo "🏷️ Creating annotated tag $(VERSION)"; \
91-
git tag -a $(VERSION) -m "Release $(VERSION)"; \
92-
git push $(REMOTE) $(VERSION); \
88+
echo "🏷️ Creating annotated tag $(VERSION)..."; \
89+
git tag -a $(VERSION) -m "Release version $(VERSION)"; \
90+
echo "⬆️ Pushing tag $(VERSION) (with retry)..."; \
91+
n=0; \
92+
until [ $$n -ge $(RETRIES) ]; do \
93+
if git push origin $(VERSION); then \
94+
echo "✅ Tag $(VERSION) pushed successfully."; \
95+
break; \
96+
fi; \
97+
n=$$((n+1)); \
98+
echo "⚠️ Push tag failed. Retry $$n/$(RETRIES) in $(SLEEP)s..."; \
99+
sleep $(SLEEP); \
100+
done; \
101+
if [ $$n -ge $(RETRIES) ]; then \
102+
echo "❌ Pushing tag $(VERSION) failed after $(RETRIES) attempts."; \
103+
exit 1; \
104+
fi; \
93105
fi
106+
@$(MAKE) return_dev
94107

95-
release: changelog commit push sync ffmerge tag
96-
@echo "✅ Release pipeline done: $(VERSION)"
108+
release:
109+
@$(MAKE) changelog
110+
@$(MAKE) commit
111+
@$(MAKE) push
112+
@$(MAKE) merge
113+
@$(MAKE) tag VERSION=$(VERSION)
114+
@$(MAKE) return_dev
97115

98116
test:
99-
@cd build && ctest --output-on-failure || true
117+
cd build && ctest --output-on-failure
118+
119+
changelog:
120+
bash scripts/update_changelog.sh
121+
@$(MAKE) return_dev
100122

include/vix/json/build.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ namespace vix::json
5252
* @brief Alias to simplify use of nlohmann::json.
5353
*/
5454
using Json = nlohmann::json;
55+
using OrderedJson = nlohmann::ordered_json;
5556

5657
// ---------------------------------------------------------------------
5758
// Internal utilities (not for direct use)
@@ -80,11 +81,10 @@ namespace vix::json
8081
*/
8182
template <class K, class V, class... Rest,
8283
std::enable_if_t<is_key_like<K>::value, int> = 0>
83-
inline void put_pairs(Json &j, K &&k, V &&v, Rest &&...rest)
84+
inline void put_pairs(OrderedJson &j, K &&k, V &&v, Rest &&...rest)
8485
{
85-
// Force key as string to avoid ambiguity
8686
const std::string key{std::string_view(std::forward<K>(k))};
87-
j.emplace(key, Json(std::forward<V>(v)));
87+
j.emplace(key, OrderedJson(std::forward<V>(v)));
8888
if constexpr (sizeof...(rest) > 0)
8989
put_pairs(j, std::forward<Rest>(rest)...);
9090
}
@@ -110,11 +110,11 @@ namespace vix::json
110110
* @endcode
111111
*/
112112
template <class... Args>
113-
inline Json o(Args &&...args)
113+
inline OrderedJson o(Args &&...args)
114114
{
115115
static_assert(sizeof...(args) % 2 == 0,
116116
"json::o requires an even number of args: (k1,v1,k2,v2,...)");
117-
Json j = Json::object();
117+
OrderedJson j = OrderedJson::object();
118118
if constexpr (sizeof...(args) > 0)
119119
detail::put_pairs(j, std::forward<Args>(args)...);
120120
return j;

0 commit comments

Comments
 (0)