jekyll-theme-zer0 0.8.1 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +308 -4
- data/README.md +58 -25
- data/_data/README.md +4 -5
- data/_includes/README.md +1 -1
- data/_includes/components/mermaid.html +98 -9
- data/_includes/content/intro.html +13 -1
- data/_includes/core/header.html +1 -1
- data/_includes/stats/README.md +14 -2
- data/_layouts/README.md +3 -3
- data/_layouts/category.html +16 -6
- data/_layouts/collection.html +8 -3
- data/_layouts/journals.html +8 -3
- data/_sass/core/_theme.scss +4 -1
- data/_sass/custom.scss +20 -12
- data/assets/images/previews/10-ai-tools-that-will-transform-your-productivity-.png +0 -0
- data/assets/images/previews/business.png +0 -0
- data/assets/images/previews/css-grid-mastery-build-any-layout-you-can-imagine.png +0 -0
- data/assets/images/previews/development.png +0 -0
- data/assets/images/previews/github-setup-deployment.png +0 -0
- data/assets/images/previews/jekyll-setup.png +0 -0
- data/assets/images/previews/machine-setup.png +0 -0
- data/assets/images/previews/published-documentation-library.png +0 -0
- data/assets/images/previews/quantum-computing-explained-from-qubits-to-quantum.png +0 -0
- data/assets/images/previews/science.png +0 -0
- data/assets/images/previews/technology.png +0 -0
- data/assets/images/previews/the-complete-guide-to-startup-funding-in-2025.png +0 -0
- data/assets/images/previews/the-remote-work-revolution-how-global-teams-are-re.png +0 -0
- data/assets/images/previews/tutorial.png +0 -0
- data/assets/images/previews/world-news.png +0 -0
- data/assets/images/previews/zer0-mistakes-news-network-building-dynamic-news-s.png +0 -0
- data/assets/images/previews/zer0-mistakes-quick-start-guide.png +0 -0
- data/assets/js/auto-hide-nav.js +79 -16
- data/scripts/bin/build +115 -0
- data/scripts/bin/release +240 -0
- data/scripts/bin/test +203 -0
- data/scripts/features/generate-preview-images +846 -0
- data/scripts/features/install-preview-generator +531 -0
- data/scripts/features/preview_generator.py +646 -0
- data/scripts/generate-preview-images.sh +38 -93
- data/scripts/lib/README.md +35 -7
- data/scripts/lib/preview_generator.py +37 -22
- data/scripts/test/integration/auto-version +243 -0
- data/scripts/test/integration/mermaid +252 -0
- data/scripts/test/lib/run_tests.sh +151 -0
- data/scripts/test/lib/test_changelog.sh +90 -0
- data/scripts/test/lib/test_gem.sh +71 -0
- data/scripts/test/lib/test_git.sh +85 -0
- data/scripts/test/lib/test_validation.sh +75 -0
- data/scripts/test/lib/test_version.sh +101 -0
- data/scripts/test/theme/validate +120 -0
- data/scripts/test-mermaid.sh +51 -11
- data/scripts/utils/analyze-commits +300 -0
- data/scripts/utils/fix-markdown +251 -0
- data/scripts/utils/setup +137 -0
- data/scripts/version.sh +26 -0
- metadata +37 -8
- data/scripts/build.sh +0 -33
- data/scripts/build.sh.legacy +0 -174
- data/scripts/gem-publish.sh +0 -42
- data/scripts/gem-publish.sh.legacy +0 -700
- data/scripts/release.sh +0 -33
- data/scripts/release.sh.legacy +0 -342
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Commit Analysis Script for Automated Version Bumping
|
|
4
|
+
# Analyzes git commits to determine appropriate semantic version bump
|
|
5
|
+
# Usage: ./scripts/utils/analyze-commits [commit-range]
|
|
6
|
+
# Output: patch|minor|major|none
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Get script and library directories
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
LIB_DIR="$SCRIPT_DIR/../lib"
|
|
13
|
+
|
|
14
|
+
# Source common library for logging and utilities
|
|
15
|
+
source "$LIB_DIR/common.sh"
|
|
16
|
+
|
|
17
|
+
# Default values
|
|
18
|
+
COMMIT_RANGE="${1:-HEAD~1..HEAD}"
|
|
19
|
+
DEBUG=${DEBUG:-false}
|
|
20
|
+
|
|
21
|
+
# Override debug function to use DEBUG flag
|
|
22
|
+
log_debug() {
|
|
23
|
+
if [[ "$DEBUG" == "true" ]]; then
|
|
24
|
+
debug "$1"
|
|
25
|
+
fi
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Function to analyze individual commit
|
|
29
|
+
analyze_commit() {
|
|
30
|
+
local commit_hash="$1"
|
|
31
|
+
local commit_message
|
|
32
|
+
local commit_files
|
|
33
|
+
local bump_level="none"
|
|
34
|
+
|
|
35
|
+
commit_message=$(git log --format="%s%n%b" -n 1 "$commit_hash")
|
|
36
|
+
commit_files=$(git diff-tree --no-commit-id --name-only -r "$commit_hash" 2>/dev/null || echo "")
|
|
37
|
+
|
|
38
|
+
log_debug "Analyzing commit: $commit_hash"
|
|
39
|
+
log_debug "Message: $(echo "$commit_message" | head -1)"
|
|
40
|
+
|
|
41
|
+
# Check for breaking changes (MAJOR)
|
|
42
|
+
if echo "$commit_message" | grep -qi "BREAKING CHANGE\|breaking:"; then
|
|
43
|
+
echo "major"
|
|
44
|
+
return 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Check for major version indicators in commit message
|
|
48
|
+
if echo "$commit_message" | grep -qE "^(major|MAJOR|breaking|BREAKING)[\s:]"; then
|
|
49
|
+
echo "major"
|
|
50
|
+
return 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Check commit message patterns for conventional commits
|
|
54
|
+
local subject_line=$(echo "$commit_message" | head -1)
|
|
55
|
+
|
|
56
|
+
# MAJOR changes
|
|
57
|
+
if echo "$subject_line" | grep -qE "^(revert|remove|delete)[\s:].*[Bb]reaking"; then
|
|
58
|
+
echo "major"
|
|
59
|
+
return 0
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# MINOR changes (new features)
|
|
63
|
+
if echo "$subject_line" | grep -qE "^(feat|feature|add|new)[\s:]"; then
|
|
64
|
+
echo "minor"
|
|
65
|
+
return 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# MINOR changes - significant additions
|
|
69
|
+
if echo "$subject_line" | grep -qE "^(enhance|improve|update)[\s:].*[Ff]eature"; then
|
|
70
|
+
echo "minor"
|
|
71
|
+
return 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# PATCH changes (bug fixes, small improvements)
|
|
75
|
+
if echo "$subject_line" | grep -qE "^(fix|bug|patch|hotfix|chore|docs|style|refactor|test|perf)[\s:]"; then
|
|
76
|
+
echo "patch"
|
|
77
|
+
return 0
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# PATCH changes - maintenance and small improvements
|
|
81
|
+
if echo "$subject_line" | grep -qE "^(update|improve|enhance|optimize|clean)[\s:]"; then
|
|
82
|
+
echo "patch"
|
|
83
|
+
return 0
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# File-based analysis for changes without conventional commit messages
|
|
87
|
+
if [[ -n "$commit_files" ]]; then
|
|
88
|
+
local critical_files=0
|
|
89
|
+
local feature_files=0
|
|
90
|
+
local patch_files=0
|
|
91
|
+
|
|
92
|
+
while IFS= read -r file; do
|
|
93
|
+
[[ -z "$file" ]] && continue
|
|
94
|
+
|
|
95
|
+
log_debug "Analyzing file: $file"
|
|
96
|
+
|
|
97
|
+
# Critical/breaking change files (MAJOR)
|
|
98
|
+
if echo "$file" | grep -qE "(Gemfile|gemspec|_config\.yml|docker-compose\.yml|Dockerfile)$"; then
|
|
99
|
+
((critical_files++))
|
|
100
|
+
log_debug "Critical file detected: $file"
|
|
101
|
+
|
|
102
|
+
# Feature files (MINOR)
|
|
103
|
+
elif echo "$file" | grep -qE "(_layouts/|_includes/|assets/|pages/.*\.md$|\.rb$|\.js$)"; then
|
|
104
|
+
((feature_files++))
|
|
105
|
+
log_debug "Feature file detected: $file"
|
|
106
|
+
|
|
107
|
+
# Documentation and minor files (PATCH)
|
|
108
|
+
elif echo "$file" | grep -qE "(README|CHANGELOG|\.md$|\.txt$|\.yml$|\.yaml$|test/)"; then
|
|
109
|
+
((patch_files++))
|
|
110
|
+
log_debug "Patch file detected: $file"
|
|
111
|
+
fi
|
|
112
|
+
done <<< "$commit_files"
|
|
113
|
+
|
|
114
|
+
# Determine bump level based on file analysis
|
|
115
|
+
if [[ $critical_files -gt 0 ]]; then
|
|
116
|
+
# But only if there are significant changes to critical files
|
|
117
|
+
local lines_changed=$(git diff --shortstat "$commit_hash^" "$commit_hash" 2>/dev/null | grep -oE '[0-9]+ insertion|[0-9]+ deletion' | grep -oE '[0-9]+' | paste -sd+ | bc 2>/dev/null || echo "0")
|
|
118
|
+
if [[ $lines_changed -gt 10 ]]; then
|
|
119
|
+
echo "minor" # Significant changes to critical files = minor
|
|
120
|
+
return 0
|
|
121
|
+
else
|
|
122
|
+
echo "patch" # Small changes to critical files = patch
|
|
123
|
+
return 0
|
|
124
|
+
fi
|
|
125
|
+
elif [[ $feature_files -gt 0 ]]; then
|
|
126
|
+
echo "patch" # Changes to feature files without explicit feat: = patch
|
|
127
|
+
return 0
|
|
128
|
+
elif [[ $patch_files -gt 0 ]]; then
|
|
129
|
+
echo "patch"
|
|
130
|
+
return 0
|
|
131
|
+
fi
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
# If we reach here, no clear classification - default to patch for any real changes
|
|
135
|
+
if [[ -n "$commit_files" ]]; then
|
|
136
|
+
echo "patch"
|
|
137
|
+
else
|
|
138
|
+
echo "none"
|
|
139
|
+
fi
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# Function to determine highest bump level from multiple commits
|
|
143
|
+
determine_overall_bump() {
|
|
144
|
+
local commits=("$@")
|
|
145
|
+
local highest_bump="none"
|
|
146
|
+
local patch_count=0
|
|
147
|
+
local minor_count=0
|
|
148
|
+
local major_count=0
|
|
149
|
+
|
|
150
|
+
log_info "Analyzing ${#commits[@]} commits for version bump determination"
|
|
151
|
+
|
|
152
|
+
for commit in "${commits[@]}"; do
|
|
153
|
+
local bump_level
|
|
154
|
+
bump_level=$(analyze_commit "$commit")
|
|
155
|
+
|
|
156
|
+
log_debug "Commit $commit: $bump_level"
|
|
157
|
+
|
|
158
|
+
case "$bump_level" in
|
|
159
|
+
"major")
|
|
160
|
+
((major_count++))
|
|
161
|
+
highest_bump="major"
|
|
162
|
+
;;
|
|
163
|
+
"minor")
|
|
164
|
+
((minor_count++))
|
|
165
|
+
if [[ "$highest_bump" != "major" ]]; then
|
|
166
|
+
highest_bump="minor"
|
|
167
|
+
fi
|
|
168
|
+
;;
|
|
169
|
+
"patch")
|
|
170
|
+
((patch_count++))
|
|
171
|
+
if [[ "$highest_bump" == "none" ]]; then
|
|
172
|
+
highest_bump="patch"
|
|
173
|
+
fi
|
|
174
|
+
;;
|
|
175
|
+
esac
|
|
176
|
+
done
|
|
177
|
+
|
|
178
|
+
log_info "Bump analysis summary:"
|
|
179
|
+
log_info " - Major changes: $major_count"
|
|
180
|
+
log_info " - Minor changes: $minor_count"
|
|
181
|
+
log_info " - Patch changes: $patch_count"
|
|
182
|
+
log_info " - Overall recommendation: $highest_bump"
|
|
183
|
+
|
|
184
|
+
echo "$highest_bump"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# Main execution
|
|
188
|
+
main() {
|
|
189
|
+
local commit_range="$COMMIT_RANGE"
|
|
190
|
+
|
|
191
|
+
log_info "Analyzing commits in range: $commit_range"
|
|
192
|
+
|
|
193
|
+
# Validate git repository
|
|
194
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
195
|
+
log_error "Not in a git repository"
|
|
196
|
+
exit 1
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Get list of commits in range
|
|
200
|
+
local commits
|
|
201
|
+
if ! commits=($(git rev-list --reverse "$commit_range" 2>/dev/null)); then
|
|
202
|
+
log_warning "No commits found in range: $commit_range"
|
|
203
|
+
echo "none"
|
|
204
|
+
exit 0
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
if [[ ${#commits[@]} -eq 0 ]]; then
|
|
208
|
+
log_warning "No commits to analyze"
|
|
209
|
+
echo "none"
|
|
210
|
+
exit 0
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# Filter out merge commits and automated commits
|
|
214
|
+
local filtered_commits=()
|
|
215
|
+
for commit in "${commits[@]}"; do
|
|
216
|
+
local commit_subject
|
|
217
|
+
commit_subject=$(git log --format="%s" -n 1 "$commit")
|
|
218
|
+
|
|
219
|
+
# Skip merge commits
|
|
220
|
+
if echo "$commit_subject" | grep -qE "^Merge (branch|pull request|remote-tracking branch)"; then
|
|
221
|
+
log_debug "Skipping merge commit: $commit"
|
|
222
|
+
continue
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
# Skip automated commits (version bumps, changelog updates)
|
|
226
|
+
if echo "$commit_subject" | grep -qE "^(chore: bump version|chore: update changelog|Automated|Auto-update)"; then
|
|
227
|
+
log_debug "Skipping automated commit: $commit"
|
|
228
|
+
continue
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# Skip commits that only modify ignored files
|
|
232
|
+
local commit_files
|
|
233
|
+
commit_files=$(git diff-tree --no-commit-id --name-only -r "$commit" 2>/dev/null || echo "")
|
|
234
|
+
|
|
235
|
+
local has_significant_files=false
|
|
236
|
+
while IFS= read -r file; do
|
|
237
|
+
[[ -z "$file" ]] && continue
|
|
238
|
+
|
|
239
|
+
# Skip if only changelog, version files, or workflow files changed
|
|
240
|
+
if ! echo "$file" | grep -qE "^(CHANGELOG\.md|lib/.*version\.rb|package\.json|\.github/workflows/)$"; then
|
|
241
|
+
has_significant_files=true
|
|
242
|
+
break
|
|
243
|
+
fi
|
|
244
|
+
done <<< "$commit_files"
|
|
245
|
+
|
|
246
|
+
if [[ "$has_significant_files" == "true" ]]; then
|
|
247
|
+
filtered_commits+=("$commit")
|
|
248
|
+
else
|
|
249
|
+
log_debug "Skipping commit with only version/changelog files: $commit"
|
|
250
|
+
fi
|
|
251
|
+
done
|
|
252
|
+
|
|
253
|
+
if [[ ${#filtered_commits[@]} -eq 0 ]]; then
|
|
254
|
+
log_info "No significant commits found after filtering"
|
|
255
|
+
echo "none"
|
|
256
|
+
exit 0
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
log_info "Analyzing ${#filtered_commits[@]} significant commits (filtered from ${#commits[@]} total)"
|
|
260
|
+
|
|
261
|
+
# Determine the appropriate version bump
|
|
262
|
+
determine_overall_bump "${filtered_commits[@]}"
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
# Show usage if requested
|
|
266
|
+
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
|
|
267
|
+
cat << EOF
|
|
268
|
+
Commit Analysis Script for Automated Version Bumping
|
|
269
|
+
|
|
270
|
+
USAGE:
|
|
271
|
+
$0 [commit-range]
|
|
272
|
+
|
|
273
|
+
ARGUMENTS:
|
|
274
|
+
commit-range Git commit range to analyze (default: HEAD~1..HEAD)
|
|
275
|
+
|
|
276
|
+
OUTPUT:
|
|
277
|
+
patch Bug fixes, documentation, small improvements
|
|
278
|
+
minor New features, enhancements
|
|
279
|
+
major Breaking changes, major refactors
|
|
280
|
+
none No version bump needed
|
|
281
|
+
|
|
282
|
+
EXAMPLES:
|
|
283
|
+
$0 # Analyze last commit
|
|
284
|
+
$0 HEAD~5..HEAD # Analyze last 5 commits
|
|
285
|
+
$0 v1.0.0..HEAD # Analyze since last tag
|
|
286
|
+
|
|
287
|
+
ENVIRONMENT:
|
|
288
|
+
DEBUG=true # Enable debug output
|
|
289
|
+
|
|
290
|
+
CONVENTIONAL COMMIT PATTERNS:
|
|
291
|
+
feat:, feature:, add: → minor
|
|
292
|
+
fix:, bug:, patch: → patch
|
|
293
|
+
BREAKING CHANGE, breaking: → major
|
|
294
|
+
chore:, docs:, style: → patch
|
|
295
|
+
EOF
|
|
296
|
+
exit 0
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
# Execute main function
|
|
300
|
+
main "$@"
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Markdown Formatting Fix Script
|
|
5
|
+
# Addresses common markdown linting violations across the repository
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Get script and library directories
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
LIB_DIR="$SCRIPT_DIR/../lib"
|
|
13
|
+
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
14
|
+
|
|
15
|
+
# Source common library for logging and utilities
|
|
16
|
+
source "$LIB_DIR/common.sh"
|
|
17
|
+
|
|
18
|
+
# Aliases for backward compatibility with logging function names
|
|
19
|
+
log_info() { info "$@"; }
|
|
20
|
+
log_success() { success "$@"; }
|
|
21
|
+
log_warning() { warn "$@"; }
|
|
22
|
+
log_error() { error "$@"; }
|
|
23
|
+
|
|
24
|
+
# Function to fix common markdown issues
|
|
25
|
+
fix_markdown_file() {
|
|
26
|
+
local file="$1"
|
|
27
|
+
local temp_file="${file}.tmp"
|
|
28
|
+
|
|
29
|
+
info "Fixing markdown formatting in: $file"
|
|
30
|
+
|
|
31
|
+
# Create backup
|
|
32
|
+
cp "$file" "${file}.backup"
|
|
33
|
+
|
|
34
|
+
# Apply fixes using sed (macOS compatible)
|
|
35
|
+
sed -e 's/[[:space:]]*$//' \
|
|
36
|
+
-e '/^#/a\
|
|
37
|
+
' \
|
|
38
|
+
-e '/^##/a\
|
|
39
|
+
' \
|
|
40
|
+
-e '/^###/a\
|
|
41
|
+
' \
|
|
42
|
+
-e '/^####/a\
|
|
43
|
+
' \
|
|
44
|
+
-e '/^#####/a\
|
|
45
|
+
' \
|
|
46
|
+
-e '/^######/a\
|
|
47
|
+
' \
|
|
48
|
+
-e '/^- /i\
|
|
49
|
+
' \
|
|
50
|
+
-e '/^* /i\
|
|
51
|
+
' \
|
|
52
|
+
-e '/^+ /i\
|
|
53
|
+
' \
|
|
54
|
+
-e '/^[0-9]/i\
|
|
55
|
+
' \
|
|
56
|
+
-e 's/```$/```bash/' \
|
|
57
|
+
-e 's/^```[[:space:]]*$/```bash/' \
|
|
58
|
+
"$file" > "$temp_file"
|
|
59
|
+
|
|
60
|
+
# Additional fixes with awk for more complex patterns
|
|
61
|
+
awk '
|
|
62
|
+
BEGIN { prev_was_heading = 0; prev_was_list = 0 }
|
|
63
|
+
|
|
64
|
+
# Handle headings - ensure blank line before and after
|
|
65
|
+
/^#/ {
|
|
66
|
+
if (NR > 1 && prev_line != "" && !prev_was_heading) print ""
|
|
67
|
+
print $0
|
|
68
|
+
prev_was_heading = 1
|
|
69
|
+
prev_was_list = 0
|
|
70
|
+
prev_line = $0
|
|
71
|
+
next
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Handle list items - ensure blank line before first item
|
|
75
|
+
/^[[:space:]]*[-*+]/ || /^[[:space:]]*[0-9]+\./ {
|
|
76
|
+
if (!prev_was_list && prev_line != "" && !prev_was_heading) print ""
|
|
77
|
+
print $0
|
|
78
|
+
prev_was_list = 1
|
|
79
|
+
prev_was_heading = 0
|
|
80
|
+
prev_line = $0
|
|
81
|
+
next
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# Handle code blocks - ensure they have language specification
|
|
85
|
+
/^```[[:space:]]*$/ {
|
|
86
|
+
print "```bash"
|
|
87
|
+
prev_was_heading = 0
|
|
88
|
+
prev_was_list = 0
|
|
89
|
+
prev_line = $0
|
|
90
|
+
next
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Regular lines
|
|
94
|
+
{
|
|
95
|
+
print $0
|
|
96
|
+
prev_was_heading = 0
|
|
97
|
+
prev_was_list = 0
|
|
98
|
+
prev_line = $0
|
|
99
|
+
}
|
|
100
|
+
' "$temp_file" > "$file"
|
|
101
|
+
|
|
102
|
+
# Clean up
|
|
103
|
+
rm "$temp_file"
|
|
104
|
+
|
|
105
|
+
log_success "Fixed formatting in: $file"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Function to remove trailing whitespace
|
|
109
|
+
remove_trailing_whitespace() {
|
|
110
|
+
local file="$1"
|
|
111
|
+
log_info "Removing trailing whitespace from: $file"
|
|
112
|
+
|
|
113
|
+
# Remove trailing whitespace
|
|
114
|
+
sed -i '' 's/[[:space:]]*$//' "$file"
|
|
115
|
+
|
|
116
|
+
log_success "Removed trailing whitespace from: $file"
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Function to fix heading punctuation
|
|
120
|
+
fix_heading_punctuation() {
|
|
121
|
+
local file="$1"
|
|
122
|
+
log_info "Fixing heading punctuation in: $file"
|
|
123
|
+
|
|
124
|
+
# Remove trailing punctuation from headings
|
|
125
|
+
sed -i '' 's/^\(#\+[[:space:]]*.*\)[.!?:;,]*[[:space:]]*$/\1/' "$file"
|
|
126
|
+
|
|
127
|
+
log_success "Fixed heading punctuation in: $file"
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
# Function to fix emphasis formatting
|
|
131
|
+
fix_emphasis_formatting() {
|
|
132
|
+
local file="$1"
|
|
133
|
+
log_info "Fixing emphasis formatting in: $file"
|
|
134
|
+
|
|
135
|
+
# Fix common emphasis issues
|
|
136
|
+
sed -i '' \
|
|
137
|
+
-e 's/\*\*\([^*]*\) \*\*/\*\*\1\*\*/g' \
|
|
138
|
+
-e 's/\*\([^*]*\) \*/\*\1\*/g' \
|
|
139
|
+
"$file"
|
|
140
|
+
|
|
141
|
+
log_success "Fixed emphasis formatting in: $file"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# Main execution function
|
|
145
|
+
main() {
|
|
146
|
+
log_info "Starting markdown formatting fixes..."
|
|
147
|
+
|
|
148
|
+
# Find all markdown files
|
|
149
|
+
local md_files
|
|
150
|
+
mapfile -t md_files < <(find "$PROJECT_ROOT" -name "*.md" \
|
|
151
|
+
-not -path "*/node_modules/*" \
|
|
152
|
+
-not -path "*/.git/*" \
|
|
153
|
+
-not -path "*/vendor/*" \
|
|
154
|
+
-not -path "*/_site/*")
|
|
155
|
+
|
|
156
|
+
if [ ${#md_files[@]} -eq 0 ]; then
|
|
157
|
+
log_warning "No markdown files found"
|
|
158
|
+
return 0
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
log_info "Found ${#md_files[@]} markdown files to process"
|
|
162
|
+
|
|
163
|
+
# Process each file
|
|
164
|
+
for file in "${md_files[@]}"; do
|
|
165
|
+
if [ -f "$file" ]; then
|
|
166
|
+
remove_trailing_whitespace "$file"
|
|
167
|
+
fix_heading_punctuation "$file"
|
|
168
|
+
fix_emphasis_formatting "$file"
|
|
169
|
+
fix_markdown_file "$file"
|
|
170
|
+
fi
|
|
171
|
+
done
|
|
172
|
+
|
|
173
|
+
log_success "Completed markdown formatting fixes for ${#md_files[@]} files"
|
|
174
|
+
|
|
175
|
+
# Provide summary
|
|
176
|
+
echo
|
|
177
|
+
log_info "Summary of fixes applied:"
|
|
178
|
+
echo " ✓ Removed trailing whitespace"
|
|
179
|
+
echo " ✓ Added blank lines around headings"
|
|
180
|
+
echo " ✓ Added blank lines before list items"
|
|
181
|
+
echo " ✓ Fixed code block language specifications"
|
|
182
|
+
echo " ✓ Fixed heading punctuation"
|
|
183
|
+
echo " ✓ Fixed emphasis formatting"
|
|
184
|
+
echo
|
|
185
|
+
log_info "Backup files created with .backup extension"
|
|
186
|
+
log_info "Run 'git diff' to review changes before committing"
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# Help function
|
|
190
|
+
show_help() {
|
|
191
|
+
cat << EOF
|
|
192
|
+
Markdown Formatting Fix Script
|
|
193
|
+
|
|
194
|
+
USAGE:
|
|
195
|
+
$0 [OPTIONS]
|
|
196
|
+
|
|
197
|
+
OPTIONS:
|
|
198
|
+
-h, --help Show this help message
|
|
199
|
+
--dry-run Show what would be fixed without making changes
|
|
200
|
+
--file FILE Fix only the specified file
|
|
201
|
+
|
|
202
|
+
EXAMPLES:
|
|
203
|
+
$0 # Fix all markdown files
|
|
204
|
+
$0 --file README.md # Fix only README.md
|
|
205
|
+
$0 --dry-run # Preview changes without applying
|
|
206
|
+
|
|
207
|
+
This script fixes common markdown linting violations:
|
|
208
|
+
- Trailing whitespace
|
|
209
|
+
- Missing blank lines around headings
|
|
210
|
+
- Missing blank lines before lists
|
|
211
|
+
- Code blocks without language specification
|
|
212
|
+
- Heading punctuation issues
|
|
213
|
+
- Emphasis formatting problems
|
|
214
|
+
|
|
215
|
+
EOF
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
# Parse command line arguments
|
|
219
|
+
case "${1:-}" in
|
|
220
|
+
-h|--help)
|
|
221
|
+
show_help
|
|
222
|
+
exit 0
|
|
223
|
+
;;
|
|
224
|
+
--dry-run)
|
|
225
|
+
log_info "DRY RUN MODE - No changes will be made"
|
|
226
|
+
# Implementation for dry run would go here
|
|
227
|
+
exit 0
|
|
228
|
+
;;
|
|
229
|
+
--file)
|
|
230
|
+
if [ -n "${2:-}" ] && [ -f "$2" ]; then
|
|
231
|
+
log_info "Fixing single file: $2"
|
|
232
|
+
remove_trailing_whitespace "$2"
|
|
233
|
+
fix_heading_punctuation "$2"
|
|
234
|
+
fix_emphasis_formatting "$2"
|
|
235
|
+
fix_markdown_file "$2"
|
|
236
|
+
log_success "Completed fixing: $2"
|
|
237
|
+
else
|
|
238
|
+
log_error "File not found: ${2:-}"
|
|
239
|
+
exit 1
|
|
240
|
+
fi
|
|
241
|
+
exit 0
|
|
242
|
+
;;
|
|
243
|
+
"")
|
|
244
|
+
main
|
|
245
|
+
;;
|
|
246
|
+
*)
|
|
247
|
+
log_error "Unknown option: $1"
|
|
248
|
+
show_help
|
|
249
|
+
exit 1
|
|
250
|
+
;;
|
|
251
|
+
esac
|
data/scripts/utils/setup
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Development setup script for zer0-mistakes Jekyll theme
|
|
4
|
+
# Usage: ./scripts/utils/setup
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Get script and library directories
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
LIB_DIR="$SCRIPT_DIR/../lib"
|
|
11
|
+
|
|
12
|
+
# Source common library for logging and utilities
|
|
13
|
+
source "$LIB_DIR/common.sh"
|
|
14
|
+
|
|
15
|
+
log "Setting up zer0-mistakes Jekyll theme development environment..."
|
|
16
|
+
|
|
17
|
+
# Check system requirements
|
|
18
|
+
log "Checking system requirements..."
|
|
19
|
+
|
|
20
|
+
# Check Ruby
|
|
21
|
+
if ! command -v ruby &> /dev/null; then
|
|
22
|
+
error "Ruby is not installed. Please install Ruby >= 2.7.0"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
RUBY_VERSION=$(ruby --version | awk '{print $2}')
|
|
26
|
+
log "Ruby version: $RUBY_VERSION"
|
|
27
|
+
|
|
28
|
+
# Check Bundler
|
|
29
|
+
if ! command -v bundle &> /dev/null; then
|
|
30
|
+
log "Installing Bundler..."
|
|
31
|
+
gem install bundler
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Check jq
|
|
35
|
+
if ! command -v jq &> /dev/null; then
|
|
36
|
+
warn "jq is not installed. Installing via Homebrew (macOS)..."
|
|
37
|
+
if command -v brew &> /dev/null; then
|
|
38
|
+
brew install jq
|
|
39
|
+
else
|
|
40
|
+
error "jq is required but not installed. Please install jq manually."
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Check Git
|
|
45
|
+
if ! command -v git &> /dev/null; then
|
|
46
|
+
error "Git is not installed"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Install dependencies
|
|
50
|
+
log "Installing Ruby dependencies..."
|
|
51
|
+
bundle install
|
|
52
|
+
|
|
53
|
+
# Make scripts executable
|
|
54
|
+
log "Making scripts executable..."
|
|
55
|
+
chmod +x scripts/*.sh
|
|
56
|
+
|
|
57
|
+
# Validate gemspec
|
|
58
|
+
log "Validating gemspec..."
|
|
59
|
+
if gem specification jekyll-theme-zer0.gemspec > /dev/null 2>&1; then
|
|
60
|
+
info "✓ Gemspec is valid"
|
|
61
|
+
else
|
|
62
|
+
error "Gemspec validation failed"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Create CHANGELOG if it doesn't exist
|
|
66
|
+
if [[ ! -f "CHANGELOG.md" ]]; then
|
|
67
|
+
log "Creating CHANGELOG.md..."
|
|
68
|
+
cat > CHANGELOG.md << 'EOF'
|
|
69
|
+
# Changelog
|
|
70
|
+
|
|
71
|
+
All notable changes to this project will be documented in this file.
|
|
72
|
+
|
|
73
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
74
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
75
|
+
|
|
76
|
+
## [Unreleased]
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
- Initial development setup
|
|
80
|
+
|
|
81
|
+
EOF
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Create .gitignore additions for gem development
|
|
85
|
+
if ! grep -q "*.gem" .gitignore 2>/dev/null; then
|
|
86
|
+
log "Adding gem development entries to .gitignore..."
|
|
87
|
+
cat >> .gitignore << 'EOF'
|
|
88
|
+
|
|
89
|
+
# Gem development
|
|
90
|
+
*.gem
|
|
91
|
+
.bundle/
|
|
92
|
+
vendor/
|
|
93
|
+
pkg/
|
|
94
|
+
EOF
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# Setup Git hooks (optional)
|
|
98
|
+
if [[ -d ".git" ]]; then
|
|
99
|
+
log "Setting up Git hooks..."
|
|
100
|
+
mkdir -p .git/hooks
|
|
101
|
+
|
|
102
|
+
# Pre-commit hook to run basic validations
|
|
103
|
+
cat > .git/hooks/pre-commit << 'EOF'
|
|
104
|
+
#!/bin/bash
|
|
105
|
+
# Pre-commit hook for zer0-mistakes Jekyll theme
|
|
106
|
+
|
|
107
|
+
echo "Running pre-commit validations..."
|
|
108
|
+
|
|
109
|
+
# Validate gemspec
|
|
110
|
+
if ! gem specification jekyll-theme-zer0.gemspec > /dev/null 2>&1; then
|
|
111
|
+
echo "❌ Gemspec validation failed"
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Check if package.json version is valid
|
|
116
|
+
if ! jq -e '.version' package.json > /dev/null 2>&1; then
|
|
117
|
+
echo "❌ Invalid version in package.json"
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
echo "✅ Pre-commit validations passed"
|
|
122
|
+
EOF
|
|
123
|
+
chmod +x .git/hooks/pre-commit
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
log "Setup complete!"
|
|
127
|
+
log ""
|
|
128
|
+
log "Available commands:"
|
|
129
|
+
log " ./scripts/version.sh [patch|minor|major] - Bump version"
|
|
130
|
+
log " ./scripts/build.sh [--publish] - Build (and optionally publish) gem"
|
|
131
|
+
log " ./scripts/test.sh - Run tests"
|
|
132
|
+
log ""
|
|
133
|
+
log "Development workflow:"
|
|
134
|
+
log "1. Make your changes"
|
|
135
|
+
log "2. Run ./scripts/test.sh to validate"
|
|
136
|
+
log "3. Run ./scripts/version.sh to bump version"
|
|
137
|
+
log "4. Run ./scripts/build.sh --publish to release"
|