neon_sakura 0.1.4
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 +7 -0
- data/.ai-reviewer/README.md +182 -0
- data/.ai-reviewer/ai-reviewer.sh +56 -0
- data/.ai-reviewer/build-system-prompt.sh +136 -0
- data/.ai-reviewer/extract-claude-sections.sh +32 -0
- data/.ai-reviewer/test-ai-reviewer.sh +40 -0
- data/.ai-reviewer-config.yml +190 -0
- data/.github/dependabot.yml +12 -0
- data/.github/settings.yml +70 -0
- data/.github/workflows/ai-pr-review-on-comment.yml +384 -0
- data/.github/workflows/ai-pr-review.yml +328 -0
- data/.github/workflows/license-check.yml +78 -0
- data/.github/workflows/lint.yml +79 -0
- data/.github/workflows/security.yml +131 -0
- data/.github/workflows/semgrep.yml +26 -0
- data/.github/workflows/test.yml +44 -0
- data/.gitignore +75 -0
- data/.rubocop.yml +33 -0
- data/.ruby-version +1 -0
- data/.simplecov +14 -0
- data/.stylelintignore +10 -0
- data/.stylelintrc.json +37 -0
- data/AGENTS.md +51 -0
- data/CHANGELOG.md +568 -0
- data/CLAUDE.md +632 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +327 -0
- data/LICENSE +21 -0
- data/README.md +1209 -0
- data/Rakefile +25 -0
- data/app/assets/images/cherry_blossom.svg +1525 -0
- data/app/assets/images/cherry_blossom_tree.png +0 -0
- data/app/assets/images/prysm-icon.png +0 -0
- data/app/assets/stylesheets/base.css +29 -0
- data/app/assets/stylesheets/components.css +1652 -0
- data/app/assets/stylesheets/forms.css +152 -0
- data/app/assets/stylesheets/loading.css +145 -0
- data/app/assets/stylesheets/neon_sakura.css +40 -0
- data/app/assets/stylesheets/pagy-tailwind.css +120 -0
- data/app/assets/stylesheets/theme-default.css +40 -0
- data/app/assets/stylesheets/theme-green.css +84 -0
- data/app/assets/stylesheets/theme-purple.css +94 -0
- data/app/assets/stylesheets/theme-red.css +84 -0
- data/app/assets/stylesheets/utility-borders.css +29 -0
- data/app/assets/stylesheets/utility-colors.css +185 -0
- data/app/assets/stylesheets/utility-effects.css +123 -0
- data/app/assets/stylesheets/utility-gradients.css +158 -0
- data/app/assets/stylesheets/utility-layout.css +132 -0
- data/app/assets/stylesheets/utility-reset.css +13 -0
- data/app/assets/stylesheets/utility-responsive.css +145 -0
- data/app/assets/stylesheets/utility-sizing.css +99 -0
- data/app/assets/stylesheets/utility-spacing.css +174 -0
- data/app/assets/stylesheets/utility-typography.css +97 -0
- data/app/controllers/errors_controller.rb +120 -0
- data/app/controllers/style_guide_controller.rb +117 -0
- data/app/helpers/errors_helper.rb +12 -0
- data/app/helpers/neon_sakura/navbar_helper.rb +43 -0
- data/app/helpers/style_guide_helper.rb +36 -0
- data/app/javascript/neon_sakura/dropdown.js +22 -0
- data/app/javascript/neon_sakura/navbar.js +71 -0
- data/app/javascript/neon_sakura/theme_switcher.js +187 -0
- data/app/views/errors/show.html.erb +105 -0
- data/app/views/layouts/error.html.erb +19 -0
- data/app/views/layouts/mission_control/jobs/_application_selection.html.erb +14 -0
- data/app/views/layouts/mission_control/jobs/_navigation.html.erb +21 -0
- data/app/views/layouts/mission_control/jobs/application.html.erb +453 -0
- data/app/views/layouts/style_guide.html.erb +416 -0
- data/app/views/shared/_file_upload.html.erb +184 -0
- data/app/views/shared/_footer.html.erb +23 -0
- data/app/views/shared/_header.html.erb +42 -0
- data/app/views/shared/_navbar.html.erb +306 -0
- data/app/views/shared/_profile_image_selector.html.erb +165 -0
- data/app/views/shared/_theme_switcher.html.erb +64 -0
- data/app/views/shared/icons/_adjustments.html.erb +10 -0
- data/app/views/shared/icons/_alert_circle.html.erb +3 -0
- data/app/views/shared/icons/_alert_triangle.html.erb +3 -0
- data/app/views/shared/icons/_archive.html.erb +3 -0
- data/app/views/shared/icons/_arrow_down.html.erb +3 -0
- data/app/views/shared/icons/_arrow_left.html.erb +3 -0
- data/app/views/shared/icons/_arrow_up.html.erb +3 -0
- data/app/views/shared/icons/_arrows_pointing_in.html.erb +10 -0
- data/app/views/shared/icons/_arrows_pointing_out.html.erb +10 -0
- data/app/views/shared/icons/_artemis_logo.html.erb +26 -0
- data/app/views/shared/icons/_auth_banner.html.erb +1 -0
- data/app/views/shared/icons/_bars.html.erb +10 -0
- data/app/views/shared/icons/_bell.html.erb +3 -0
- data/app/views/shared/icons/_book.html.erb +3 -0
- data/app/views/shared/icons/_bookmark.html.erb +3 -0
- data/app/views/shared/icons/_box.html.erb +3 -0
- data/app/views/shared/icons/_brain.html.erb +3 -0
- data/app/views/shared/icons/_briefcase.html.erb +3 -0
- data/app/views/shared/icons/_calendar.html.erb +3 -0
- data/app/views/shared/icons/_camera.html.erb +4 -0
- data/app/views/shared/icons/_chart_bar.html.erb +3 -0
- data/app/views/shared/icons/_chart_line.html.erb +10 -0
- data/app/views/shared/icons/_chart_pie.html.erb +11 -0
- data/app/views/shared/icons/_chat.html.erb +3 -0
- data/app/views/shared/icons/_check.html.erb +3 -0
- data/app/views/shared/icons/_check_circle.html.erb +3 -0
- data/app/views/shared/icons/_cherry_blossom.html.erb +1516 -0
- data/app/views/shared/icons/_cherry_blossom_silhouette.html.erb +1016 -0
- data/app/views/shared/icons/_cherry_blossom_single_flower.html.erb +1125 -0
- data/app/views/shared/icons/_cherry_blossom_tree.html.erb +159 -0
- data/app/views/shared/icons/_chevron_down.html.erb +3 -0
- data/app/views/shared/icons/_chevron_right.html.erb +9 -0
- data/app/views/shared/icons/_clipboard.html.erb +3 -0
- data/app/views/shared/icons/_clock.html.erb +3 -0
- data/app/views/shared/icons/_close.html.erb +3 -0
- data/app/views/shared/icons/_cog.html.erb +4 -0
- data/app/views/shared/icons/_crop.html.erb +10 -0
- data/app/views/shared/icons/_crown.html.erb +3 -0
- data/app/views/shared/icons/_disc.html.erb +3 -0
- data/app/views/shared/icons/_download.html.erb +3 -0
- data/app/views/shared/icons/_dragonfly.html.erb +58 -0
- data/app/views/shared/icons/_duplicate.html.erb +4 -0
- data/app/views/shared/icons/_edit.html.erb +3 -0
- data/app/views/shared/icons/_envelope.html.erb +3 -0
- data/app/views/shared/icons/_eraser.html.erb +10 -0
- data/app/views/shared/icons/_external_link.html.erb +3 -0
- data/app/views/shared/icons/_eye.html.erb +4 -0
- data/app/views/shared/icons/_file_csv.html.erb +10 -0
- data/app/views/shared/icons/_file_export.html.erb +10 -0
- data/app/views/shared/icons/_file_image.html.erb +10 -0
- data/app/views/shared/icons/_file_import.html.erb +10 -0
- data/app/views/shared/icons/_file_question.html.erb +6 -0
- data/app/views/shared/icons/_film.html.erb +3 -0
- data/app/views/shared/icons/_filter.html.erb +3 -0
- data/app/views/shared/icons/_folder.html.erb +3 -0
- data/app/views/shared/icons/_folder_open.html.erb +3 -0
- data/app/views/shared/icons/_folder_plus.html.erb +3 -0
- data/app/views/shared/icons/_globe.html.erb +3 -0
- data/app/views/shared/icons/_google.html.erb +11 -0
- data/app/views/shared/icons/_heart.html.erb +3 -0
- data/app/views/shared/icons/_heart_broken.html.erb +11 -0
- data/app/views/shared/icons/_heart_pulse.html.erb +4 -0
- data/app/views/shared/icons/_history.html.erb +11 -0
- data/app/views/shared/icons/_home.html.erb +10 -0
- data/app/views/shared/icons/_image.html.erb +3 -0
- data/app/views/shared/icons/_inbox.html.erb +3 -0
- data/app/views/shared/icons/_info_circle.html.erb +10 -0
- data/app/views/shared/icons/_key.html.erb +3 -0
- data/app/views/shared/icons/_layers.html.erb +10 -0
- data/app/views/shared/icons/_lightbulb.html.erb +10 -0
- data/app/views/shared/icons/_lightning.html.erb +3 -0
- data/app/views/shared/icons/_list.html.erb +3 -0
- data/app/views/shared/icons/_lock.html.erb +3 -0
- data/app/views/shared/icons/_logout.html.erb +3 -0
- data/app/views/shared/icons/_magazine.html.erb +3 -0
- data/app/views/shared/icons/_magic.html.erb +3 -0
- data/app/views/shared/icons/_minus.html.erb +10 -0
- data/app/views/shared/icons/_mobile.html.erb +10 -0
- data/app/views/shared/icons/_moon.html.erb +3 -0
- data/app/views/shared/icons/_network.html.erb +10 -0
- data/app/views/shared/icons/_new_item_banner.html.erb +1 -0
- data/app/views/shared/icons/_ouroboros.html.erb +24 -0
- data/app/views/shared/icons/_package.html.erb +3 -0
- data/app/views/shared/icons/_palette.html.erb +3 -0
- data/app/views/shared/icons/_paper_plane.html.erb +10 -0
- data/app/views/shared/icons/_photo.html.erb +10 -0
- data/app/views/shared/icons/_play.html.erb +4 -0
- data/app/views/shared/icons/_plus.html.erb +3 -0
- data/app/views/shared/icons/_pocket.html.erb +11 -0
- data/app/views/shared/icons/_prysm-icon.html.erb +34 -0
- data/app/views/shared/icons/_prysm.html.erb +13 -0
- data/app/views/shared/icons/_pushbullet-1.html.erb +29 -0
- data/app/views/shared/icons/_pushbullet-2.html.erb +2 -0
- data/app/views/shared/icons/_puzzle.html.erb +10 -0
- data/app/views/shared/icons/_qrcode.html.erb +3 -0
- data/app/views/shared/icons/_question.html.erb +3 -0
- data/app/views/shared/icons/_receipt.html.erb +10 -0
- data/app/views/shared/icons/_redo.html.erb +3 -0
- data/app/views/shared/icons/_refresh.html.erb +3 -0
- data/app/views/shared/icons/_rocket.html.erb +10 -0
- data/app/views/shared/icons/_rss.html.erb +3 -0
- data/app/views/shared/icons/_save.html.erb +3 -0
- data/app/views/shared/icons/_search.html.erb +3 -0
- data/app/views/shared/icons/_search_minus.html.erb +10 -0
- data/app/views/shared/icons/_search_plus.html.erb +10 -0
- data/app/views/shared/icons/_server_error.html.erb +6 -0
- data/app/views/shared/icons/_share.html.erb +3 -0
- data/app/views/shared/icons/_shield_check.html.erb +3 -0
- data/app/views/shared/icons/_sign_in.html.erb +3 -0
- data/app/views/shared/icons/_spinner.html.erb +4 -0
- data/app/views/shared/icons/_star.html.erb +3 -0
- data/app/views/shared/icons/_store.html.erb +10 -0
- data/app/views/shared/icons/_sun.html.erb +3 -0
- data/app/views/shared/icons/_sync.html.erb +3 -0
- data/app/views/shared/icons/_table.html.erb +3 -0
- data/app/views/shared/icons/_tag.html.erb +3 -0
- data/app/views/shared/icons/_tags.html.erb +11 -0
- data/app/views/shared/icons/_tools.html.erb +4 -0
- data/app/views/shared/icons/_trash.html.erb +3 -0
- data/app/views/shared/icons/_undo.html.erb +3 -0
- data/app/views/shared/icons/_unlock.html.erb +3 -0
- data/app/views/shared/icons/_upload.html.erb +3 -0
- data/app/views/shared/icons/_user.html.erb +3 -0
- data/app/views/shared/icons/_user_circle.html.erb +10 -0
- data/app/views/shared/icons/_user_plus.html.erb +10 -0
- data/app/views/shared/icons/_video.html.erb +3 -0
- data/app/views/shared/icons/_wrench.html.erb +11 -0
- data/app/views/style_guide/index.html.erb +77 -0
- data/app/views/style_guide/sections/_alerts.html.erb +114 -0
- data/app/views/style_guide/sections/_badges.html.erb +78 -0
- data/app/views/style_guide/sections/_buttons.html.erb +130 -0
- data/app/views/style_guide/sections/_cards.html.erb +84 -0
- data/app/views/style_guide/sections/_colors.html.erb +106 -0
- data/app/views/style_guide/sections/_file_upload.html.erb +135 -0
- data/app/views/style_guide/sections/_forms.html.erb +129 -0
- data/app/views/style_guide/sections/_gradients.html.erb +253 -0
- data/app/views/style_guide/sections/_header.html.erb +12 -0
- data/app/views/style_guide/sections/_icons.html.erb +55 -0
- data/app/views/style_guide/sections/_images.html.erb +40 -0
- data/app/views/style_guide/sections/_loading.html.erb +242 -0
- data/app/views/style_guide/sections/_pagination.html.erb +212 -0
- data/app/views/style_guide/sections/_profile_components.html.erb +203 -0
- data/app/views/style_guide/sections/_theme_switcher.html.erb +72 -0
- data/app/views/style_guide/sections/_typography.html.erb +65 -0
- data/bin/ai-optimize-claude-md +540 -0
- data/bin/ai-review-local +345 -0
- data/bin/ai-security-review +585 -0
- data/bin/brakeman +9 -0
- data/bin/install-hooks +57 -0
- data/bin/rake +7 -0
- data/bin/rubocop +10 -0
- data/bin/verify_setup.rb +31 -0
- data/config/brakeman.ignore +28 -0
- data/config/initializers/neon_sakura.rb +15 -0
- data/config/license_overrides.yml +13 -0
- data/config/routes.rb +21 -0
- data/config/theme_mappings.yml +61 -0
- data/docs/PRYSM_ASSETS.md +210 -0
- data/docs/plans/extract_ai_reviewer_plan.md +151 -0
- data/docs/plans/neon_sakura_gem_plan.md +138 -0
- data/lib/neon_sakura/configuration.rb +94 -0
- data/lib/neon_sakura/engine.rb +48 -0
- data/lib/neon_sakura/icon_helper.rb +54 -0
- data/lib/neon_sakura/profile_helper.rb +24 -0
- data/lib/neon_sakura/stylesheet_helper.rb +40 -0
- data/lib/neon_sakura/theme_helper.rb +63 -0
- data/lib/neon_sakura/theme_importer.rb +112 -0
- data/lib/neon_sakura/version.rb +5 -0
- data/lib/neon_sakura.rb +13 -0
- data/neon_sakura.gemspec +50 -0
- data/package.json +18 -0
- data/scripts/git-hooks/post-merge +132 -0
- data/scripts/git-hooks/pre-commit +123 -0
- data/scripts/git-hooks/pre-push +127 -0
- data/scripts/license-check.rb +587 -0
- data/settings.local.json +12 -0
- data/yarn.lock +778 -0
- metadata +503 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# neon_sakura pre-commit hook
|
|
4
|
+
# Runs Rubocop and Brakeman security checks before commits
|
|
5
|
+
|
|
6
|
+
echo "🔍 Running pre-commit checks..."
|
|
7
|
+
|
|
8
|
+
# Check if we're in a Rails app
|
|
9
|
+
if [ ! -f "Gemfile" ]; then
|
|
10
|
+
echo "❌ Not a Rails application, skipping checks"
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Colors for output
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
NC='\033[0m' # No Color
|
|
19
|
+
|
|
20
|
+
# Function to run command and check exit status
|
|
21
|
+
run_check() {
|
|
22
|
+
local check_name="$1"
|
|
23
|
+
local command="$2"
|
|
24
|
+
local success_msg="$3"
|
|
25
|
+
local failure_msg="$4"
|
|
26
|
+
|
|
27
|
+
echo -e "${YELLOW}Running $check_name...${NC}"
|
|
28
|
+
|
|
29
|
+
if eval "$command" > /dev/null 2>&1; then
|
|
30
|
+
echo -e "${GREEN}✅ $success_msg${NC}"
|
|
31
|
+
return 0
|
|
32
|
+
else
|
|
33
|
+
echo -e "${RED}❌ $failure_msg${NC}"
|
|
34
|
+
return 1
|
|
35
|
+
fi
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Track if any checks failed
|
|
39
|
+
failed_checks=0
|
|
40
|
+
|
|
41
|
+
# 1. Rubocop - Ruby code style and quality
|
|
42
|
+
if ! run_check "Rubocop" "bundle exec rubocop --fail-fast" "Ruby code style checks passed" "Ruby code style issues found"; then
|
|
43
|
+
echo -e "${RED}Fix Rubocop issues with: bundle exec rubocop -a${NC}"
|
|
44
|
+
failed_checks=$((failed_checks + 1))
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# 2. Stylelint - CSS linting
|
|
48
|
+
if command -v yarn &> /dev/null && [ -f "package.json" ]; then
|
|
49
|
+
if ! run_check "Stylelint" "yarn lint:css" "CSS style checks passed" "CSS style issues found"; then
|
|
50
|
+
echo -e "${RED}Fix CSS style issues with: yarn lint:css:fix${NC}"
|
|
51
|
+
failed_checks=$((failed_checks + 1))
|
|
52
|
+
fi
|
|
53
|
+
else
|
|
54
|
+
echo -e "${YELLOW}⚠️ Stylelint skipped (yarn not installed or package.json missing)${NC}"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# 3. Brakeman - Security vulnerability scanner
|
|
58
|
+
if ! run_check "Brakeman" "bundle exec brakeman -q --no-pager" "Security scan passed" "Security vulnerabilities found"; then
|
|
59
|
+
echo -e "${RED}Review security issues with: bundle exec brakeman${NC}"
|
|
60
|
+
failed_checks=$((failed_checks + 1))
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# 4. Bundle Audit - Check for gem vulnerabilities
|
|
64
|
+
if ! run_check "Bundle Audit" "bundle exec bundle-audit check --update" "Gem security check passed" "Vulnerable gems found"; then
|
|
65
|
+
echo -e "${RED}Update vulnerable gems or check: bundle exec bundle-audit check${NC}"
|
|
66
|
+
failed_checks=$((failed_checks + 1))
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# 5. Pending Migrations - Check for unapplied migrations
|
|
70
|
+
pending_migrations=$(bundle exec rails db:migrate:status 2>/dev/null | grep "^\s*down" | wc -l)
|
|
71
|
+
if [ "$pending_migrations" -gt 0 ]; then
|
|
72
|
+
echo -e "${RED}❌ $pending_migrations pending migration(s) found${NC}"
|
|
73
|
+
echo -e "${RED}Run: bundle exec rails db:migrate${NC}"
|
|
74
|
+
failed_checks=$((failed_checks + 1))
|
|
75
|
+
else
|
|
76
|
+
echo -e "${GREEN}✅ No pending migrations${NC}"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# 6. Secrets Detection - Scan for API keys/passwords
|
|
80
|
+
secrets_check() {
|
|
81
|
+
# Check for common secret patterns in staged files
|
|
82
|
+
local patterns=(
|
|
83
|
+
"api[_-]?key\s*[:=]\s*['\"][^'\"]{10,}['\"]"
|
|
84
|
+
"secret[_-]?key\s*[:=]\s*['\"][^'\"]{10,}['\"]"
|
|
85
|
+
"password\s*[:=]\s*['\"][^'\"]{8,}['\"]"
|
|
86
|
+
"token\s*[:=]\s*['\"][^'\"]{10,}['\"]"
|
|
87
|
+
"access[_-]?token\s*[:=]\s*['\"][^'\"]{10,}['\"]"
|
|
88
|
+
"private[_-]?key"
|
|
89
|
+
"-----BEGIN.*PRIVATE KEY-----"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Get staged files
|
|
93
|
+
staged_files=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(rb|yml|yaml|env|json)$' || true)
|
|
94
|
+
|
|
95
|
+
if [ -n "$staged_files" ]; then
|
|
96
|
+
for pattern in "${patterns[@]}"; do
|
|
97
|
+
if echo "$staged_files" | xargs git show :0 2>/dev/null | grep -iE "$pattern" > /dev/null 2>&1; then
|
|
98
|
+
return 1
|
|
99
|
+
fi
|
|
100
|
+
done
|
|
101
|
+
fi
|
|
102
|
+
return 0
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if ! secrets_check; then
|
|
106
|
+
echo -e "${RED}❌ Potential secrets detected in staged files${NC}"
|
|
107
|
+
echo -e "${RED}Review your changes for API keys, passwords, or tokens${NC}"
|
|
108
|
+
failed_checks=$((failed_checks + 1))
|
|
109
|
+
else
|
|
110
|
+
echo -e "${GREEN}✅ No secrets detected${NC}"
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# Exit with error if any checks failed
|
|
114
|
+
if [ $failed_checks -gt 0 ]; then
|
|
115
|
+
echo ""
|
|
116
|
+
echo -e "${RED}❌ $failed_checks check(s) failed. Commit aborted.${NC}"
|
|
117
|
+
echo -e "${YELLOW}Fix the issues above and try committing again.${NC}"
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
echo ""
|
|
122
|
+
echo -e "${GREEN}🎉 All pre-commit checks passed!${NC}"
|
|
123
|
+
exit 0
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# neon_sakura pre-push hook
|
|
4
|
+
# Runs database consistency and asset compilation checks before pushing
|
|
5
|
+
|
|
6
|
+
echo "🚀 Running pre-push checks..."
|
|
7
|
+
|
|
8
|
+
# Check if we're in a Rails app
|
|
9
|
+
if [ ! -f "Gemfile" ]; then
|
|
10
|
+
echo "❌ Not a Rails application, skipping checks"
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Colors for output
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
NC='\033[0m' # No Color
|
|
19
|
+
|
|
20
|
+
# Function to run command and check exit status
|
|
21
|
+
run_check() {
|
|
22
|
+
local check_name="$1"
|
|
23
|
+
local command="$2"
|
|
24
|
+
local success_msg="$3"
|
|
25
|
+
local failure_msg="$4"
|
|
26
|
+
|
|
27
|
+
echo -e "${YELLOW}Running $check_name...${NC}"
|
|
28
|
+
|
|
29
|
+
if eval "$command" > /dev/null 2>&1; then
|
|
30
|
+
echo -e "${GREEN}✅ $success_msg${NC}"
|
|
31
|
+
return 0
|
|
32
|
+
else
|
|
33
|
+
echo -e "${RED}❌ $failure_msg${NC}"
|
|
34
|
+
return 1
|
|
35
|
+
fi
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Track if any checks failed
|
|
39
|
+
failed_checks=0
|
|
40
|
+
|
|
41
|
+
# 1. Database Consistency - Check schema.rb matches migrations
|
|
42
|
+
check_schema_consistency() {
|
|
43
|
+
# Check if schema.rb is up to date with migrations
|
|
44
|
+
local schema_version=""
|
|
45
|
+
local migration_version=""
|
|
46
|
+
|
|
47
|
+
# Get version from schema.rb
|
|
48
|
+
if [ -f "db/schema.rb" ]; then
|
|
49
|
+
schema_version=$(grep "ActiveRecord::Schema\[.*\]\.define.*version:" db/schema.rb | grep -o "version: [0-9_]*" | cut -d' ' -f2 | tr -d '_')
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Get latest migration version
|
|
53
|
+
if [ -d "db/migrate" ]; then
|
|
54
|
+
migration_version=$(ls db/migrate/*.rb 2>/dev/null | tail -1 | grep -o "[0-9]\{14\}" | head -1)
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
if [ -n "$schema_version" ] && [ -n "$migration_version" ]; then
|
|
58
|
+
if [ "$schema_version" = "$migration_version" ]; then
|
|
59
|
+
return 0
|
|
60
|
+
else
|
|
61
|
+
return 1
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# If we can't determine versions, assume they're consistent
|
|
66
|
+
return 0
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if ! check_schema_consistency; then
|
|
70
|
+
echo -e "${RED}❌ Schema.rb doesn't match latest migration${NC}"
|
|
71
|
+
echo -e "${RED}Run: bundle exec rails db:migrate${NC}"
|
|
72
|
+
failed_checks=$((failed_checks + 1))
|
|
73
|
+
else
|
|
74
|
+
echo -e "${GREEN}✅ Database schema is consistent${NC}"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# 2. Asset Compilation - Ensure assets compile successfully
|
|
78
|
+
if [ -f "config/application.rb" ]; then
|
|
79
|
+
# Check if we're using asset pipeline (Propshaft)
|
|
80
|
+
if grep -q "propshaft" Gemfile 2>/dev/null; then
|
|
81
|
+
# Test asset compilation in a temporary directory
|
|
82
|
+
temp_dir=$(mktemp -d)
|
|
83
|
+
export SECRET_KEY_BASE=dummy_key_for_asset_compilation
|
|
84
|
+
|
|
85
|
+
if bundle exec rails assets:precompile RAILS_ENV=development > "$temp_dir/assets.log" 2>&1; then
|
|
86
|
+
echo -e "${GREEN}✅ Assets compile successfully${NC}"
|
|
87
|
+
# Clean up precompiled assets
|
|
88
|
+
bundle exec rails assets:clobber > /dev/null 2>&1
|
|
89
|
+
else
|
|
90
|
+
echo -e "${RED}❌ Asset compilation failed${NC}"
|
|
91
|
+
echo -e "${RED}Check: cat $temp_dir/assets.log${NC}"
|
|
92
|
+
failed_checks=$((failed_checks + 1))
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Clean up
|
|
96
|
+
rm -rf "$temp_dir"
|
|
97
|
+
unset RAILS_ENV SECRET_KEY_BASE
|
|
98
|
+
else
|
|
99
|
+
echo -e "${GREEN}✅ No asset pipeline detected, skipping asset compilation check${NC}"
|
|
100
|
+
fi
|
|
101
|
+
else
|
|
102
|
+
echo -e "${YELLOW}⚠️ Not a Rails application, skipping asset compilation check${NC}"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# 3. Additional checks that are good for pre-push
|
|
106
|
+
echo -e "${YELLOW}Running additional pre-push checks...${NC}"
|
|
107
|
+
|
|
108
|
+
# Check for TODO/FIXME comments in staged files (warning only)
|
|
109
|
+
todo_count=$(git diff --cached --name-only | xargs grep -i "TODO\|FIXME" 2>/dev/null | wc -l)
|
|
110
|
+
if [ "$todo_count" -gt 0 ]; then
|
|
111
|
+
echo -e "${YELLOW}⚠️ $todo_count TODO/FIXME comment(s) found in staged files${NC}"
|
|
112
|
+
else
|
|
113
|
+
echo -e "${GREEN}✅ No TODO/FIXME comments in staged files${NC}"
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# Exit with error if any critical checks failed
|
|
117
|
+
if [ $failed_checks -gt 0 ]; then
|
|
118
|
+
echo ""
|
|
119
|
+
echo -e "${RED}❌ $failed_checks critical check(s) failed. Push aborted.${NC}"
|
|
120
|
+
echo -e "${YELLOW}Fix the issues above and try pushing again.${NC}"
|
|
121
|
+
echo -e "${YELLOW}To skip these checks: git push --no-verify${NC}"
|
|
122
|
+
exit 1
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
echo ""
|
|
126
|
+
echo -e "${GREEN}🎉 All pre-push checks passed!${NC}"
|
|
127
|
+
exit 0
|