├── .gem_release.yml ├── .git-blame-ignore-revs ├── .github ├── stale.yml └── workflows │ ├── lint.yml │ └── test.yml ├── .github_changelog_generator ├── .gitignore ├── .mergify.yml ├── .rspec ├── .rubocop.yml ├── .standard.yml ├── CHANGELOG.md ├── Gemfile ├── LICENSE.txt ├── OLD_CHANGELOG.md ├── README.md ├── Rakefile ├── bin ├── console ├── rake ├── setup └── solidus ├── exe └── solidus ├── lib ├── solidus_dev_support.rb └── solidus_dev_support │ ├── extension.rb │ ├── rake_tasks.rb │ ├── rspec │ ├── capybara.rb │ ├── coverage.rb │ ├── feature_helper.rb │ ├── rails_helper.rb │ └── spec_helper.rb │ ├── rubocop.rb │ ├── rubocop │ └── config.yml │ ├── solidus_command.rb │ ├── templates │ └── extension │ │ ├── .circleci │ │ └── config.yml │ │ ├── .github │ │ ├── stale.yml │ │ └── workflows │ │ │ ├── lint.yml │ │ │ └── test.yml │ │ ├── CHANGELOG.md.tt │ │ ├── CONTRIBUTING.md │ │ ├── Gemfile.tt │ │ ├── LICENSE │ │ ├── README.md │ │ ├── Rakefile │ │ ├── app │ │ └── assets │ │ │ ├── javascripts │ │ │ └── spree │ │ │ │ ├── backend │ │ │ │ └── %file_name%.js │ │ │ │ └── frontend │ │ │ │ └── %file_name%.js │ │ │ └── stylesheets │ │ │ └── spree │ │ │ ├── backend │ │ │ └── %file_name%.css │ │ │ └── frontend │ │ │ └── %file_name%.css │ │ ├── bin │ │ ├── console.tt │ │ ├── rails │ │ ├── rails-engine.tt │ │ ├── rails-sandbox │ │ ├── rake │ │ ├── sandbox.tt │ │ └── setup │ │ ├── config │ │ ├── locales │ │ │ └── en.yml │ │ └── routes.rb │ │ ├── extension.gemspec.tt │ │ ├── gem_release.yml.tt │ │ ├── github_changelog_generator │ │ ├── gitignore │ │ ├── lib │ │ ├── %file_name%.rb.tt │ │ ├── %file_name% │ │ │ ├── configuration.rb.tt │ │ │ ├── engine.rb.tt │ │ │ ├── testing_support │ │ │ │ └── factories.rb.tt │ │ │ └── version.rb.tt │ │ └── generators │ │ │ └── %file_name% │ │ │ └── install │ │ │ ├── install_generator.rb.tt │ │ │ └── templates │ │ │ └── initializer.rb.tt │ │ ├── rspec │ │ ├── rubocop.yml │ │ └── spec │ │ └── spec_helper.rb.tt │ ├── testing_support │ ├── factories.rb │ └── preferences.rb │ └── version.rb ├── solidus_dev_support.gemspec └── spec ├── features └── create_extension_spec.rb ├── lib └── extension_spec.rb └── spec_helper.rb /.gem_release.yml: -------------------------------------------------------------------------------- 1 | bump: 2 | recurse: false 3 | file: 'lib/solidus_dev_support/version.rb' 4 | message: Bump SolidusDevSupport to %{version} 5 | tag: true 6 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # .git-blame-ignore-revs 2 | # Convert to standardrb 3 | e466db2b9cf9ae6f8b905bedb758228204ee80ab 4 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: [pull_request] 4 | 5 | concurrency: 6 | group: lint-${{ github.ref_name }} 7 | cancel-in-progress: ${{ github.ref_name != 'main' }} 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | ruby: 14 | name: Check Ruby 15 | runs-on: ubuntu-24.04 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v3 19 | - name: Install Ruby and gems 20 | uses: ruby/setup-ruby@v1 21 | with: 22 | ruby-version: "3.2" 23 | bundler-cache: true 24 | - name: Lint Ruby files 25 | run: bundle exec rubocop -ESP 26 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | schedule: 9 | - cron: "0 0 * * 4" # every Thursday 10 | 11 | concurrency: 12 | group: test-${{ github.ref_name }} 13 | cancel-in-progress: ${{ github.ref_name != 'main' }} 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | rspec: 20 | name: Solidus ${{ matrix.solidus-branch }}, Rails ${{ matrix.rails-version }} and Ruby ${{ matrix.ruby-version }} on ${{ matrix.database }} 21 | runs-on: ubuntu-24.04 22 | strategy: 23 | fail-fast: true 24 | matrix: 25 | rails-version: 26 | - "7.1" 27 | - "7.2" 28 | - "8.0" 29 | ruby-version: 30 | - "3.1" 31 | - "3.4" 32 | solidus-branch: 33 | - "v4.3" 34 | - "v4.4" 35 | - "v4.5" 36 | - "main" 37 | database: 38 | - "postgresql" 39 | - "mysql" 40 | - "sqlite" 41 | exclude: 42 | - rails-version: "7.2" 43 | solidus-branch: "v4.3" 44 | - ruby-version: "3.1" 45 | rails-version: "8.0" 46 | - solidus-branch: "v4.3" 47 | rails-version: "8.0" 48 | - solidus-branch: "v4.4" 49 | rails-version: "8.0" 50 | steps: 51 | - uses: actions/checkout@v4 52 | - name: Run extension tests 53 | uses: solidusio/test-solidus-extension@main 54 | with: 55 | database: ${{ matrix.database }} 56 | rails-version: ${{ matrix.rails-version }} 57 | ruby-version: ${{ matrix.ruby-version }} 58 | solidus-branch: ${{ matrix.solidus-branch }} 59 | - name: Upload coverage reports to Codecov 60 | uses: codecov/codecov-action@v5 61 | continue-on-error: true 62 | with: 63 | token: ${{ secrets.CODECOV_TOKEN }} 64 | files: ./coverage/coverage.xml 65 | -------------------------------------------------------------------------------- /.github_changelog_generator: -------------------------------------------------------------------------------- 1 | issues=false 2 | exclude-labels=infrastructure 3 | since-tag=v1.4.0 4 | base=OLD_CHANGELOG.md 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | /vendor/bundle/ 10 | /Gemfile.lock 11 | /Gemfile-local* 12 | 13 | # rspec failure tracking 14 | .rspec_status 15 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: request changelog labels when a PR is missing them 3 | conditions: 4 | - base=main 5 | - -label=bug 6 | - -label=enhancement 7 | - -label=documentation 8 | - -label=security 9 | - -label=removed 10 | - -label=infrastructure 11 | actions: 12 | label: 13 | add: 14 | - needs changelog label 15 | comment: 16 | message: | 17 | It looks like this PR is missing a label to determine the type of change it introduces. The maintainer should add one of the following labels: 18 | 19 | - `bug` for bugfixes. 20 | - `enhancement` for new features and improvements. 21 | - `documentation` for documentation changes. 22 | - `security` for security patches. 23 | - `removed` for feature removals. 24 | - `infrastructure` for internal changes that should not go in the changelog. 25 | 26 | Additionally, the maintainer may also want to add one of the following: 27 | 28 | - `breaking` for breaking changes. 29 | - `deprecated` for feature deprecations. 30 | 31 | Once the correct labels have been set, simply remove the `needs changelog label` label from this PR so I can merge it. 32 | - name: merge PRs automatically 33 | conditions: 34 | - base=main 35 | - -label="needs changelog label" 36 | - -label=blocked 37 | - "#approved-reviews-by>=1" 38 | - -draft 39 | actions: 40 | merge: 41 | method: merge 42 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - standard 3 | 4 | inherit_gem: 5 | standard: config/base.yml 6 | 7 | AllCops: 8 | TargetRubyVersion: 3.0 9 | -------------------------------------------------------------------------------- /.standard.yml: -------------------------------------------------------------------------------- 1 | parallel: true # default: false 2 | format: progress # default: Standard::Formatter 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | See https://github.com/solidusio/solidus_dev_support/releases or OLD_CHANGELOG.md for older versions. 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } 6 | 7 | # Specify your gem's dependencies in solidus_dev_support.gemspec 8 | gemspec 9 | 10 | branch = ENV.fetch("SOLIDUS_BRANCH", "main") 11 | gem "solidus", github: "solidusio/solidus", branch: branch 12 | 13 | rails_version = ENV.fetch("RAILS_VERSION", "7.0") 14 | gem "rails", "~> #{rails_version}" 15 | 16 | gem "bundler" 17 | gem "rake" 18 | 19 | # These gems will be used by the temporary extensions generated by tests 20 | group :test do 21 | gem "mysql2" 22 | gem "pg" 23 | gem "solidus_auth_devise" 24 | gem "sqlite3", (rails_version < "7.2") ? "~> 1.4" : "~> 2.0" 25 | end 26 | 27 | # Use a local Gemfile to include development dependencies that might not be 28 | # relevant for the project or for other contributors, e.g.: `gem 'pry-debug'`. 29 | eval_gemfile "Gemfile-local" if File.exist? "Gemfile-local" 30 | 31 | if rails_version == "7.0" 32 | gem "concurrent-ruby", "< 1.3.5" 33 | end 34 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Nebulab Srls 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /OLD_CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.5.6](https://github.com/solidusio/solidus_dev_support/tree/2.5.6) (2023-04-24) 4 | 5 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.5.5...2.5.6) 6 | 7 | **Implemented enhancements:** 8 | 9 | - Allow Solidus 4 [\#203](https://github.com/solidusio/solidus_dev_support/pull/203) ([elia](https://github.com/elia)) 10 | - Update proposed defaults [\#191](https://github.com/solidusio/solidus_dev_support/pull/191) ([elia](https://github.com/elia)) 11 | 12 | **Fixed bugs:** 13 | 14 | - Fix sandbox default solidus branch [\#192](https://github.com/solidusio/solidus_dev_support/pull/192) ([RyanofWoods](https://github.com/RyanofWoods)) 15 | 16 | **Merged pull requests:** 17 | 18 | - Remove Slack notifications for CI failures [\#199](https://github.com/solidusio/solidus_dev_support/pull/199) ([waiting-for-dev](https://github.com/waiting-for-dev)) 19 | 20 | ## [v2.5.5](https://github.com/solidusio/solidus_dev_support/tree/v2.5.5) (2022-09-08) 21 | 22 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.5.4...v2.5.5) 23 | 24 | **Implemented enhancements:** 25 | 26 | - Configure solidus\_chrome\_headless as capybara-screenshot driver [\#190](https://github.com/solidusio/solidus_dev_support/pull/190) ([tvdeyen](https://github.com/tvdeyen)) 27 | - Misc: auth-devise, extracted frontend gem, sqlite [\#188](https://github.com/solidusio/solidus_dev_support/pull/188) ([elia](https://github.com/elia)) 28 | 29 | **Fixed bugs:** 30 | 31 | - Revert temporary fix for Octokit [\#186](https://github.com/solidusio/solidus_dev_support/pull/186) ([waiting-for-dev](https://github.com/waiting-for-dev)) 32 | 33 | ## [v2.5.4](https://github.com/solidusio/solidus_dev_support/tree/v2.5.4) (2022-05-31) 34 | 35 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.5.2...v2.5.4) 36 | 37 | **Fixed bugs:** 38 | 39 | - Add a missing require for octokit/repository [\#185](https://github.com/solidusio/solidus_dev_support/pull/185) ([elia](https://github.com/elia)) 40 | - Fix window resizing of `solidus_chrome_headless` driver [\#184](https://github.com/solidusio/solidus_dev_support/pull/184) ([gsmendoza](https://github.com/gsmendoza)) 41 | 42 | ## [v2.5.2](https://github.com/solidusio/solidus_dev_support/tree/v2.5.2) (2021-11-23) 43 | 44 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.5.1...v2.5.2) 45 | 46 | **Merged pull requests:** 47 | 48 | - Loosen webdrivers constraint in solidus\_dev\_support [\#180](https://github.com/solidusio/solidus_dev_support/pull/180) ([gsmendoza](https://github.com/gsmendoza)) 49 | 50 | ## [v2.5.1](https://github.com/solidusio/solidus_dev_support/tree/v2.5.1) (2021-08-31) 51 | 52 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.5.0...v2.5.1) 53 | 54 | ## [v2.5.0](https://github.com/solidusio/solidus_dev_support/tree/v2.5.0) (2021-04-20) 55 | 56 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.4.3...v2.5.0) 57 | 58 | **Implemented enhancements:** 59 | 60 | - Allow Solidus 3 [\#176](https://github.com/solidusio/solidus_dev_support/pull/176) ([kennyadsl](https://github.com/kennyadsl)) 61 | - Relax Ruby version requirement [\#174](https://github.com/solidusio/solidus_dev_support/pull/174) ([gauravtiwari](https://github.com/gauravtiwari)) 62 | 63 | ## [v2.4.3](https://github.com/solidusio/solidus_dev_support/tree/v2.4.3) (2021-02-23) 64 | 65 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.4.2...v2.4.3) 66 | 67 | **Implemented enhancements:** 68 | 69 | - Add instruction on how to use the new factories in apps [\#172](https://github.com/solidusio/solidus_dev_support/pull/172) ([kennyadsl](https://github.com/kennyadsl)) 70 | 71 | **Fixed bugs:** 72 | 73 | - Explode directories into individual files [\#171](https://github.com/solidusio/solidus_dev_support/pull/171) ([kennyadsl](https://github.com/kennyadsl)) 74 | - Fix factories loading, part 2 [\#170](https://github.com/solidusio/solidus_dev_support/pull/170) ([kennyadsl](https://github.com/kennyadsl)) 75 | 76 | ## [v2.4.2](https://github.com/solidusio/solidus_dev_support/tree/v2.4.2) (2021-02-19) 77 | 78 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.4.1...v2.4.2) 79 | 80 | ## [v2.4.1](https://github.com/solidusio/solidus_dev_support/tree/v2.4.1) (2021-02-19) 81 | 82 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.4.0...v2.4.1) 83 | 84 | **Fixed bugs:** 85 | 86 | - Fix loading factories in extensions after the last changes in Solidus [\#169](https://github.com/solidusio/solidus_dev_support/pull/169) ([kennyadsl](https://github.com/kennyadsl)) 87 | 88 | ## [v2.4.0](https://github.com/solidusio/solidus_dev_support/tree/v2.4.0) (2021-02-05) 89 | 90 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.3.0...v2.4.0) 91 | 92 | **Implemented enhancements:** 93 | 94 | - Improve engine's requires to remove double inclusions [\#165](https://github.com/solidusio/solidus_dev_support/pull/165) ([kennyadsl](https://github.com/kennyadsl)) 95 | - Remove double require of core factories from rails\_helper [\#164](https://github.com/solidusio/solidus_dev_support/pull/164) ([kennyadsl](https://github.com/kennyadsl)) 96 | 97 | **Fixed bugs:** 98 | 99 | - Fix typo in configuration.rb.tt [\#166](https://github.com/solidusio/solidus_dev_support/pull/166) ([brchristian](https://github.com/brchristian)) 100 | 101 | **Merged pull requests:** 102 | 103 | - Rename spree:install to solidus:install in the sandbox template [\#167](https://github.com/solidusio/solidus_dev_support/pull/167) ([blocknotes](https://github.com/blocknotes)) 104 | 105 | ## [v2.3.0](https://github.com/solidusio/solidus_dev_support/tree/v2.3.0) (2021-01-14) 106 | 107 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.2.0...v2.3.0) 108 | 109 | **Implemented enhancements:** 110 | 111 | - Do not raise if source\_code\_uri is missing in the gemspec [\#163](https://github.com/solidusio/solidus_dev_support/pull/163) ([kennyadsl](https://github.com/kennyadsl)) 112 | - Factory bot fixes for latest Solidus 2.11 release [\#162](https://github.com/solidusio/solidus_dev_support/pull/162) ([elia](https://github.com/elia)) 113 | 114 | **Fixed bugs:** 115 | 116 | - use rubocop-rspec 2.x [\#161](https://github.com/solidusio/solidus_dev_support/pull/161) ([ccarruitero](https://github.com/ccarruitero)) 117 | 118 | ## [v2.2.0](https://github.com/solidusio/solidus_dev_support/tree/v2.2.0) (2020-11-27) 119 | 120 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.1.0...v2.2.0) 121 | 122 | **Implemented enhancements:** 123 | 124 | - Improve the URL generation for the gemspec and Readme \(defaulting to the solidusio-contrib organization\), consistently use a file-based Changelog [\#159](https://github.com/solidusio/solidus_dev_support/pull/159) ([elia](https://github.com/elia)) 125 | - Configuration Cleanup [\#158](https://github.com/solidusio/solidus_dev_support/pull/158) ([elia](https://github.com/elia)) 126 | - Refer to Solidus wiki page for gem release info [\#157](https://github.com/solidusio/solidus_dev_support/pull/157) ([spaghetticode](https://github.com/spaghetticode)) 127 | - Upgrade to RuboCop 1.0 [\#156](https://github.com/solidusio/solidus_dev_support/pull/156) ([aldesantis](https://github.com/aldesantis)) 128 | - Add a command to display gem's version [\#154](https://github.com/solidusio/solidus_dev_support/pull/154) ([igorbp](https://github.com/igorbp)) 129 | 130 | **Fixed bugs:** 131 | 132 | - Require "webdrivers" before using it as the default javascript driver [\#152](https://github.com/solidusio/solidus_dev_support/pull/152) ([ccarruitero](https://github.com/ccarruitero)) 133 | 134 | **Merged pull requests:** 135 | 136 | - Don't let mergify mark a PR as red because it's missing a review [\#153](https://github.com/solidusio/solidus_dev_support/pull/153) ([elia](https://github.com/elia)) 137 | 138 | ## [v2.1.0](https://github.com/solidusio/solidus_dev_support/tree/v2.1.0) (2020-10-02) 139 | 140 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.0.1...v2.1.0) 141 | 142 | **Implemented enhancements:** 143 | 144 | - Add standard github\_changelog\_generator configuration [\#151](https://github.com/solidusio/solidus_dev_support/pull/151) ([aldesantis](https://github.com/aldesantis)) 145 | - Move generated factories to `testing_support/` [\#150](https://github.com/solidusio/solidus_dev_support/pull/150) ([aldesantis](https://github.com/aldesantis)) 146 | - Add extension configuration boilerplate [\#149](https://github.com/solidusio/solidus_dev_support/pull/149) ([aldesantis](https://github.com/aldesantis)) 147 | 148 | **Fixed bugs:** 149 | 150 | - Fix `NewCops: Enable` option for RuboCop [\#148](https://github.com/solidusio/solidus_dev_support/pull/148) ([aldesantis](https://github.com/aldesantis)) 151 | 152 | ## [v2.0.1](https://github.com/solidusio/solidus_dev_support/tree/v2.0.1) (2020-09-22) 153 | 154 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v2.0.0...v2.0.1) 155 | 156 | **Fixed bugs:** 157 | 158 | - Fix gem\_version not being found during extension generation [\#144](https://github.com/solidusio/solidus_dev_support/pull/144) ([aldesantis](https://github.com/aldesantis)) 159 | 160 | ## [v2.0.0](https://github.com/solidusio/solidus_dev_support/tree/v2.0.0) (2020-09-22) 161 | 162 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v1.6.0...v2.0.0) 163 | 164 | **Breaking changes:** 165 | 166 | - Switch the JS driver to WebDriver/Selenium [\#136](https://github.com/solidusio/solidus_dev_support/pull/136) ([elia](https://github.com/elia)) 167 | 168 | **Implemented enhancements:** 169 | 170 | - Enable new RuboCop cops automatically [\#143](https://github.com/solidusio/solidus_dev_support/pull/143) ([aldesantis](https://github.com/aldesantis)) 171 | - Don't forcefully close issues via stale-bot [\#139](https://github.com/solidusio/solidus_dev_support/pull/139) ([elia](https://github.com/elia)) 172 | - Add the approximate recommendation for dev-support to the gemspec [\#137](https://github.com/solidusio/solidus_dev_support/pull/137) ([elia](https://github.com/elia)) 173 | 174 | **Fixed bugs:** 175 | 176 | - fix capybara driver declaration [\#141](https://github.com/solidusio/solidus_dev_support/pull/141) ([ccarruitero](https://github.com/ccarruitero)) 177 | - Bump RuboCop to latest 0.90.0 version [\#138](https://github.com/solidusio/solidus_dev_support/pull/138) ([peterberkenbosch](https://github.com/peterberkenbosch)) 178 | - Fix missing backslash in solidus install command [\#135](https://github.com/solidusio/solidus_dev_support/pull/135) ([nirebu](https://github.com/nirebu)) 179 | 180 | ## [v1.6.0](https://github.com/solidusio/solidus_dev_support/tree/v1.6.0) (2020-08-26) 181 | 182 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v1.5.0...v1.6.0) 183 | 184 | **Implemented enhancements:** 185 | 186 | - Let the extension name include spaces [\#133](https://github.com/solidusio/solidus_dev_support/pull/133) ([elia](https://github.com/elia)) 187 | - Add precompiled badges fro CI and coverage [\#132](https://github.com/solidusio/solidus_dev_support/pull/132) ([elia](https://github.com/elia)) 188 | - Add Changelog Rake task [\#128](https://github.com/solidusio/solidus_dev_support/pull/128) ([tvdeyen](https://github.com/tvdeyen)) 189 | - Readme fixes [\#122](https://github.com/solidusio/solidus_dev_support/pull/122) ([elia](https://github.com/elia)) 190 | 191 | **Fixed bugs:** 192 | 193 | - Don't install a payment-method in the sandbox [\#131](https://github.com/solidusio/solidus_dev_support/pull/131) ([elia](https://github.com/elia)) 194 | - Run extension generator in sandbox [\#127](https://github.com/solidusio/solidus_dev_support/pull/127) ([elia](https://github.com/elia)) 195 | 196 | ## [v1.5.0](https://github.com/solidusio/solidus_dev_support/tree/v1.5.0) (2020-06-13) 197 | 198 | [Full Changelog](https://github.com/solidusio/solidus_dev_support/compare/v1.4.0...v1.5.0) 199 | 200 | **Fixed bugs:** 201 | 202 | - Fix formatting typo in readme [\#117](https://github.com/solidusio/solidus_dev_support/pull/117) ([aldesantis](https://github.com/aldesantis)) 203 | 204 | **Removed:** 205 | 206 | - Remove deprecated bin/r and bin/sandbox\_rails binaries [\#118](https://github.com/solidusio/solidus_dev_support/pull/118) ([aldesantis](https://github.com/aldesantis)) 207 | 208 | ## [1.4.0] - 2020-06-05 209 | 210 | ### Added 211 | 212 | - Added a "Usage" section to the default readme 213 | 214 | ### Changed 215 | 216 | - Restored `bin/rails` and renamed the context specific bins to `bin/rails-engine` and `bin/rails-sandbox` 217 | - Adjusted the readme structure with better formatting and grammar 218 | - Moved the RuboCop `AllCops/Exclude` statement back to the internal configuration 219 | 220 | ### Deprecated 221 | 222 | - Deprecated `bin/r` in favor of `bin/rails-engine` and `bin/sandbox_rails` in favor of `bin/rails-sandbox` 223 | 224 | ## [1.3.0] - 2020-05-22 225 | 226 | ### Added 227 | 228 | - Ignored `.rvmrc`, `.ruby-version` and `.ruby-gemset` by default in extensions 229 | - Added deprecation warning when extensions don't support Zeitwerk 230 | 231 | ### Changed 232 | 233 | - Updated the extension template to use latest (0.5.X) solidus_support 234 | - Set Ruby 2.5+ as the minimum Ruby version in generated extensions 235 | 236 | ### Removed 237 | 238 | - Removed Stale from the default extension configuration 239 | 240 | ## [1.2.0] - 2020-04-24 241 | 242 | ### Changed 243 | 244 | - Updated the extension template with the latest modifications 245 | 246 | ## [1.1.0] - 2020-03-06 247 | 248 | ### Added 249 | 250 | - Made Git ignore `sandbox` in generated extensions 251 | - Added support for specifying `SOLIDUS_BRANCH` in the sandbox 252 | 253 | ### Changed 254 | 255 | - Split `bin/rails` into `bin/r` and `bin/sandbox_rails` 256 | 257 | 258 | ### Fixed 259 | 260 | - Fixed the sandbox Gemfile not including Solidus 261 | 262 | ## [1.0.1] - 2020-02-17 263 | 264 | ### Fixed 265 | 266 | - Fixed missing factory definitions when using `modify` on Solidus factories 267 | 268 | ## [1.0.0] - 2020-02-07 269 | 270 | ### Added 271 | 272 | - Added a binstub for `rake` to the extension generator 273 | - Added the ability for the generator to reuse existing data for the gemspec 274 | 275 | ### Fixed 276 | 277 | - Fixed Dependabot throwing an error because of `eval_gemfile` in the Gemfile 278 | 279 | ## [0.6.0] - 2020-01-20 280 | 281 | ### Added 282 | 283 | - Added support for a local Gemfile for local development dependencies (e.g. 'pry-debug') 284 | - Added a `bin/sandbox` script to all extension for local development with `bin/rails` support. 285 | 286 | ### Changed 287 | 288 | - The default rake task no longer re-generates the `test_app` each time it runs. 289 | In order to get that behavior back simply call clobber before launching it: 290 | `bin/rake clobber default` 291 | 292 | ### Fixed 293 | 294 | - Fixed generated extensions isolating the wrong namespace 295 | 296 | ## [0.5.0] - 2020-01-16 297 | 298 | ### Added 299 | 300 | - Added `--require spec_helper` to the generated `.rspec` 301 | 302 | ### Fixed 303 | 304 | - Replaced "Spree" with "Solidus" in the license of generated extensions 305 | 306 | ### Changed 307 | 308 | - Updated gem-release to use tags instead of branches for new releases 309 | 310 | ## [0.4.1] - 2020-01-15 311 | 312 | ### Fixed 313 | 314 | - Fixed the generated RuboCop config inheriting from this gem's dev-only config 315 | - Fixed the generated extension not requiring the `version` file 316 | - Fixed the generator not properly marking `bin/` files as executable 317 | 318 | ## [0.4.0] - 2020-01-10 319 | 320 | ### Added 321 | 322 | - Enforced Rails version depending on the Solidus version in generated Gemfile 323 | - Made Git ignore `spec/examples.txt` in generated extensions 324 | - Added the ability to run `solidus extension .` to update an extension 325 | 326 | ### Changed 327 | 328 | - The `solidus` executable is now solely managed by Thor and is open to extension by other gems 329 | 330 | ### Fixed 331 | 332 | - Fixed generated extensions using an old Rakefile 333 | - Fixed some RuboCop offenses in the generated files 334 | - Fixed the `bin/setup` script calling a non-existing Rake binary 335 | 336 | ### Removed 337 | 338 | - Removed RuboCop from the default Rake task 339 | - Removed the `-v` option from the `solidus` executable 340 | - Removed the factory_bot gem from the Gemfile 341 | 342 | ## [0.3.0] - 2020-01-10 343 | 344 | ### Added 345 | 346 | - Adopted Ruby 2.4+ as the minimum Ruby version in generated extensions 347 | - Added `bin/console`, `bin/rails` and `bin/setup` to generated extensions 348 | - Added some Bundler gemspec defaults to generated extensions 349 | - Configured the default Rake task to run generate the test app before running RSpec 350 | 351 | ### Changed 352 | 353 | - Updated solidus_support to 0.4.0 for Zeitwerk and Rails 6 compatibility 354 | - Updated the `solidus` executable to only rely on Thor and be open to extension by other gems 355 | 356 | ### Removed 357 | 358 | - Removed solidus_support as a dependency 359 | 360 | ### Fixed 361 | 362 | - Fixed `extension:test_app` not going back to the root after execution 363 | 364 | ## [0.2.0] - 2019-12-16 365 | 366 | ### Added 367 | 368 | - Adopted [Apparition](https://github.com/twalpole/apparition) as the deafult JS driver for Capybara 369 | - Fixed window size to 1920x1080px in feature specs 370 | - Added [Stale](https://github.com/apps/stale) to automatically mark GitHub issues as stale 371 | 372 | ### Changed 373 | 374 | - Disabled all `Metrics` cops except for `LineLength` 375 | - Set `Layout/AlignArguments` cop to `with_fixed_indentation` 376 | - Disabled `Layout/MultilineOperationIndentation` cop 377 | - Renamed the project to SolidusDevSupport (was SolidusExtensionDevTools) 378 | 379 | ### Fixed 380 | 381 | - Fixed Chrome not starting in headless mode 382 | 383 | ## [0.1.1] - 2019-11-11 384 | 385 | ### Fixed 386 | 387 | - Fixed `rails_helper` not working due to `SolidusDevSupport` not being available 388 | 389 | ## [0.1.0] - 2019-11-11 390 | 391 | Initial release. 392 | 393 | [Unreleased]: https://github.com/solidusio/solidus_dev_support/compare/v1.4.0...HEAD 394 | [1.4.0]: https://github.com/solidusio/solidus_dev_support/compare/v1.3.0...v1.4.0 395 | [1.3.0]: https://github.com/solidusio/solidus_dev_support/compare/v1.2.0...v1.3.0 396 | [1.2.0]: https://github.com/solidusio/solidus_dev_support/compare/v1.1.0...v1.2.0 397 | [1.1.0]: https://github.com/solidusio/solidus_dev_support/compare/v1.0.1...v1.1.0 398 | [1.0.1]: https://github.com/solidusio/solidus_dev_support/compare/v1.0.0...v1.0.1 399 | [1.0.0]: https://github.com/solidusio/solidus_dev_support/compare/v0.6.0...v1.0.0 400 | [0.6.0]: https://github.com/solidusio/solidus_dev_support/compare/v0.5.0...v0.6.0 401 | [0.5.0]: https://github.com/solidusio/solidus_dev_support/compare/v0.4.1...v0.5.0 402 | [0.4.1]: https://github.com/solidusio/solidus_dev_support/compare/v0.4.0...v0.4.1 403 | [0.4.0]: https://github.com/solidusio/solidus_dev_support/compare/v0.3.0...v0.4.0 404 | [0.3.0]: https://github.com/solidusio/solidus_dev_support/compare/v0.2.0...v0.3.0 405 | [0.2.0]: https://github.com/solidusio/solidus_dev_support/compare/v0.1.1...v0.2.0 406 | [0.1.1]: https://github.com/solidusio/solidus_dev_support/compare/v0.1.0...v0.1.1 407 | [0.1.0]: https://github.com/solidusio/solidus_dev_support/releases/tag/v0.1.0 408 | 409 | 410 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 411 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # solidus_dev_support 2 | 3 | 4 | [![Test](https://github.com/solidusio/solidus_dev_support/actions/workflows/test.yml/badge.svg)](https://github.com/solidusio/solidus_dev_support/actions/workflows/test.yml) 5 | [![codecov](https://codecov.io/gh/solidusio/solidus_dev_support/branch/main/graph/badge.svg)](https://codecov.io/gh/solidusio/solidus_dev_support) 6 | 7 | This gem contains common development functionality for Solidus extensions. 8 | 9 | If you're looking for runtime tools instead, look at 10 | [solidus_support](https://github.com/solidusio/solidus_support). 11 | 12 | ## Installation 13 | 14 | Add this gem as a development dependency of your extension: 15 | 16 | ```ruby 17 | spec.add_development_dependency 'solidus_dev_support' 18 | ``` 19 | 20 | And then execute: 21 | 22 | ```console 23 | $ bundle 24 | ``` 25 | 26 | ## Usage 27 | 28 | ### Extension generator 29 | 30 | This gem provides a generator for Solidus extensions. To use it, simply run: 31 | 32 | ```console 33 | $ solidus extension my_awesome_extension 34 | ``` 35 | 36 | This will generate the basic extension structure, already configured to use all the shiny helpers 37 | in solidus_dev_support. 38 | 39 | #### Updating existing extensions 40 | 41 | If you have an existing extension generated with `solidus_dev_support` and want to update it to use 42 | the latest standards from this gem, you can run the following in the extension's directory: 43 | 44 | ```console 45 | $ bundle exec solidus extension . 46 | ``` 47 | 48 | In case of conflicting files, you will be prompted for an action. You can overwrite the files with 49 | the new version, keep the current version or view the diff and only apply the adjustments that make 50 | sense to you. 51 | 52 | ### Sandbox app 53 | 54 | When developing an extension you will surely need to try it out within a Rails app with Solidus 55 | installed. Using solidus_dev_support your extension will have a `bin/rails-sandbox` executable that will 56 | operate on a _sandbox_ app (creating it if necessary). 57 | 58 | The path for the sandbox app is `./sandbox` and `bin/rails-sandbox` will forward any Rails command 59 | to `sandbox/bin/rails`. 60 | 61 | Example: 62 | 63 | ```bash 64 | $ bin/rails-sandbox server 65 | => Booting Puma 66 | => Rails 6.0.2.1 application starting in development 67 | * Listening on tcp://127.0.0.1:3000 68 | Use Ctrl-C to stop 69 | ``` 70 | 71 | #### Rebuilding the sandbox app 72 | 73 | To rebuild the sandbox app just remove the `./sandbox` folder or run `bin/sandbox`. 74 | You can control the DB adapter and Solidus version used with the sandbox by providing 75 | the `DB` and `SOLIDUS_BRANCH` env variables. 76 | 77 | ```bash 78 | DB=[postgres|mysql|sqlite] SOLIDUS_BRANCH= bin/sandbox 79 | ``` 80 | 81 | By default we use sqlite3 and the main branch. 82 | 83 | ### Rails generators 84 | 85 | Your extension will have a `bin/rails-engine` executable that you can use for generating models, migrations 86 | etc. It's the same as the default `rails` command in Rails engines. 87 | 88 | Example: 89 | 90 | ```bash 91 | $ bin/rails-engine generate migration AddStoreIdToProducts 92 | ``` 93 | 94 | ### The `bin/rails` shortcut 95 | 96 | For convenience a `bin/rails` executable is also provided that will run everything but generators on the sandbox application. Generators will instead be processed in the context of the extension. 97 | 98 | 99 | ### RSpec helpers 100 | 101 | This gem provides some useful helpers for RSpec to setup an extension's test environment easily. 102 | 103 | Add this to your extension's `spec/spec_helper.rb`: 104 | 105 | ```ruby 106 | require 'solidus_dev_support/rspec/feature_helper' 107 | ``` 108 | 109 | This helper loads configuration needed to run extension feature specs correctly, setting up Capybara 110 | and configuring a Rails test application to precompile assets before the first feature spec. 111 | 112 | `feature_helper` builds on top of `rails_helper`, which you can also use a standalone helper if you 113 | want: 114 | 115 | ```ruby 116 | require 'solidus_dev_support/rspec/rails_helper' 117 | ``` 118 | 119 | This will include the Rails and Solidus-related RSpec configuration, such as authorization helpers, 120 | Solidus factories, URL helpers, and other helpers to easily work with Solidus. 121 | 122 | `rails_helper`, in turn, builds on top of `spec_helper`, which is responsible for setting up a 123 | basic RSpec environment: 124 | 125 | ```ruby 126 | require 'solidus_dev_support/rspec/spec_helper' 127 | ``` 128 | 129 | ### Code coverage 130 | 131 | The gem also includes a SimpleCov configuration that will send your test coverage information 132 | directly to Codecov.io. Simply add this at the top of your `spec/spec_helper.rb`: 133 | 134 | ```ruby 135 | require 'solidus_dev_support/rspec/coverage' 136 | ``` 137 | 138 | **Note: Make sure to add this at the VERY TOP of your spec_helper, otherwise you'll get skewed 139 | coverage reports!** 140 | 141 | If your extension is in a public repo and being tested on GitHub actions, there's nothing else 142 | you need to do! If your setup is more complex, look at the 143 | [SimpleCov](https://github.com/colszowka/simplecov) 144 | and [codecov](https://about.codecov.io/language/ruby/) docs. 145 | 146 | #### Using GitHub Actions 147 | 148 | The recommended way to upload coverage reports to Codecov with GitHub Actions is to use the `solidusio/test-solidus-extension` 149 | workflow. 150 | 151 | ```yaml 152 | jobs: 153 | RSpec: 154 | env: 155 | CODECOV_COVERAGE_PATH: ./coverage/coverage.xml 156 | steps: 157 | - uses: actions/checkout@v4 158 | - name: Run extension tests 159 | uses: solidusio/test-solidus-extension@main 160 | - name: Upload coverage reports to Codecov 161 | uses: codecov/codecov-action@v5 162 | continue-on-error: true 163 | with: 164 | token: ${{ secrets.CODECOV_TOKEN }} 165 | files: ${{ env.CODECOV_COVERAGE_PATH }} 166 | ``` 167 | 168 | ### RuboCop configuration 169 | 170 | solidus_dev_support includes a default [RuboCop](https://github.com/rubocop-hq/rubocop) 171 | configuration for Solidus extensions. This configuration is based on the excellent [`standardrb`](https://github.com/standardrb/standard) gem. 172 | 173 | We strongly recommend including the RuboCop configuration in your extension. All you have to do is 174 | add this to your `.rubocop.yml`: 175 | 176 | ```yaml 177 | require: 178 | - solidus_dev_support/rubocop 179 | ``` 180 | 181 | You can now run RuboCop with: 182 | 183 | ```console 184 | $ bundle exec rubocop 185 | ``` 186 | 187 | ### Changelog generator 188 | 189 | Generating a changelog for your extension is possible by running this command: 190 | 191 | ```console 192 | $ CHANGELOG_GITHUB_TOKEN="«your-40-digit-github-token»" bundle exec github_changelog_generator github_username/github_project 193 | ``` 194 | 195 | This generates a `CHANGELOG.md`, with pretty Markdown formatting. 196 | 197 | For further instructions please read the [GitHub Changelog Generator documentation](https://github.com/github-changelog-generator/github-changelog-generator#usage). 198 | 199 | ### Release management 200 | 201 | By installing solidus_dev_support, you also get 202 | [`gem release`](https://github.com/svenfuchs/gem-release), which you can use to automatically manage 203 | releases for your gem. 204 | 205 | For instance, you can run the following to release a new minor version: 206 | 207 | ```console 208 | $ gem bump -v minor -r 209 | ``` 210 | 211 | The above command will: 212 | 213 | * bump the gem version to the next minor (you can also use `patch`, `major` or a specific version 214 | number); 215 | * commit the change and push it to `origin/main`; 216 | * create a Git tag; 217 | * push the tag to the `origin` remote; 218 | * release the new version on RubyGems. 219 | 220 | You can refer to 221 | [`gem release`'s documentation](https://github.com/svenfuchs/gem-release/blob/master/README.md) for 222 | further configuration and usage instructions. 223 | 224 | ### Rake tasks 225 | 226 | To install extension-related Rake tasks, add this to your `Rakefile`: 227 | 228 | ```rb 229 | require 'solidus_dev_support/rake_tasks' 230 | SolidusDevSupport::RakeTasks.install 231 | 232 | task default: 'extension:specs' 233 | ``` 234 | 235 | (If your extension used the legacy extension Rakefile, then you should completely replace its 236 | contents with the block above.) 237 | 238 | This will provide the following tasks: 239 | 240 | - `extension:test_app`, which generates a dummy app for your extension 241 | - `extension:specs` (default), which runs the specs for your extension 242 | 243 | If your extension requires the `test_app` to be always recreated you can do so by running: 244 | 245 | ```rb 246 | bin/rake extension:test_app extension:specs 247 | ``` 248 | 249 | ## Development 250 | 251 | After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run 252 | the tests. You can also run `bin/console` for an interactive prompt that will allow you to 253 | experiment. 254 | 255 | To install this gem onto your local machine, run `bin/rake install`. 256 | 257 | ### Releasing new versions 258 | 259 | Please use the same process suggested for extensions in the [dedicated page](https://github.com/solidusio/solidus/wiki/How-to-release-extensions) in the Solidus wiki. 260 | 261 | ## Contributing 262 | 263 | Bug reports and pull requests are welcome on GitHub at https://github.com/solidusio/solidus_dev_support. 264 | 265 | ## License 266 | 267 | The gem is available as open source under the terms of the 268 | [MIT License](https://opensource.org/licenses/MIT). 269 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rspec/core/rake_task" 5 | RSpec::Core::RakeTask.new(:spec) 6 | 7 | task default: :spec 8 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "bundler/setup" 5 | require "solidus_dev_support" 6 | 7 | # You can add fixtures and/or initialization code here to make experimenting 8 | # with your gem easier. You can also use a different console, if you like. 9 | 10 | # (If you use this, don't forget to add pry to your Gemfile!) 11 | # require "pry" 12 | # Pry.start 13 | 14 | require "irb" 15 | IRB.start(__FILE__) 16 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rake' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require "pathname" 12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 13 | Pathname.new(__FILE__).realpath) 14 | 15 | bundle_binstub = File.expand_path("../bundle", __FILE__) 16 | 17 | if File.file?(bundle_binstub) 18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ 19 | load(bundle_binstub) 20 | else 21 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. 22 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") 23 | end 24 | end 25 | 26 | require "rubygems" 27 | require "bundler/setup" 28 | 29 | load Gem.bin_path("rake", "rake") 30 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | include FileUtils # rubocop:disable Style/MixinUsage 4 | 5 | GEM_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system(*args) 8 | puts "$ #{(args.size == 1) ? args.first : args.shelljoin}" 9 | super 10 | end 11 | 12 | def system!(*args) 13 | system(*args) || abort("\n== Command #{args} failed ==") 14 | end 15 | 16 | cd GEM_ROOT 17 | 18 | puts "\n== Installing Ruby dependencies ==" 19 | system! %(gem install bundler --conservative) 20 | system! %(bundle check || bundle install) 21 | -------------------------------------------------------------------------------- /bin/solidus: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | load "#{__dir__}/../exe/solidus" 5 | -------------------------------------------------------------------------------- /exe/solidus: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "solidus_dev_support/solidus_command" 5 | 6 | SolidusDevSupport::SolidusCommand.start 7 | -------------------------------------------------------------------------------- /lib/solidus_dev_support.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "solidus_dev_support/version" 4 | 5 | module SolidusDevSupport 6 | class Error < StandardError; end 7 | 8 | class << self 9 | def reset_spree_preferences_deprecated? 10 | first_version_without_reset = Gem::Requirement.new(">= 2.9") 11 | first_version_without_reset.satisfied_by?(Spree.solidus_gem_version) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/extension.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "thor" 4 | require "pathname" 5 | 6 | require "solidus_dev_support/version" 7 | 8 | module SolidusDevSupport 9 | class Extension < Thor 10 | include Thor::Actions 11 | PREFIX = "solidus_" 12 | 13 | default_command :generate 14 | 15 | desc "generate PATH", "Generates a new Solidus extension" 16 | def generate(raw_path = ".") 17 | self.path = raw_path 18 | 19 | empty_directory path 20 | 21 | directory "app", "#{path}/app" 22 | directory "lib", "#{path}/lib" 23 | directory "bin", "#{path}/bin" 24 | directory ".circleci", "#{path}/.circleci" 25 | directory ".github", "#{path}/.github" 26 | 27 | Dir["#{path}/bin/*"].each do |bin| 28 | make_executable bin 29 | end 30 | 31 | template "CHANGELOG.md", "#{path}/CHANGELOG.md" 32 | template "extension.gemspec", "#{path}/#{file_name}.gemspec" 33 | template "Gemfile", "#{path}/Gemfile" 34 | template "gitignore", "#{path}/.gitignore" 35 | template "gem_release.yml.tt", "#{path}/.gem_release.yml" 36 | template "LICENSE", "#{path}/LICENSE" 37 | template "Rakefile", "#{path}/Rakefile" 38 | template "README.md", "#{path}/README.md" 39 | template "config/routes.rb", "#{path}/config/routes.rb" 40 | template "config/locales/en.yml", "#{path}/config/locales/en.yml" 41 | template "rspec", "#{path}/.rspec" 42 | template "spec/spec_helper.rb.tt", "#{path}/spec/spec_helper.rb" 43 | template "rubocop.yml", "#{path}/.rubocop.yml" 44 | template "github_changelog_generator", "#{path}/.github_changelog_generator" 45 | end 46 | 47 | no_tasks do 48 | def path=(path) 49 | path = File.expand_path(path) 50 | 51 | @file_name = Thor::Util.snake_case(File.basename(path)) 52 | @file_name = PREFIX + @file_name unless @file_name.start_with?(PREFIX) 53 | 54 | @class_name = Thor::Util.camel_case file_name 55 | 56 | @root = File.dirname(path) 57 | @path = File.join(root, file_name) 58 | 59 | @repo = existing_repo || default_repo 60 | 61 | @gemspec = existing_gemspec || default_gemspec 62 | end 63 | 64 | attr_reader :root, :path, :file_name, :class_name, :gemspec, :repo 65 | 66 | private 67 | 68 | def gemspec_path 69 | @gemspec_path ||= File.join(path, "#{file_name}.gemspec") 70 | end 71 | 72 | def default_gemspec 73 | @default_gemspec ||= Gem::Specification.new(file_name, "0.0.1") do |gem| 74 | gem.author = git("config user.name", "TODO: Write your name") 75 | gem.email = git("config user.email", "TODO: Write your email address") 76 | 77 | gem.summary = "TODO: Write a short summary, because RubyGems requires one." 78 | gem.description = "TODO: Write a longer description or delete this line." 79 | gem.license = "BSD-3-Clause" 80 | 81 | gem.metadata["homepage_uri"] = gem.homepage = "https://github.com/#{repo}#readme" 82 | gem.metadata["changelog_uri"] = "https://github.com/#{repo}/blob/main/CHANGELOG.md" 83 | gem.metadata["source_code_uri"] = "https://github.com/#{repo}" 84 | end 85 | end 86 | 87 | def existing_gemspec 88 | return unless File.exist?(gemspec_path) 89 | 90 | @existing_gemspec ||= Gem::Specification.load(gemspec_path).tap do |spec| 91 | spec.author ||= default_gemspec.author 92 | spec.email ||= default_gemspec.email 93 | 94 | spec.summary ||= default_gemspec.summary 95 | spec.license ||= default_gemspec.license 96 | 97 | spec.homepage ||= default_gemspec.homepage 98 | spec.metadata["source_code_uri"] ||= default_gemspec.metadata["source_code_uri"] 99 | spec.metadata["changelog_uri"] ||= default_gemspec.metadata["changelog_uri"] 100 | spec.metadata["source_code_uri"] ||= default_gemspec.metadata["source_code_uri"] 101 | end 102 | end 103 | 104 | def default_repo 105 | "solidusio-contrib/#{file_name}" 106 | end 107 | 108 | def existing_repo 109 | git("remote get-url origin")&.sub(%r{^.*github\.com.([^/]+)/([^/.]+).*$}, '\1/\2') 110 | end 111 | 112 | def git(command, default = nil) 113 | result = `git #{command} 2> /dev/null`.strip 114 | result.empty? ? default : result 115 | end 116 | 117 | def make_executable(path) 118 | path = Pathname(path) 119 | executable = (path.stat.mode | 0o111) 120 | path.chmod(executable) 121 | end 122 | end 123 | 124 | def self.source_root 125 | "#{__dir__}/templates/extension" 126 | end 127 | end 128 | end 129 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rake_tasks.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rake" 4 | require "pathname" 5 | 6 | module SolidusDevSupport 7 | class RakeTasks 8 | include Rake::DSL 9 | 10 | def self.install(**args) 11 | new(**args).tap(&:install) 12 | end 13 | 14 | def initialize(root: Dir.pwd, user_class: "Spree::LegacyUser") 15 | @root = Pathname(root) 16 | @test_app_path = @root.join(ENV.fetch("DUMMY_PATH", "spec/dummy")) 17 | @gemspec = Bundler.load_gemspec(@root.glob("{,*}.gemspec").first) 18 | @user_class = user_class 19 | end 20 | 21 | attr_reader :test_app_path, :root, :gemspec 22 | 23 | def install 24 | install_test_app_task 25 | install_dev_app_task 26 | install_rspec_task 27 | install_changelog_task 28 | end 29 | 30 | def install_test_app_task 31 | require "rake/clean" 32 | require "spree/testing_support/extension_rake" 33 | 34 | ENV["DUMMY_PATH"] = test_app_path.to_s 35 | ENV["LIB_NAME"] = gemspec.name 36 | 37 | ::CLOBBER.include test_app_path 38 | 39 | namespace :extension do 40 | # We need to go back to the gem root since the upstream 41 | # extension:test_app changes the working directory to be the dummy app. 42 | task :test_app do 43 | Rake::Task["extension:test_app"].invoke(@user_class) 44 | cd root 45 | end 46 | 47 | directory ENV.fetch("DUMMY_PATH", nil) do 48 | Rake::Task["extension:test_app"].invoke(@user_class) 49 | end 50 | end 51 | end 52 | 53 | def install_dev_app_task 54 | desc "Creates a sandbox application for simulating the Extension code in a deployed Rails app" 55 | task :sandbox do 56 | warn "DEPRECATED TASK: This task is here just for parity with solidus, please use bin/sandbox directly." 57 | exec("bin/sandbox", gemspec.name) 58 | end 59 | end 60 | 61 | def install_rspec_task 62 | require "rspec/core/rake_task" 63 | 64 | namespace :extension do 65 | ::RSpec::Core::RakeTask.new(:specs, [] => FileList[ENV.fetch("DUMMY_PATH", nil)]) do |t| 66 | # Ref: https://circleci.com/docs/2.0/configuration-reference#store_test_results 67 | # Ref: https://github.com/solidusio/circleci-orbs-extensions#test-results-rspec 68 | if ENV["TEST_RESULTS_PATH"] 69 | t.rspec_opts = 70 | "--format progress " \ 71 | "--format RspecJunitFormatter --out #{ENV["TEST_RESULTS_PATH"]}" 72 | end 73 | end 74 | end 75 | end 76 | 77 | def install_changelog_task 78 | require "github_changelog_generator/task" 79 | 80 | GitHubChangelogGenerator::RakeTask.new(:changelog) do |config| 81 | require "octokit" 82 | repo = Octokit::Repository.from_url(gemspec.metadata["source_code_uri"] || gemspec.homepage) 83 | 84 | config.user = repo.owner 85 | config.project = repo.name 86 | config.future_release = "v#{ENV.fetch("UNRELEASED_VERSION") { gemspec.version }}" 87 | rescue Octokit::InvalidRepository 88 | warn <<~WARN 89 | It won't be possible to automatically generate the CHANGELOG for this extension because the 90 | gemspec is missing the `source_code_uri` metadata. Please add this line to the gemspec to 91 | enable automatic CHANGELOG generation: 92 | 93 | s.metadata["source_code_uri"] = 'https://github.com/org/repo' 94 | 95 | WARN 96 | end 97 | end 98 | end 99 | end 100 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rspec/capybara.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Allow to override the initial windows size 4 | CAPYBARA_WINDOW_SIZE = ENV.fetch("CAPYBARA_WINDOW_SIZE", "1920x1080").split("x", 2).map(&:to_i) 5 | CAPYBARA_WINDOW_WIDTH = CAPYBARA_WINDOW_SIZE[0] 6 | CAPYBARA_WINDOW_HEIGHT = CAPYBARA_WINDOW_SIZE[1] 7 | 8 | Capybara.javascript_driver = ENV.fetch("CAPYBARA_JAVASCRIPT_DRIVER", "solidus_chrome_headless").to_sym 9 | Capybara.default_max_wait_time = 10 10 | Capybara.server = :puma, {Silent: true} # A fix for rspec/rspec-rails#1897 11 | 12 | Capybara.drivers[:selenium_chrome_headless].tap do |original_driver| 13 | Capybara.register_driver :solidus_chrome_headless do |app| 14 | original_driver.call(app).tap do |driver| 15 | driver.resize_window_to( 16 | driver.current_window_handle, CAPYBARA_WINDOW_WIDTH, CAPYBARA_WINDOW_HEIGHT 17 | ) 18 | end 19 | end 20 | end 21 | 22 | require "capybara-screenshot/rspec" 23 | 24 | Capybara::Screenshot.register_driver(:solidus_chrome_headless) do |driver, path| 25 | driver.browser.save_screenshot(path) 26 | end 27 | 28 | require "spree/testing_support/capybara_ext" 29 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rspec/coverage.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # A SimpleCov and Codecov configuration to track code coverage in your extension 4 | # 5 | # Include it AT THE TOP of your spec/spec_helper.rb: 6 | # 7 | # require 'solidus_dev_support/rspec/coverage' 8 | # 9 | # Note that things may not work properly if you don't include this at the very top! 10 | # 11 | 12 | require "simplecov" 13 | SimpleCov.start("rails") do 14 | add_filter %r{^/lib/generators/.*/install/install_generator.rb} 15 | add_filter %r{^/lib/.*/factories.rb} 16 | add_filter %r{^/lib/.*/version.rb} 17 | end 18 | 19 | if ENV["CODECOV_TOKEN"] 20 | require "codecov" 21 | SimpleCov.formatter = SimpleCov::Formatter::Codecov 22 | warn <<~WARN 23 | DEPRECATION WARNING: The Codecov ruby uploader is deprecated. 24 | Please use the Codecov CLI uploader to upload code coverage reports. 25 | See https://docs.codecov.com/docs/deprecated-uploader-migration-guide#ruby-uploader for more information on upgrading. 26 | WARN 27 | elsif ENV["CODECOV_COVERAGE_PATH"] 28 | require "simplecov-cobertura" 29 | SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter 30 | else 31 | warn "Provide a CODECOV_COVERAGE_PATH environment variable to enable Codecov uploads" 32 | end 33 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rspec/feature_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # A basic feature_helper to be included as the starting point for extensions 4 | # 5 | # Can be required from an extension's spec/feature_helper.rb 6 | # 7 | # require 'solidus_dev_support/rspec/feature_helper' 8 | # 9 | 10 | require "solidus_dev_support/rspec/rails_helper" 11 | require "solidus_dev_support/rspec/capybara" 12 | 13 | dev_support_assets_preload = ->(*) { 14 | if Rails.application.respond_to?(:precompiled_assets) 15 | Rails.application.precompiled_assets 16 | else 17 | # For older sprockets 2.x 18 | Rails.application.config.assets.precompile.each do |asset| 19 | Rails.application.assets.find_asset(asset) 20 | end 21 | end 22 | } 23 | 24 | RSpec.configure do |config| 25 | config.when_first_matching_example_defined(type: :feature) do 26 | config.before :suite, &dev_support_assets_preload 27 | end 28 | 29 | config.when_first_matching_example_defined(type: :system) do 30 | config.before :suite, &dev_support_assets_preload 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rspec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # A basic rails_helper to be included as the starting point for extensions 4 | # 5 | # Can be required from an extension's spec/rails_helper.rb 6 | # 7 | # require 'solidus_dev_support/rspec/rails_helper' 8 | # 9 | 10 | require "solidus_dev_support/rspec/spec_helper" 11 | require "solidus_dev_support" 12 | 13 | require "rspec/rails" 14 | require "database_cleaner" 15 | require "factory_bot" 16 | require "ffaker" 17 | 18 | require "spree/testing_support/authorization_helpers" 19 | require "spree/testing_support/url_helpers" 20 | require "spree/testing_support/preferences" 21 | require "spree/testing_support/controller_requests" 22 | require "solidus_dev_support/testing_support/factories" 23 | require "solidus_dev_support/testing_support/preferences" 24 | 25 | RSpec.configure do |config| 26 | config.infer_spec_type_from_file_location! 27 | 28 | config.include FactoryBot::Syntax::Methods 29 | 30 | # visit spree.admin_path 31 | # current_path.should eql(spree.products_path) 32 | config.include Spree::TestingSupport::UrlHelpers 33 | 34 | config.include Spree::TestingSupport::ControllerRequests, type: :controller 35 | 36 | config.include Spree::TestingSupport::Preferences 37 | config.include SolidusDevSupport::TestingSupport::Preferences 38 | 39 | config.before :suite do 40 | DatabaseCleaner.clean_with :truncation 41 | end 42 | 43 | config.before do 44 | ActiveJob::Base.queue_adapter = :test 45 | end 46 | 47 | # Around each spec check if it is a Javascript test and switch between using 48 | # database transactions or not where necessary. 49 | config.around(:each) do |example| 50 | DatabaseCleaner.strategy = RSpec.current_example.metadata[:js] ? :truncation : :transaction 51 | 52 | DatabaseCleaner.cleaning do 53 | reset_spree_preferences unless SolidusDevSupport.reset_spree_preferences_deprecated? 54 | 55 | example.run 56 | end 57 | end 58 | 59 | config.include ActiveJob::TestHelper 60 | 61 | config.after(:suite) do 62 | if Rails.respond_to?(:autoloaders) && Rails.autoloaders.zeitwerk_enabled? 63 | Rails.autoloaders.main.class.eager_load_all 64 | end 65 | rescue NameError => e 66 | class ZeitwerkNameError < NameError; end 67 | 68 | error_message = 69 | if /expected file .*? to define constant [\w:]+/.match?(e.message) 70 | e.message.sub(/expected file #{Regexp.escape(File.expand_path("../..", Rails.root))}./, "expected file ") 71 | else 72 | e.message 73 | end 74 | 75 | message = <<~WARN 76 | Zeitwerk raised the following error when trying to eager load your extension: 77 | 78 | #{error_message} 79 | 80 | This most likely means that your extension's file structure is not 81 | compatible with the Zeitwerk autoloader. 82 | Refer to https://github.com/solidusio/solidus_support#engine-extensions in 83 | order to update the file structure to match Zeitwerk's expectations. 84 | WARN 85 | 86 | raise ZeitwerkNameError, message 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rspec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # A basic spec_helper to be included as the starting point for extensions 4 | # 5 | # Can be required from an extension's spec/spec_helper.rb 6 | # 7 | # require 'solidus_dev_support/rspec/spec_helper' 8 | # 9 | 10 | RSpec.configure do |config| 11 | config.filter_run focus: true 12 | config.run_all_when_everything_filtered = true 13 | 14 | config.mock_with :rspec 15 | config.color = true 16 | 17 | config.fail_fast = ENV.fetch("FAIL_FAST", false) 18 | config.order = "random" 19 | 20 | config.raise_errors_for_deprecations! 21 | 22 | config.example_status_persistence_file_path = "./spec/examples.txt" 23 | 24 | Kernel.srand config.seed 25 | end 26 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rubocop.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SolidusDevSupport 4 | module RuboCop 5 | CONFIG_PATH = "#{__dir__}/rubocop/config.yml".freeze 6 | 7 | def self.inject_defaults! 8 | config = ::RuboCop::ConfigLoader.load_file(CONFIG_PATH) 9 | puts "configuration from #{CONFIG_PATH}" if ::RuboCop::ConfigLoader.debug? 10 | config = ::RuboCop::ConfigLoader.merge_with_default(config, CONFIG_PATH, unset_nil: false) 11 | ::RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, config) 12 | end 13 | end 14 | end 15 | 16 | SolidusDevSupport::RuboCop.inject_defaults! 17 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/rubocop/config.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - standard 3 | 4 | inherit_gem: 5 | standard: config/base.yml 6 | 7 | AllCops: 8 | TargetRubyVersion: 3.0 9 | Exclude: 10 | - spec/dummy/**/* 11 | - sandbox/**/* 12 | - vendor/**/* 13 | - bin/* 14 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/solidus_command.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "thor" 4 | require "solidus_dev_support/extension" 5 | require "spree/core/version" 6 | 7 | module SolidusDevSupport 8 | class SolidusCommand < Thor 9 | namespace "" 10 | 11 | desc "extension", "Manage solidus extensions" 12 | subcommand "extension", Extension 13 | 14 | desc "e", 'Manage solidus extensions (shortcut for "extension")' 15 | subcommand "e", Extension 16 | 17 | desc "version", "Displays solidus_dev_support version" 18 | def version 19 | puts "Solidus version #{Spree.solidus_gem_version}" 20 | puts "Solidus Dev Support version #{SolidusDevSupport::VERSION}" 21 | end 22 | map ["-v", "--version"] => :version 23 | 24 | def self.exit_on_failure? 25 | true 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | # Required for feature specs. 5 | browser-tools: circleci/browser-tools@1.1 6 | 7 | # Always take the latest version of the orb, this allows us to 8 | # run specs against Solidus supported versions only without the need 9 | # to change this configuration every time a Solidus version is released 10 | # or goes EOL. 11 | solidusio_extensions: solidusio/extensions@volatile 12 | 13 | jobs: 14 | run-specs-with-sqlite: 15 | executor: solidusio_extensions/sqlite 16 | steps: 17 | - browser-tools/install-chrome 18 | - solidusio_extensions/run-tests 19 | run-specs-with-postgres: 20 | executor: solidusio_extensions/postgres 21 | steps: 22 | - browser-tools/install-chrome 23 | - solidusio_extensions/run-tests 24 | run-specs-with-mysql: 25 | executor: solidusio_extensions/mysql 26 | steps: 27 | - browser-tools/install-chrome 28 | - solidusio_extensions/run-tests 29 | lint-code: 30 | executor: solidusio_extensions/sqlite-memory 31 | steps: 32 | - solidusio_extensions/lint-code 33 | 34 | workflows: 35 | "Run specs on supported Solidus versions": 36 | jobs: 37 | - run-specs-with-sqlite 38 | - run-specs-with-postgres 39 | - run-specs-with-mysql 40 | - lint-code 41 | 42 | "Weekly run specs against main": 43 | triggers: 44 | - schedule: 45 | cron: "0 0 * * 4" # every Thursday 46 | filters: 47 | branches: 48 | only: 49 | - main 50 | jobs: 51 | - run-specs-with-sqlite 52 | - run-specs-with-postgres 53 | - run-specs-with-mysql 54 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/.github/stale.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: [pull_request] 4 | 5 | concurrency: 6 | group: lint-${{ github.ref_name }} 7 | cancel-in-progress: ${{ github.ref_name != 'main' }} 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | ruby: 14 | name: Check Ruby 15 | runs-on: ubuntu-24.04 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v3 19 | - name: Install Ruby and gems 20 | uses: ruby/setup-ruby@v1 21 | with: 22 | ruby-version: "3.2" 23 | bundler-cache: true 24 | - name: Lint Ruby files 25 | run: bundle exec rubocop -ESP 26 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | schedule: 9 | - cron: "0 0 * * 4" # every Thursday 10 | 11 | concurrency: 12 | group: test-${{ github.ref_name }} 13 | cancel-in-progress: ${{ github.ref_name != 'main' }} 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | rspec: 20 | name: Solidus ${{ matrix.solidus-branch }}, Rails ${{ matrix.rails-version }} and Ruby ${{ matrix.ruby-version }} on ${{ matrix.database }} 21 | runs-on: ubuntu-24.04 22 | strategy: 23 | fail-fast: true 24 | matrix: 25 | rails-version: 26 | - "7.0" 27 | - "7.1" 28 | - "7.2" 29 | ruby-version: 30 | - "3.1" 31 | - "3.4" 32 | solidus-branch: 33 | - "v4.1" 34 | - "v4.2" 35 | - "v4.3" 36 | - "v4.4" 37 | - "v4.5" 38 | database: 39 | - "postgresql" 40 | - "mysql" 41 | - "sqlite" 42 | exclude: 43 | - rails-version: "7.2" 44 | solidus-branch: "v4.3" 45 | - rails-version: "7.2" 46 | solidus-branch: "v4.2" 47 | - rails-version: "7.2" 48 | solidus-branch: "v4.1" 49 | - rails-version: "7.1" 50 | solidus-branch: "v4.2" 51 | - rails-version: "7.1" 52 | solidus-branch: "v4.1" 53 | - ruby-version: "3.4" 54 | rails-version: "7.0" 55 | env: 56 | CODECOV_COVERAGE_PATH: ./coverage/coverage.xml 57 | steps: 58 | - uses: actions/checkout@v4 59 | - name: Run extension tests 60 | uses: solidusio/test-solidus-extension@main 61 | with: 62 | database: ${{ matrix.database }} 63 | rails-version: ${{ matrix.rails-version }} 64 | ruby-version: ${{ matrix.ruby-version }} 65 | solidus-branch: ${{ matrix.solidus-branch }} 66 | - name: Upload coverage reports to Codecov 67 | uses: codecov/codecov-action@v5 68 | continue-on-error: true 69 | with: 70 | token: ${{ secrets.CODECOV_TOKEN }} 71 | files: ${{ env.CODECOV_COVERAGE_PATH }} 72 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/CHANGELOG.md.tt: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | See https://github.com/<%=default_repo%>/releases or OLD_CHANGELOG.md for older versions. 4 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Third-party patches are essential to any great open source project. We want 4 | to keep it as easy as possible to contribute changes that get things working 5 | in your environment. There are a few guidelines that we need contributors to 6 | follow so that we can have a chance of keeping on top of things. 7 | 8 | ## Getting Started 9 | 10 | * Make sure you have a [GitHub account](https://github.com/signup/free) 11 | * Submit a ticket for your issue, assuming one does not already exist. 12 | * Clearly describe the issue including steps to reproduce when it is a bug. 13 | * Make sure you fill in the earliest version that you know has the issue. 14 | * Fork the repository on GitHub 15 | 16 | ## Making Changes 17 | 18 | * Create a topic branch from where you want to base your work. 19 | * This is usually the main branch. 20 | * Only target release branches if you are certain your fix must be on that 21 | branch. 22 | * To quickly create a topic branch based on main; `git branch 23 | fix/main/my_contribution main` then checkout the new branch with `git 24 | checkout fix/main/my_contribution`. Please avoid working directly on the 25 | `main` branch. 26 | * Make commits of logical units. 27 | * Check for unnecessary whitespace with `git diff --check` before committing. 28 | * Make sure your commit messages are in the proper format. 29 | 30 | ```` 31 | (#99999) Make the example in CONTRIBUTING imperative and concrete 32 | 33 | Without this patch applied the example commit message in the CONTRIBUTING 34 | document is not a concrete example. This is a problem because the 35 | contributor is left to imagine what the commit message should look like 36 | based on a description rather than an example. This patch fixes the 37 | problem by making the example concrete and imperative. 38 | 39 | The first line is a real life imperative statement with a ticket number 40 | from our issue tracker. The body describes the behavior without the patch, 41 | why this is a problem, and how the patch fixes the problem when applied. 42 | ```` 43 | 44 | * Make sure you have added the necessary tests for your changes. 45 | * Run _all_ the tests to assure nothing else was accidentally broken. 46 | 47 | ## Submitting Changes 48 | 49 | * Push your changes to a topic branch in your fork of the repository. 50 | * Submit a pull request to the extensions repository. 51 | * Update any Github issues to mark that you have submitted code and are ready for it to be reviewed. 52 | * Include a link to the pull request in the ticket 53 | 54 | # Additional Resources 55 | 56 | * [General GitHub documentation](http://help.github.com/) 57 | * [GitHub pull request documentation](http://help.github.com/send-pull-requests/) 58 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/Gemfile.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | git_source(:github) { |repo| "https://github.com/#{repo}.git" } 5 | 6 | branch = ENV.fetch('SOLIDUS_BRANCH', 'main') 7 | gem 'solidus', github: 'solidusio/solidus', branch: branch 8 | 9 | # The solidus_frontend gem has been pulled out since v3.2 10 | if branch >= 'v3.2' 11 | gem 'solidus_frontend' 12 | elsif branch == 'main' 13 | gem 'solidus_frontend', github: 'solidusio/solidus_frontend' 14 | else 15 | gem 'solidus_frontend', github: 'solidusio/solidus', branch: branch 16 | end 17 | 18 | rails_version = ENV.fetch('RAILS_VERSION', '7.0') 19 | gem 'rails', "~> #{rails_version}" 20 | 21 | case ENV.fetch('DB', nil) 22 | when 'mysql' 23 | gem 'mysql2' 24 | when 'postgresql' 25 | gem 'pg' 26 | else 27 | gem 'sqlite3', rails_version < '7.2' ? '~> 1.4' : '~> 2.0' 28 | end 29 | 30 | if rails_version == '7.0' 31 | gem 'concurrent-ruby', '< 1.3.5' 32 | end 33 | 34 | if RUBY_VERSION >= '3.4' 35 | # Solidus Promotions uses CSV but does not have it as dependency yet. 36 | gem 'csv' 37 | end 38 | 39 | # While we still support Ruby < 3 we need to workaround a limitation in 40 | # the 'async' gem that relies on the latest ruby, since RubyGems doesn't 41 | # resolve gems based on the required ruby version. 42 | gem 'async', '< 3' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3') 43 | 44 | gemspec 45 | 46 | # Use a local Gemfile to include development dependencies that might not be 47 | # relevant for the project or for other contributors, e.g. pry-byebug. 48 | # 49 | # We use `send` instead of calling `eval_gemfile` to work around an issue with 50 | # how Dependabot parses projects: https://github.com/dependabot/dependabot-core/issues/1658. 51 | send(:eval_gemfile, 'Gemfile-local') if File.exist? 'Gemfile-local' 52 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) <%= Time.now.year %> <%= gemspec.authors.join ', ' %> 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | * Neither the name Solidus nor the names of its contributors may be used to 13 | endorse or promote products derived from this software without specific 14 | prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/README.md: -------------------------------------------------------------------------------- 1 | # <%= class_name.gsub(/(?<=[^A-Z])([A-Z])/, ' \1') %> 2 | 3 | [![CircleCI](https://circleci.com/gh/<%= repo %>.svg?style=shield)](https://circleci.com/gh/<%= repo %>) 4 | [![codecov](https://codecov.io/gh/<%= repo %>/branch/main/graph/badge.svg)](https://codecov.io/gh/<%= repo %>) 5 | 6 | 7 | 8 | ## Installation 9 | 10 | Add <%= file_name %> to your Gemfile: 11 | 12 | ```ruby 13 | gem '<%= file_name %>' 14 | ``` 15 | 16 | Bundle your dependencies and run the installation generator: 17 | 18 | ```shell 19 | bin/rails generate <%= file_name %>:install 20 | ``` 21 | 22 | ## Usage 23 | 24 | 25 | 26 | ## Development 27 | 28 | ### Testing the extension 29 | 30 | First bundle your dependencies, then run `bin/rake`. `bin/rake` will default to building the dummy 31 | app if it does not exist, then it will run specs. The dummy app can be regenerated by using 32 | `bin/rake extension:test_app`. 33 | 34 | ```shell 35 | bin/rake 36 | ``` 37 | 38 | To run [Rubocop](https://github.com/bbatsov/rubocop) static code analysis run 39 | 40 | ```shell 41 | bundle exec rubocop 42 | ``` 43 | 44 | When testing your application's integration with this extension you may use its factories. 45 | You can load Solidus core factories along with this extension's factories using this statement: 46 | 47 | ```ruby 48 | SolidusDevSupport::TestingSupport::Factories.load_for(<%= class_name %>::Engine) 49 | ``` 50 | 51 | ### Running the sandbox 52 | 53 | To run this extension in a sandboxed Solidus application, you can run `bin/sandbox`. The path for 54 | the sandbox app is `./sandbox` and `bin/rails` will forward any Rails commands to 55 | `sandbox/bin/rails`. 56 | 57 | Here's an example: 58 | 59 | ``` 60 | $ bin/rails server 61 | => Booting Puma 62 | => Rails 6.0.2.1 application starting in development 63 | * Listening on tcp://127.0.0.1:3000 64 | Use Ctrl-C to stop 65 | ``` 66 | 67 | ### Releasing new versions 68 | 69 | Please refer to the [dedicated page](https://github.com/solidusio/solidus/wiki/How-to-release-extensions) in the Solidus wiki. 70 | 71 | ## License 72 | 73 | Copyright (c) <%= Time.now.year %> <%= gemspec.authors.join ', ' %>, released under the New BSD License. 74 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "solidus_dev_support/rake_tasks" 5 | SolidusDevSupport::RakeTasks.install 6 | 7 | task default: "extension:specs" 8 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/app/assets/javascripts/spree/backend/%file_name%.js: -------------------------------------------------------------------------------- 1 | // Placeholder manifest file. 2 | // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js' -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/app/assets/javascripts/spree/frontend/%file_name%.js: -------------------------------------------------------------------------------- 1 | // Placeholder manifest file. 2 | // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js' -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/app/assets/stylesheets/spree/backend/%file_name%.css: -------------------------------------------------------------------------------- 1 | /* 2 | Placeholder manifest file. 3 | the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css' 4 | */ 5 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/app/assets/stylesheets/spree/frontend/%file_name%.css: -------------------------------------------------------------------------------- 1 | /* 2 | Placeholder manifest file. 3 | the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css' 4 | */ 5 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/bin/console.tt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # frozen_string_literal: true 4 | 5 | require "bundler/setup" 6 | require "<%= file_name %>" 7 | 8 | # You can add fixtures and/or initialization code here to make experimenting 9 | # with your gem easier. You can also use a different console, if you like. 10 | $LOAD_PATH.unshift(*Dir["#{__dir__}/../app/*"]) 11 | 12 | # (If you use this, don't forget to add pry to your Gemfile!) 13 | # require "pry" 14 | # Pry.start 15 | 16 | require "irb" 17 | IRB.start(__FILE__) 18 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | if %w[g generate].include? ARGV.first 4 | exec "#{__dir__}/rails-engine", *ARGV 5 | else 6 | exec "#{__dir__}/rails-sandbox", *ARGV 7 | end 8 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/bin/rails-engine.tt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails gems 3 | # installed from the root of your application. 4 | 5 | ENGINE_ROOT = File.expand_path('..', __dir__) 6 | ENGINE_PATH = File.expand_path('../lib/<%=file_name%>/engine', __dir__) 7 | 8 | # Set up gems listed in the Gemfile. 9 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 10 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 11 | 12 | require 'rails/all' 13 | require 'rails/engine/commands' 14 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/bin/rails-sandbox: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | app_root = "sandbox" 4 | 5 | unless File.exist? "#{app_root}/bin/rails" 6 | warn "Creating the sandbox app..." 7 | Dir.chdir "#{__dir__}/.." do 8 | system "#{__dir__}/sandbox" or begin 9 | warn "Automatic creation of the sandbox app failed" 10 | exit 1 11 | end 12 | end 13 | end 14 | 15 | Dir.chdir app_root 16 | exec "bin/rails", *ARGV 17 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "rubygems" 5 | require "bundler/setup" 6 | 7 | load Gem.bin_path("rake", "rake") 8 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/bin/sandbox.tt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | test -z "${DEBUG+empty_string}" || set -x 5 | 6 | test "$DB" = "sqlite" && export DB="sqlite3" 7 | 8 | if [ -z "$PAYMENT_METHOD" ] 9 | then 10 | PAYMENT_METHOD="none" 11 | fi 12 | 13 | if [ -z "$SOLIDUS_BRANCH" ] 14 | then 15 | echo "~~> Use 'export SOLIDUS_BRANCH=[main|v4.0|...]' to control the Solidus branch" 16 | SOLIDUS_BRANCH="main" 17 | fi 18 | echo "~~> Using branch $SOLIDUS_BRANCH of solidus" 19 | 20 | extension_name="<%= file_name %>" 21 | 22 | # Stay away from the bundler env of the containing extension. 23 | function unbundled { 24 | ruby -rbundler -e' 25 | Bundler.with_unbundled_env {system *ARGV}' -- \ 26 | env BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES=true $@ 27 | } 28 | 29 | echo "~~~> Removing the old sandbox" 30 | rm -rf ./sandbox 31 | 32 | echo "~~~> Creating a pristine Rails app" 33 | rails_version=`bundle exec ruby -e'require "rails"; puts Rails.version'` 34 | rails _${rails_version}_ new sandbox \ 35 | --database="${DB:-sqlite3}" \ 36 | --skip-git \ 37 | --skip-keeps \ 38 | --skip-rc \ 39 | --skip-bootsnap \ 40 | --skip-test 41 | 42 | if [ ! -d "sandbox" ]; then 43 | echo 'sandbox rails application failed' 44 | exit 1 45 | fi 46 | 47 | echo "~~~> Adding solidus (with i18n) to the Gemfile" 48 | cd ./sandbox 49 | cat <> Gemfile 50 | gem 'solidus', github: 'solidusio/solidus', branch: '$SOLIDUS_BRANCH' 51 | gem 'rails-i18n' 52 | gem 'solidus_i18n' 53 | gem 'solidus_auth_devise' 54 | 55 | gem '$extension_name', path: '..' 56 | 57 | group :test, :development do 58 | platforms :mri do 59 | gem 'pry-byebug' 60 | end 61 | end 62 | RUBY 63 | 64 | echo "Generating manifest file" 65 | mkdir -p app/assets/config 66 | cat < app/assets/config/manifest.js 67 | //= link_tree ../images 68 | //= link_directory ../javascripts .js 69 | //= link_directory ../stylesheets .css 70 | MANIFESTJS 71 | 72 | unbundled bundle install --gemfile Gemfile 73 | 74 | unbundled bundle exec rake db:drop db:create 75 | 76 | unbundled bundle exec rails generate solidus:install \ 77 | --auto-accept \ 78 | $@ 79 | 80 | unbundled bundle exec rails generate solidus:auth:install --auto-run-migrations 81 | unbundled bundle exec rails generate ${extension_name}:install --auto-run-migrations 82 | 83 | echo 84 | echo "🚀 Sandbox app successfully created for $extension_name!" 85 | echo "🧪 This app is intended for test purposes." 86 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | gem install bundler --conservative 7 | bundle update 8 | bin/rake clobber 9 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: Hello world 6 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/config/routes.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Spree::Core::Engine.routes.draw do 4 | # Add your extension routes here 5 | end 6 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/extension.gemspec.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'lib/<%= file_name %>/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = '<%= file_name %>' 7 | spec.version = <%= class_name %>::VERSION 8 | spec.authors = <%= gemspec.authors.inspect.gsub('"', "'") %> 9 | spec.email = '<%= gemspec.email %>' 10 | 11 | spec.summary = '<%= gemspec.summary %>' 12 | <% if gemspec.description %>spec.description = '<%= gemspec.description %>' 13 | <% end %>spec.homepage = '<%= gemspec.homepage %>' 14 | spec.license = '<%= gemspec.license %>' 15 | 16 | spec.metadata['homepage_uri'] = spec.homepage 17 | spec.metadata['source_code_uri'] = '<%= gemspec.metadata["source_code_uri"] %>' 18 | spec.metadata['changelog_uri'] = '<%= gemspec.metadata["changelog_uri"] %>' 19 | 20 | spec.required_ruby_version = Gem::Requirement.new('>= 2.5', '< 4') 21 | 22 | # Specify which files should be added to the gem when it is released. 23 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 24 | files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") } 25 | 26 | spec.files = files.grep_v(%r{^(test|spec|features)/}) 27 | spec.test_files = files.grep(%r{^(test|spec|features)/}) 28 | spec.bindir = "exe" 29 | spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | spec.add_dependency 'solidus_core', ['>= 2.0.0', '< 5'] 33 | spec.add_dependency 'solidus_support', '>= 0.12.0' 34 | 35 | spec.add_development_dependency 'solidus_dev_support', '<%= SolidusDevSupport.gem_version.approximate_recommendation %>' 36 | end 37 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/gem_release.yml.tt: -------------------------------------------------------------------------------- 1 | bump: 2 | recurse: false 3 | file: 'lib/<%=file_name%>/version.rb' 4 | message: Bump <%=class_name%> to %{version} 5 | tag: true 6 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/github_changelog_generator: -------------------------------------------------------------------------------- 1 | issues=false 2 | exclude-labels=infrastructure 3 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | \#* 3 | *~ 4 | .#* 5 | .DS_Store 6 | .idea 7 | .project 8 | .sass-cache 9 | coverage 10 | Gemfile.lock 11 | Gemfile-local 12 | tmp 13 | nbproject 14 | pkg 15 | *.swp 16 | spec/dummy 17 | spec/examples.txt 18 | /sandbox 19 | .rvmrc 20 | .ruby-version 21 | .ruby-gemset 22 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/lib/%file_name%.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require '<%=file_name%>/configuration' 4 | require '<%=file_name%>/version' 5 | require '<%=file_name%>/engine' 6 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/lib/%file_name%/configuration.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module <%= class_name %> 4 | class Configuration 5 | # Define here the settings for this extension, e.g.: 6 | # 7 | # attr_accessor :my_setting 8 | end 9 | 10 | class << self 11 | def configuration 12 | @configuration ||= Configuration.new 13 | end 14 | 15 | alias config configuration 16 | 17 | def configure 18 | yield configuration 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/lib/%file_name%/engine.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'solidus_core' 4 | require 'solidus_support' 5 | 6 | module <%= class_name %> 7 | class Engine < Rails::Engine 8 | include SolidusSupport::EngineExtensions 9 | 10 | isolate_namespace ::Spree 11 | 12 | engine_name '<%= file_name %>' 13 | 14 | # use rspec for tests 15 | config.generators do |g| 16 | g.test_framework :rspec 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/lib/%file_name%/testing_support/factories.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | end 5 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/lib/%file_name%/version.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module <%= class_name %> 4 | VERSION = '<%= gemspec.version %>' 5 | end 6 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/lib/generators/%file_name%/install/install_generator.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module <%= class_name %> 4 | module Generators 5 | class InstallGenerator < Rails::Generators::Base 6 | class_option :auto_run_migrations, type: :boolean, default: false 7 | source_root File.expand_path('templates', __dir__) 8 | 9 | def self.exit_on_failure? 10 | true 11 | end 12 | 13 | def copy_initializer 14 | template 'initializer.rb', 'config/initializers/<%= file_name %>.rb' 15 | end 16 | 17 | def add_javascripts 18 | append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/<%= file_name %>\n" 19 | append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/<%= file_name %>\n" 20 | end 21 | 22 | def add_stylesheets 23 | inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/<%= file_name %>\n", before: %r{\*/}, verbose: true # rubocop:disable Layout/LineLength 24 | inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/<%= file_name %>\n", before: %r{\*/}, verbose: true # rubocop:disable Layout/LineLength 25 | end 26 | 27 | def add_migrations 28 | run 'bin/rails railties:install:migrations FROM=<%= file_name %>' 29 | end 30 | 31 | def run_migrations 32 | run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) # rubocop:disable Layout/LineLength 33 | if run_migrations 34 | run 'bin/rails db:migrate' 35 | else 36 | puts 'Skipping bin/rails db:migrate, don\'t forget to run it!' # rubocop:disable Rails/Output 37 | end 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/lib/generators/%file_name%/install/templates/initializer.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | <%= class_name %>.configure do |config| 4 | # TODO: Remember to change this with the actual preferences you have implemented! 5 | # config.sample_preference = 'sample_value' 6 | end 7 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/rubocop.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - solidus_dev_support/rubocop 3 | 4 | AllCops: 5 | NewCops: disable 6 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/templates/extension/spec/spec_helper.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Configure Rails Environment 4 | ENV['RAILS_ENV'] = 'test' 5 | 6 | # Run Coverage report 7 | require 'solidus_dev_support/rspec/coverage' 8 | 9 | # Create the dummy app if it's still missing. 10 | dummy_env = "#{__dir__}/dummy/config/environment.rb" 11 | system 'bin/rake extension:test_app' unless File.exist? dummy_env 12 | require dummy_env 13 | 14 | # Requires factories and other useful helpers defined in spree_core. 15 | require 'solidus_dev_support/rspec/feature_helper' 16 | 17 | # Requires supporting ruby files with custom matchers and macros, etc, 18 | # in spec/support/ and its subdirectories. 19 | Dir["#{__dir__}/support/**/*.rb"].sort.each { |f| require f } 20 | 21 | # Requires factories defined in Solidus core and this extension. 22 | # See: lib/<%= file_name %>/testing_support/factories.rb 23 | SolidusDevSupport::TestingSupport::Factories.load_for(<%= class_name %>::Engine) 24 | 25 | RSpec.configure do |config| 26 | config.infer_spec_type_from_file_location! 27 | config.use_transactional_fixtures = false 28 | 29 | if Spree.solidus_gem_version < Gem::Version.new('2.11') 30 | config.extend Spree::TestingSupport::AuthorizationHelpers::Request, type: :system 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/testing_support/factories.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "factory_bot" 4 | require "spree/testing_support/factory_bot" 5 | 6 | module SolidusDevSupport 7 | module TestingSupport 8 | module Factories 9 | def self.load_for(*engines) 10 | paths = engines.flat_map do |engine| 11 | engine.root.glob("lib/**/testing_support/factories{,.rb}") 12 | end.map { |path| path.sub(/.rb\z/, "").to_s } 13 | 14 | FactoryBot.definition_file_paths = [ 15 | Spree::TestingSupport::FactoryBot.definition_file_paths, 16 | paths 17 | ].flatten 18 | 19 | FactoryBot.reload 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/testing_support/preferences.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SolidusDevSupport 4 | module TestingSupport 5 | module Preferences 6 | # This wrapper method allows to stub spree preferences using 7 | # the new standard way of solidus core but also works with 8 | # old versions that does not have the stub_spree_preferences 9 | # method yet. This way we can start using this method in our 10 | # extensions safely. 11 | # 12 | # To have this available, it is needed to require in the 13 | # spec/spec_helper.rb of the extension both: 14 | # 15 | # require 'spree/testing_support/preferences' 16 | # require 'solidus_dev_support/testing_support/preferences' 17 | # 18 | # @example Set a preference on Spree::Config 19 | # stub_spree_preferences(allow_guest_checkout: false) 20 | # 21 | # @example Set a preference on Spree::Api::Config 22 | # stub_spree_preferences(Spree::Api::Config, requires_authentication: false) 23 | # 24 | # @example Set a preference on a custom Spree::CustomExtension::Config 25 | # stub_spree_preferences(Spree::CustomExtension::Config, custom_pref: true) 26 | # 27 | # @param prefs_or_conf_class [Class, Hash] the class we want to stub 28 | # preferences for or the preferences hash (see prefs param). If this 29 | # param is an Hash, preferences will be stubbed on Spree::Config. 30 | # @param prefs [Hash, nil] names and values to be stubbed 31 | def stub_spree_preferences(prefs_or_conf_class, prefs = nil) 32 | super && return if SolidusDevSupport.reset_spree_preferences_deprecated? 33 | 34 | if prefs_or_conf_class.is_a?(Hash) 35 | preference_store_class = Spree::Config 36 | preferences = prefs_or_conf_class 37 | else 38 | preference_store_class = prefs_or_conf_class 39 | preferences = prefs 40 | end 41 | preference_store_class.set(preferences) 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/solidus_dev_support/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SolidusDevSupport 4 | VERSION = "2.12.0" 5 | 6 | def self.gem_version 7 | Gem::Version.new(VERSION) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /solidus_dev_support.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/solidus_dev_support/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "solidus_dev_support" 7 | spec.version = SolidusDevSupport::VERSION 8 | spec.authors = ["Alessandro Desantis"] 9 | spec.email = ["alessandrodesantis@nebulab.it"] 10 | 11 | spec.summary = "Development tools for Solidus extensions." 12 | spec.homepage = "https://github.com/solidusio/solidus_dev_support" 13 | spec.license = "MIT" 14 | 15 | spec.metadata["homepage_uri"] = spec.homepage 16 | spec.metadata["source_code_uri"] = "https://github.com/solidusio/solidus_dev_support" 17 | spec.metadata["changelog_uri"] = "https://github.com/solidusio/solidus_dev_support/releases" 18 | spec.metadata["rubygems_mfa_required"] = "true" 19 | 20 | spec.required_ruby_version = ">= 3.0.0" 21 | 22 | # Specify which files should be added to the gem when it is released. 23 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 24 | files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") } 25 | 26 | spec.files = files.grep_v(%r{^(test|spec|features)/}) 27 | spec.bindir = "exe" 28 | spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) } 29 | spec.require_paths = ["lib"] 30 | 31 | spec.add_dependency "capybara", "~> 3.29" 32 | spec.add_dependency "capybara-screenshot", "~> 1.0" 33 | spec.add_dependency "codecov", "~> 0.2" 34 | spec.add_dependency "database_cleaner", [">= 1.7", "< 3"] 35 | spec.add_dependency "factory_bot", ">= 4.8" 36 | spec.add_dependency "factory_bot_rails" 37 | spec.add_dependency "ffaker", "~> 2.13" 38 | spec.add_dependency "gem-release", "~> 2.1" 39 | spec.add_dependency "github_changelog_generator", "~> 1.15" 40 | spec.add_dependency "puma", ">= 4.3", "< 7.0" 41 | spec.add_dependency "rspec_junit_formatter" 42 | spec.add_dependency "rspec-rails", ">= 5.0", "< 7.0" 43 | spec.add_dependency "selenium-webdriver", "~> 4.11" 44 | spec.add_dependency "simplecov-cobertura", "~> 2.1" 45 | spec.add_dependency "solidus_core", [">= 2.0", "< 5"] 46 | spec.add_dependency "standard", "~> 1.49" 47 | end 48 | -------------------------------------------------------------------------------- /spec/features/create_extension_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "fileutils" 4 | require "open3" 5 | require "spec_helper" 6 | require "spree/core/version" 7 | 8 | RSpec.describe "Create extension" do 9 | include FileUtils 10 | 11 | let(:gem_root) { File.expand_path("../..", __dir__) } 12 | let(:solidus_cmd) { "#{gem_root}/exe/solidus" } 13 | let(:extension_name) { "test_extension" } 14 | let(:gemspec_name) { "solidus_#{extension_name}.gemspec" } 15 | let(:tmp_path) { Pathname.new(gem_root).join("tmp") } 16 | let(:install_path) { tmp_path.join("solidus_#{extension_name}") } 17 | let(:command_failed_error) { Class.new(StandardError) } 18 | 19 | before do 20 | rm_rf(install_path) 21 | mkdir_p(tmp_path) 22 | end 23 | 24 | def step(method_name) 25 | puts "Step #{method_name}" 26 | send method_name 27 | end 28 | 29 | it "checks the create extension process" do 30 | step :check_solidus_cmd 31 | step :check_gem_version 32 | step :check_create_extension 33 | step :check_bundle_install 34 | step :check_default_task 35 | step :check_run_specs 36 | step :check_sandbox 37 | end 38 | 39 | private 40 | 41 | def check_solidus_cmd 42 | cd(tmp_path) do 43 | output = `#{solidus_cmd} -h` 44 | expect($?).to be_success 45 | expect(output).to include("Commands:") 46 | end 47 | end 48 | 49 | def check_gem_version 50 | gem_version_commands = ["version", "--version", "-v"] 51 | gem_version = SolidusDevSupport::VERSION 52 | solidus_version = Spree.solidus_gem_version 53 | 54 | cd(tmp_path) do 55 | gem_version_commands.each do |gem_version_cmd| 56 | output = `#{solidus_cmd} #{gem_version_cmd}` 57 | expect($?).to be_success 58 | expect(output).to include("Solidus version #{solidus_version}") 59 | expect(output).to include("Solidus Dev Support version #{gem_version}") 60 | end 61 | end 62 | end 63 | 64 | def check_create_extension 65 | cd(tmp_path) do 66 | output = `#{solidus_cmd} extension #{extension_name}` 67 | expect($?).to be_success 68 | expect(output).to include(gemspec_name) 69 | expect(output).to include(".circleci") 70 | end 71 | 72 | cd(install_path) do 73 | aggregate_failures do 74 | %w[ 75 | bin/console 76 | bin/rails 77 | bin/rails-engine 78 | bin/rails-sandbox 79 | bin/sandbox 80 | bin/setup 81 | ].each do |bin| 82 | bin = Pathname(bin) 83 | expect( 84 | name: bin, 85 | exist: bin.exist?, 86 | executable: bin.stat.executable? 87 | ).to eq( 88 | name: bin, 89 | exist: true, 90 | executable: true 91 | ) 92 | end 93 | end 94 | end 95 | end 96 | 97 | def check_bundle_install 98 | cd(install_path) do 99 | open("Gemfile", "a") { |f| f.puts "gem 'solidus_dev_support', path: '../..'" } 100 | end 101 | 102 | # Update gemspec with the required fields 103 | gemspec_path = install_path.join(gemspec_name) 104 | gemspec = gemspec_path.read.lines 105 | gemspec.grep(/spec\.author/).first.replace(" spec.author = 'John Doe'\n") 106 | gemspec.grep(/spec\.email/).first.replace(" spec.email = 'john@example.com'\n") 107 | gemspec.grep(/spec\.summary/).first.replace(" spec.summary = 'A nice extension'\n") 108 | gemspec.grep(/spec\.description/).first.replace(" spec.description = 'A super nice extension'\n") 109 | gemspec_path.write(gemspec.join) 110 | 111 | expect(bundle_install).to match(/Bundle complete/) 112 | end 113 | 114 | def check_default_task 115 | cd(install_path) do 116 | output = sh("bin/rake") 117 | expect(output).to include("Generating dummy Rails application") 118 | expect(output).to include("0 examples, 0 failures") 119 | end 120 | end 121 | 122 | def check_run_specs 123 | install_path.join("lib", "solidus_test_extension", "testing_support", "factories.rb").open("a") do |factories_file| 124 | factories_file.write "\n puts 'loading test_extension factories'" 125 | end 126 | 127 | install_path.join("spec", "some_spec.rb").write( 128 | "require 'spec_helper'\nRSpec.describe 'Some test' do it { expect(true).to be_truthy } end\n" 129 | ) 130 | cd(install_path) do 131 | output = sh("bundle exec rspec") 132 | expect(output).to include("loading test_extension factories") 133 | expect(output).to include("1 example, 0 failures") 134 | expect(output).to include(ENV["CODECOV_TOKEN"] ? "Coverage reports upload successfully" : "Provide a CODECOV_COVERAGE_PATH environment variable to enable Codecov uploads") 135 | end 136 | end 137 | 138 | def check_sandbox 139 | cd(install_path) do 140 | command = 'bin/rails-sandbox runner "puts %{The version of SolidusTestExtension is #{SolidusTestExtension::VERSION}}"' 141 | 142 | first_run_output = sh(command) 143 | expect(first_run_output).to include("Creating the sandbox app...") 144 | expect(first_run_output).to include("The version of SolidusTestExtension is 0.0.1") 145 | 146 | second_run_output = sh(command) 147 | expect(second_run_output).not_to include("Creating the sandbox app...") 148 | expect(second_run_output).to include("The version of SolidusTestExtension is 0.0.1") 149 | end 150 | end 151 | 152 | def sh(*args) 153 | command = (args.size == 1) ? args.first : args.shelljoin 154 | output, status = with_unbundled_env do 155 | Open3.capture2e({"CI" => nil}, command) 156 | end 157 | 158 | if $DEBUG || ENV["DEBUG"] 159 | warn "~" * 80 160 | warn "$ #{command}" 161 | warn output 162 | warn "$ #{command} ~~~~> EXIT STATUS: #{status.exitstatus}" 163 | end 164 | 165 | unless status.success? 166 | raise(command_failed_error, "command failed: #{command}\n#{output}") 167 | end 168 | 169 | output.to_s 170 | end 171 | 172 | def with_unbundled_env(...) 173 | if Bundler.respond_to?(:with_unbundled_env) 174 | Bundler.with_unbundled_env(...) 175 | else 176 | Bundler.with_clean_env(...) 177 | end 178 | end 179 | 180 | def bundle_install 181 | # Optimize the bundle path within the CI, in this context using bundler env 182 | # variables doesn't help because commands are run with a clean env. 183 | bundle_path = "#{gem_root}/vendor/bundle" 184 | 185 | if File.exist?(bundle_path) 186 | sh "bundle config set --local path #{bundle_path.shellescape}" 187 | end 188 | 189 | output = nil 190 | cd(install_path) { output = sh "bundle install" } 191 | output 192 | end 193 | end 194 | -------------------------------------------------------------------------------- /spec/lib/extension_spec.rb: -------------------------------------------------------------------------------- 1 | require "solidus_dev_support/extension" 2 | 3 | RSpec.describe SolidusDevSupport::Extension do 4 | describe "#path=" do 5 | specify "with an existing extension" do 6 | allow(subject).to receive(:git).with("remote get-url origin", any_args).and_return("git@github.com:some_user/solidus_my_ext.git") 7 | allow(subject).to receive(:git).with("config user.name", any_args).and_return("John Doe") 8 | allow(subject).to receive(:git).with("config user.email", any_args).and_return("john.doe@example.com") 9 | 10 | allow(File).to receive(:exist?).with("/foo/bar/solidus_my_ext/solidus_my_ext.gemspec").and_return(true) 11 | allow(Gem::Specification).to receive(:load).with("/foo/bar/solidus_my_ext/solidus_my_ext.gemspec").and_return( 12 | Gem::Specification.new("solidus_my_ext", "0.1.1") do |gem| 13 | gem.author = "Jane Doe" 14 | gem.email = "jane.doe@example.com" 15 | 16 | gem.summary = "This extension is awesome!" 17 | gem.license = "MIT" 18 | 19 | gem.homepage = "some_user.github.io/solidus_my_ext" 20 | gem.metadata["changelog_uri"] = "https://github.com/some_user/solidus_my_ext/releases" 21 | gem.metadata["source_code_uri"] = "https://github.com/some_user/solidus_my_ext" 22 | end 23 | ) 24 | 25 | subject.path = "/foo/bar/solidus_my_ext" 26 | 27 | aggregate_failures do 28 | expect(subject.file_name).to eq("solidus_my_ext") 29 | expect(subject.class_name).to eq("SolidusMyExt") 30 | expect(subject.root).to eq("/foo/bar") 31 | expect(subject.path).to eq("/foo/bar/solidus_my_ext") 32 | expect(subject.repo).to eq("some_user/solidus_my_ext") 33 | expect(subject.gemspec.author).to eq("Jane Doe") 34 | expect(subject.gemspec.email).to eq("jane.doe@example.com") 35 | expect(subject.gemspec.summary).to eq("This extension is awesome!") 36 | expect(subject.gemspec.license).to eq("MIT") 37 | expect(subject.gemspec.homepage).to eq("some_user.github.io/solidus_my_ext") 38 | expect(subject.gemspec.metadata["changelog_uri"]).to eq("https://github.com/some_user/solidus_my_ext/releases") 39 | expect(subject.gemspec.metadata["source_code_uri"]).to eq("https://github.com/some_user/solidus_my_ext") 40 | end 41 | end 42 | 43 | specify "when creating a new extension" do 44 | allow(subject).to receive(:git).with("remote get-url origin", any_args) { |_, default| default } 45 | allow(subject).to receive(:git).with("config user.name", any_args).and_return("John Doe") 46 | allow(subject).to receive(:git).with("config user.email", any_args).and_return("john.doe@example.com") 47 | 48 | allow(Dir).to receive(:pwd).and_return("/foo/bar") 49 | 50 | subject.path = "/foo/bar/solidus_my_ext" 51 | 52 | aggregate_failures do 53 | expect(subject.file_name).to eq("solidus_my_ext") 54 | expect(subject.class_name).to eq("SolidusMyExt") 55 | expect(subject.root).to eq("/foo/bar") 56 | expect(subject.path).to eq("/foo/bar/solidus_my_ext") 57 | expect(subject.repo).to eq("solidusio-contrib/solidus_my_ext") 58 | expect(subject.gemspec.author).to eq("John Doe") 59 | expect(subject.gemspec.email).to eq("john.doe@example.com") 60 | expect(subject.gemspec.summary).to eq("TODO: Write a short summary, because RubyGems requires one.") 61 | expect(subject.gemspec.description).to eq("TODO: Write a longer description or delete this line.") 62 | expect(subject.gemspec.license).to eq("BSD-3-Clause") 63 | expect(subject.gemspec.homepage).to eq("https://github.com/solidusio-contrib/solidus_my_ext#readme") 64 | expect(subject.gemspec.metadata["changelog_uri"]).to eq("https://github.com/solidusio-contrib/solidus_my_ext/blob/main/CHANGELOG.md") 65 | expect(subject.gemspec.metadata["source_code_uri"]).to eq("https://github.com/solidusio-contrib/solidus_my_ext") 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/setup" 4 | require "solidus_dev_support" 5 | 6 | RSpec.configure do |config| 7 | # Enable flags like --only-failures and --next-failure 8 | config.example_status_persistence_file_path = ".rspec_status" 9 | 10 | # Disable RSpec exposing methods globally on `Module` and `main` 11 | config.disable_monkey_patching! 12 | 13 | config.expect_with :rspec do |c| 14 | c.syntax = :expect 15 | end 16 | end 17 | --------------------------------------------------------------------------------