jekyll-theme-zer0 0.8.1 → 0.10.0

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.
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+
3
+ # Unit tests for validation.sh library
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ LIB_DIR="$(cd "$SCRIPT_DIR/../../lib" && pwd)"
7
+
8
+ # Set up test environment
9
+ export DRY_RUN=true
10
+ export INTERACTIVE=false
11
+ export VERBOSE=false
12
+
13
+ # Source the library
14
+ source "$LIB_DIR/validation.sh"
15
+
16
+ # Disable errexit for test assertions
17
+ set +e
18
+
19
+ print_suite_header "validation.sh"
20
+
21
+ # Test: validate_git_repo (should pass since we're in a git repo)
22
+ echo "Testing validate_git_repo..."
23
+
24
+ if validate_git_repo 2>/dev/null; then
25
+ assert_true "true" "Detects git repository"
26
+ else
27
+ assert_true "false" "Detects git repository"
28
+ fi
29
+
30
+ # Test: validate_required_files
31
+ echo -e "\nTesting validate_required_files..."
32
+
33
+ # This will fail if we're not in the project root, but that's expected for tests
34
+ if validate_required_files 2>/dev/null; then
35
+ assert_true "true" "Required files exist"
36
+ else
37
+ # If files don't exist (running from test dir), that's ok for unit tests
38
+ echo -e "${YELLOW}ℹ${NC} Required files check skipped (not in project root)"
39
+ fi
40
+
41
+ # Test: command_exists (from common.sh)
42
+ echo -e "\nTesting command_exists..."
43
+
44
+ if command_exists "git"; then
45
+ assert_true "true" "Git command exists"
46
+ else
47
+ assert_true "false" "Git command exists"
48
+ fi
49
+
50
+ if command_exists "bash"; then
51
+ assert_true "true" "Bash command exists"
52
+ else
53
+ assert_true "false" "Bash command exists"
54
+ fi
55
+
56
+ if command_exists "nonexistent_command_xyz"; then
57
+ assert_false "true" "Nonexistent command not found"
58
+ else
59
+ assert_false "false" "Nonexistent command not found"
60
+ fi
61
+
62
+ # Test: validate_dependencies
63
+ echo -e "\nTesting validate_dependencies..."
64
+
65
+ # Test that common dependencies are found
66
+ common_commands=("git" "ruby" "bundle" "jq")
67
+ for cmd in "${common_commands[@]}"; do
68
+ if command_exists "$cmd"; then
69
+ assert_true "true" "Required command exists: $cmd"
70
+ else
71
+ echo -e "${YELLOW}ℹ${NC} Optional command not found: $cmd (skipping)"
72
+ fi
73
+ done
74
+
75
+ echo -e "\n${GREEN}validation.sh tests complete${NC}"
@@ -0,0 +1,101 @@
1
+ #!/bin/bash
2
+
3
+ # Unit tests for version.sh library
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ LIB_DIR="$(cd "$SCRIPT_DIR/../../lib" && pwd)"
7
+
8
+ # Set up test environment
9
+ export DRY_RUN=true
10
+ export INTERACTIVE=false
11
+ export VERBOSE=false
12
+
13
+ # Source the library
14
+ source "$LIB_DIR/version.sh"
15
+
16
+ # Disable errexit for test assertions (sourcing common.sh enables it)
17
+ set +e
18
+
19
+ print_suite_header "version.sh"
20
+
21
+ # Test: validate_version_format
22
+ echo "Testing validate_version_format..."
23
+
24
+ valid_versions=("0.0.1" "1.0.0" "10.20.30" "999.999.999")
25
+ for version in "${valid_versions[@]}"; do
26
+ # Run in subshell because error() calls exit 1
27
+ if (validate_version_format "$version" 2>/dev/null); then
28
+ assert_true "true" "Valid version format accepted: $version"
29
+ else
30
+ assert_true "false" "Valid version format accepted: $version"
31
+ fi
32
+ done
33
+
34
+ invalid_versions=("1.0" "1.0.0.0" "v1.0.0" "1.0.0-beta" "abc.def.ghi")
35
+ for version in "${invalid_versions[@]}"; do
36
+ # Run in subshell because error() calls exit 1
37
+ if (validate_version_format "$version" 2>/dev/null); then
38
+ assert_false "true" "Invalid version format rejected: $version"
39
+ else
40
+ assert_false "false" "Invalid version format rejected: $version"
41
+ fi
42
+ done
43
+
44
+ # Test: calculate_new_version
45
+ echo -e "\nTesting calculate_new_version..."
46
+
47
+ result=$(calculate_new_version "1.2.3" "patch")
48
+ assert_equals "1.2.4" "$result" "Patch bump: 1.2.3 → 1.2.4"
49
+
50
+ result=$(calculate_new_version "1.2.3" "minor")
51
+ assert_equals "1.3.0" "$result" "Minor bump: 1.2.3 → 1.3.0"
52
+
53
+ result=$(calculate_new_version "1.2.3" "major")
54
+ assert_equals "2.0.0" "$result" "Major bump: 1.2.3 → 2.0.0"
55
+
56
+ result=$(calculate_new_version "0.0.9" "patch")
57
+ assert_equals "0.0.10" "$result" "Patch bump with digit rollover: 0.0.9 → 0.0.10"
58
+
59
+ result=$(calculate_new_version "0.9.9" "minor")
60
+ assert_equals "0.10.0" "$result" "Minor bump resets patch: 0.9.9 → 0.10.0"
61
+
62
+ result=$(calculate_new_version "9.9.9" "major")
63
+ assert_equals "10.0.0" "$result" "Major bump resets minor and patch: 9.9.9 → 10.0.0"
64
+
65
+ # Test: version_less_than
66
+ echo -e "\nTesting version_less_than..."
67
+
68
+ if version_less_than "1.0.0" "2.0.0"; then
69
+ assert_true "true" "1.0.0 < 2.0.0"
70
+ else
71
+ assert_true "false" "1.0.0 < 2.0.0"
72
+ fi
73
+
74
+ if version_less_than "1.2.3" "1.2.4"; then
75
+ assert_true "true" "1.2.3 < 1.2.4"
76
+ else
77
+ assert_true "false" "1.2.3 < 1.2.4"
78
+ fi
79
+
80
+ if version_less_than "2.0.0" "1.0.0"; then
81
+ assert_false "true" "2.0.0 not < 1.0.0"
82
+ else
83
+ assert_false "false" "2.0.0 not < 1.0.0"
84
+ fi
85
+
86
+ if version_less_than "1.2.3" "1.2.3"; then
87
+ assert_false "true" "1.2.3 not < 1.2.3 (equal)"
88
+ else
89
+ assert_false "false" "1.2.3 not < 1.2.3 (equal)"
90
+ fi
91
+
92
+ # Test: get_version_from_tag
93
+ echo -e "\nTesting get_version_from_tag..."
94
+
95
+ result=$(get_version_from_tag "v1.2.3")
96
+ assert_equals "1.2.3" "$result" "Remove 'v' prefix: v1.2.3 → 1.2.3"
97
+
98
+ result=$(get_version_from_tag "1.2.3")
99
+ assert_equals "1.2.3" "$result" "No prefix to remove: 1.2.3 → 1.2.3"
100
+
101
+ echo -e "\n${GREEN}version.sh tests complete${NC}"
@@ -0,0 +1,120 @@
1
+ #!/bin/bash
2
+
3
+ # Theme validation tests for zer0-mistakes Jekyll theme
4
+ # Usage: ./scripts/test/theme/validate
5
+
6
+ set -euo pipefail
7
+
8
+ # Get script and library directories
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ SCRIPTS_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
11
+ LIB_DIR="$SCRIPTS_ROOT/lib"
12
+ PROJECT_ROOT="$(cd "$SCRIPTS_ROOT/.." && pwd)"
13
+
14
+ # Source common library for logging and utilities
15
+ source "$LIB_DIR/common.sh"
16
+
17
+ # Test counter
18
+ TESTS_RUN=0
19
+ TESTS_PASSED=0
20
+
21
+ run_test() {
22
+ local test_name="$1"
23
+ local test_command="$2"
24
+
25
+ ((TESTS_RUN++)) || true
26
+
27
+ step "Running: $test_name"
28
+
29
+ if [[ "${VERBOSE:-false}" == "true" ]]; then
30
+ debug "Command: $test_command"
31
+ fi
32
+
33
+ if eval "$test_command" > /dev/null 2>&1; then
34
+ success "$test_name"
35
+ ((TESTS_PASSED++)) || true
36
+ else
37
+ warn "$test_name - FAILED"
38
+ if [[ "${VERBOSE:-false}" == "true" ]]; then
39
+ echo "Command output:"
40
+ eval "$test_command" 2>&1 || true
41
+ fi
42
+ fi
43
+ }
44
+
45
+ log "Running theme validation tests for zer0-mistakes..."
46
+
47
+ cd "$PROJECT_ROOT"
48
+
49
+ # Test 1: Validate package.json
50
+ run_test "Validate package.json syntax" "jq empty package.json"
51
+
52
+ # Test 2: Validate package.json version
53
+ run_test "Validate package.json version format" "jq -r '.version' package.json | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'"
54
+
55
+ # Test 3: Validate gemspec syntax
56
+ run_test "Validate gemspec syntax" "ruby -c jekyll-theme-zer0.gemspec"
57
+
58
+ # Test 4: Build gem (test build)
59
+ run_test "Test gem build" "gem build jekyll-theme-zer0.gemspec"
60
+
61
+ # Test 5: Check for required files
62
+ run_test "Check README.md exists" "test -f README.md"
63
+ run_test "Check LICENSE exists" "test -f LICENSE"
64
+ run_test "Check _layouts directory exists" "test -d _layouts"
65
+ run_test "Check _includes directory exists" "test -d _includes"
66
+ run_test "Check _sass directory exists" "test -d _sass"
67
+ run_test "Check assets directory exists" "test -d assets"
68
+
69
+ # Test 6: Validate YAML front matter in layouts
70
+ if [[ -d "_layouts" ]]; then
71
+ for layout in _layouts/*.html; do
72
+ if [[ -f "$layout" ]]; then
73
+ layout_name=$(basename "$layout")
74
+ run_test "Validate front matter in $layout_name" "head -10 '$layout' | grep -q -- '---'"
75
+ fi
76
+ done
77
+ fi
78
+
79
+ # Test 7: Check for common Jekyll requirements
80
+ run_test "Check Jekyll dependency in gemspec" "grep -q 'jekyll' jekyll-theme-zer0.gemspec"
81
+
82
+ # Test 8: Validate version consistency
83
+ PACKAGE_VERSION=$(jq -r '.version' package.json)
84
+ if [[ -f "jekyll-theme-zer0-${PACKAGE_VERSION}.gem" ]]; then
85
+ run_test "Version consistency check" "test -f jekyll-theme-zer0-${PACKAGE_VERSION}.gem"
86
+ fi
87
+
88
+ # Test 9: Check scripts are executable
89
+ if [[ -d "scripts/bin" ]]; then
90
+ for script in scripts/bin/*; do
91
+ if [[ -f "$script" ]]; then
92
+ script_name=$(basename "$script")
93
+ run_test "Check $script_name is executable" "test -x '$script'"
94
+ fi
95
+ done
96
+ fi
97
+
98
+ # Test 10: Validate bundle install
99
+ run_test "Test bundle install" "bundle install --quiet"
100
+
101
+ # Clean up test gem file
102
+ rm -f jekyll-theme-zer0-*.gem 2>/dev/null || true
103
+
104
+ # Test results
105
+ echo ""
106
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
107
+ info "Test Results"
108
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
109
+ echo " Tests run: $TESTS_RUN"
110
+ echo " Tests passed: $TESTS_PASSED"
111
+ echo " Tests failed: $((TESTS_RUN - TESTS_PASSED))"
112
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
113
+
114
+ if [[ $TESTS_PASSED -eq $TESTS_RUN ]]; then
115
+ success "All tests passed!"
116
+ exit 0
117
+ else
118
+ error "Some tests failed!"
119
+ exit 1
120
+ fi
@@ -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 "$@"