#!/usr/bin/env ruby # frozen_string_literal: true # # Setup script for trunk.io and RuboCop configuration # This script creates the necessary configuration files for trunk.io and RuboCop # based on the Standard Ruby style guide. # # Usage: ruby setup_trunk_rubocop.rb [project_root] # project_root: Path to your project root (defaults to current directory) require 'fileutils' require 'pathname' # Get project root from argument or use current directory project_root = Pathname.new(ARGV[0] || Dir.pwd).expand_path puts "Setting up trunk.io and RuboCop configuration..." puts "Project root: #{project_root}" # Create .trunk directory if it doesn't exist trunk_dir = project_root.join('.trunk') FileUtils.mkdir_p(trunk_dir) # Create .trunk/configs directory for isolated configuration trunk_configs_dir = trunk_dir.join('configs') FileUtils.mkdir_p(trunk_configs_dir) # Create .github/workflows directory if it doesn't exist github_workflows_dir = project_root.join('.github', 'workflows') FileUtils.mkdir_p(github_workflows_dir) # Write .trunk/trunk.yaml trunk_yaml_content = <<~YAML # This file controls the behavior of Trunk: https://docs.trunk.io/cli # To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml version: 0.1 cli: version: 1.25.0 # Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) plugins: sources: - id: trunk ref: v1.7.4 uri: https://github.com/trunk-io/plugins # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) runtimes: enabled: - go@1.21.0 - node@22.16.0 - python@3.10.8 - ruby@>=3.3.0 # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) lint: disabled: - brakeman - rufo - eslint - prettier - standardrb - semgrep - oxipng - svgo - trufflehog - shfmt - hadolint definitions: - name: stylelint files: [css] - name: rubocop extra_packages: - standard@1.52.0 - standard-custom@1.0.2 - standard-rails@1.5.0 - standard-performance@1.8.0 - standard-rspec@0.3.1 - rubocop-rails@2.34.2 - rubocop-rspec@3.8.0 - rubocop-thread_safety@0.7.3 ignore: - linters: [ALL] paths: - bin/** - db/schema.rb - vendor/** - tmp/** - log/** - storage/** - coverage/** - uploads/** enabled: - biome@2.3.8 - rubocop@1.81.7 - stylelint@16.26.1 - yamllint@1.37.1 - gitleaks@8.29.0 - actionlint@1.7.8 - checkov@3.2.495 - dotenv-linter@4.0.0 - git-diff-check - markdownlint@0.46.0 - osv-scanner@2.2.4 - shellcheck@0.11.0 - trivy@0.67.2 actions: disabled: - trunk-announce - trunk-check-pre-push - trunk-fmt-pre-commit enabled: - trunk-upgrade-available YAML trunk_yaml_path = trunk_dir.join('trunk.yaml') if trunk_yaml_path.exist? print "File #{trunk_yaml_path} already exists. Overwrite? (y/N): " response = $stdin.gets.chomp.downcase unless response == 'y' || response == 'yes' puts "Skipping #{trunk_yaml_path}" else File.write(trunk_yaml_path, trunk_yaml_content) puts "✓ Created #{trunk_yaml_path}" end else File.write(trunk_yaml_path, trunk_yaml_content) puts "✓ Created #{trunk_yaml_path}" end # Write .trunk/configs/.rubocop.yml (for complete isolation) # You can also place this in project root as .rubocop.yml if preferred rubocop_yml_content = <<~YAML inherit_mode: merge: - Exclude require: - standard plugins: - standard-custom - standard-performance - rubocop-performance - rubocop-rails - rubocop-rspec - rubocop-thread_safety inherit_gem: standard: config/base.yml standard-performance: config/base.yml standard-custom: config/base.yml standard-rails: config/base.yml AllCops: SuggestExtensions: false TargetRubyVersion: 3.4 NewCops: enable Exclude: - bin/**/* - db/**/* - vendor/**/* - tmp/**/* - log/**/* - storage/**/* - coverage/**/* - uploads/**/* - .git/**/* - node_modules/**/* - public/packs/**/* - public/packs-test/**/* # RSpec-specific configuration RSpec/ExampleLength: Max: 50 RSpec/SpecFilePathFormat: Enabled: false Exclude: - spec/**/* RSpec/HooksBeforeExamples: Enabled: false RSpec/MultipleMemoizedHelpers: Max: 16 RSpec/NestedGroups: Max: 4 # Custom cop overrides Style/AccessModifierDeclarations: EnforcedStyle: inline Rails/ActiveRecordCallbacksOrder: Enabled: false Style/FrozenStringLiteralComment: Enabled: false Lint/UselessAssignment: Enabled: false Rails/Exit: Exclude: - usr/**/* ThreadSafety/ClassAndModuleAttributes: Enabled: false ThreadSafety/ClassInstanceVariable: Enabled: false ThreadSafety/DirChdir: Exclude: - "*.gemspec" # Strict cops that should never be disabled Lint/Debugger: Enabled: true Exclude: [] RSpec/Focus: Enabled: true Exclude: [] Rails/Output: Enabled: true Exclude: - usr/**/* Rails/FindEach: Enabled: true Exclude: [] Rails/UniqBeforePluck: Enabled: true Exclude: [] YAML rubocop_yml_path = trunk_configs_dir.join('.rubocop.yml') if rubocop_yml_path.exist? print "File #{rubocop_yml_path} already exists. Overwrite? (y/N): " response = $stdin.gets.chomp.downcase unless response == 'y' || response == 'yes' puts "Skipping #{rubocop_yml_path}" else File.write(rubocop_yml_path, rubocop_yml_content) puts "✓ Created #{rubocop_yml_path}" end else File.write(rubocop_yml_path, rubocop_yml_content) puts "✓ Created #{rubocop_yml_path}" end # Write GitHub Actions workflow github_workflow_content = <<~YAML name: _trunk_check on: [pull_request] concurrency: group: ${{ github.head_ref || github.run_id }} cancel-in-progress: true permissions: read-all jobs: run_trunk_action: runs-on: ubuntu-latest permissions: checks: write contents: read steps: - uses: actions/checkout@v6 - uses: ruby/setup-ruby@v1 with: bundler-cache: true - uses: trunk-io/trunk-action@v1 YAML github_workflow_path = github_workflows_dir.join('_trunk_check.yml') if github_workflow_path.exist? print "File #{github_workflow_path} already exists. Overwrite? (y/N): " response = $stdin.gets.chomp.downcase unless response == 'y' || response == 'yes' puts "Skipping #{github_workflow_path}" else File.write(github_workflow_path, github_workflow_content) puts "✓ Created #{github_workflow_path}" end else File.write(github_workflow_path, github_workflow_content) puts "✓ Created #{github_workflow_path}" end puts "\n✓ Setup complete!" puts "\nNext steps:" puts " 1. Run: trunk check" puts " 2. Run: trunk upgrade" puts "\nNote: With trunk.io's full isolation, you don't need to add RuboCop gems" puts " to your Gemfile. trunk.io manages all linter dependencies in its" puts " own isolated environment." puts "\nFor more information, see: https://docs.trunk.io/cli"