diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b18fd29 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml new file mode 100644 index 0000000..f662094 --- /dev/null +++ b/.github/workflows/push_gem.yml @@ -0,0 +1,46 @@ +name: Publish gem to rubygems.org + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + +jobs: + push: + if: github.repository == 'ruby/ruby2_keywords' + runs-on: ubuntu-latest + + environment: + name: rubygems.org + url: https://rubygems.org/gems/ruby2_keywords + + permissions: + contents: write + id-token: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Set up Ruby + uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0 + with: + bundler-cache: true + ruby-version: "ruby" + + - name: Publish to RubyGems + uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1 + + - name: Create GitHub release + run: | + tag_name="$(git describe --tags --abbrev=0)" + gh release create "${tag_name}" --verify-tag --generate-notes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b79ea7d..5932c89 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,20 +1,56 @@ -name: ubuntu +name: test on: [push, pull_request] jobs: + ruby-versions: + uses: ruby/actions/.github/workflows/ruby_versions.yml@master + with: + engine: cruby + min_version: 2.1 + build: + needs: ruby-versions name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ '3.0', 2.7, 2.6, head ] + ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} os: [ ubuntu-latest, macos-latest, windows-latest ] + include: + - { os: ubuntu-latest, ruby: truffleruby-head } + - { os: macos-latest, ruby: truffleruby-head } + exclude: + - { os: macos-latest, ruby: 2.1 } + - { os: macos-latest, ruby: 2.2 } + - { os: macos-latest, ruby: 2.3 } + - { os: macos-latest, ruby: 2.4 } + - { os: macos-latest, ruby: 2.5 } runs-on: ${{ matrix.os }} steps: + - name: git config + run: | + git config --global core.autocrlf false + git config --global core.eol lf + git config --global advice.detachedHead 0 - uses: actions/checkout@master - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} + bundler-cache: true - name: Run test - run: rake test + run: bundle exec rake test + - id: build + run: | + rake build + echo "pkg=${GITHUB_REPOSITORY#*/}-${RUNNING_OS%-*}" >> $GITHUB_OUTPUT + env: + RUNNING_OS: ${{matrix.os}} + if: "matrix.ruby == '3.0'" + shell: bash + - name: Upload package + uses: actions/upload-artifact@v4 + with: + path: pkg/*.gem + name: ${{steps.build.outputs.pkg}} + if: steps.build.outputs.pkg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..230b7e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +ChangeLog +logs/ +gems.locked +pkg/ diff --git a/README.md b/README.md index 4cc0282..42e1157 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,14 @@ ruby2_keywords :delegating_method Bug reports and pull requests are welcome on [GitHub] or [Ruby Issue Tracking System]. +## Development + +After checking out the repo, run `bundle install` to install dependencies. +Then, run `bundle exec rake test` to run the tests. + +To test on older Ruby versions, you can use docker. E.g. to test on Ruby 2.0, +use `docker-compose run ruby-2.0`. + ## License The gem is available as open source under the terms of the diff --git a/Rakefile b/Rakefile index 8830e05..caacbf2 100644 --- a/Rakefile +++ b/Rakefile @@ -6,3 +6,11 @@ Rake::TestTask.new(:test) do |t| end task :default => :test + +task "bump:minor" do + raise "can't bump up minor" +end + +task "bump:major" do + raise "can't bump up major" +end diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3135f88 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,57 @@ +version: '3.0' + +services: + ruby-2.0: + image: ruby:2.0 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-2.1: + image: ruby:2.1 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-2.2: + image: ruby:2.2 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-2.3: + image: ruby:2.3 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-2.4: + image: ruby:2.4 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-2.5: + image: ruby:2.5 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-2.6: + image: ruby:2.6 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-2.7: + image: ruby:2.7 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' + ruby-3.0: + image: ruby:3.0 + volumes: + - .:/app + command: + bash -c 'cd /app && bundle install && bundle exec rake test' diff --git a/gems.rb b/gems.rb new file mode 100644 index 0000000..2b2a2c4 --- /dev/null +++ b/gems.rb @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +gemspec + +group :development do + gem "test-unit", ">= 2.2" + gem "rake" +end diff --git a/lib/ruby2_keywords.rb b/lib/ruby2_keywords.rb index 97cd081..09827b5 100644 --- a/lib/ruby2_keywords.rb +++ b/lib/ruby2_keywords.rb @@ -1,5 +1,5 @@ class Module - unless private_method_defined?(:ruby2_keywords, true) + unless private_method_defined?(:ruby2_keywords) private # call-seq: # ruby2_keywords(method_name, ...) @@ -11,7 +11,7 @@ def ruby2_keywords(name, *) end end -main = TOPLEVEL_BINDING.receiver +main = TOPLEVEL_BINDING.eval('self') unless main.respond_to?(:ruby2_keywords, true) # call-seq: # ruby2_keywords(method_name, ...) diff --git a/rakelib/changelogs.rake b/rakelib/changelogs.rake new file mode 100644 index 0000000..df72f9d --- /dev/null +++ b/rakelib/changelogs.rake @@ -0,0 +1,34 @@ +task "build" => "changelogs" + +changelog = proc do |output, ver = nil, prev = nil| + ver &&= Gem::Version.new(ver) + range = [[prev], [ver, "HEAD"]].map {|ver, branch| ver ? "v#{ver.to_s}" : branch}.compact.join("..") + IO.popen(%W[git log --format=fuller --topo-order --no-merges #{range}]) do |log| + line = log.gets + FileUtils.mkpath(File.dirname(output)) + File.open(output, "wb") do |f| + f.print "-*- coding: utf-8 -*-\n\n", line + log.each_line do |line| + line.sub!(/^(?!:)(?:Author|Commit)?(?:Date)?: /, ' \&') + line.sub!(/ +$/, '') + f.print(line) + end + end + end +end + +tags = IO.popen(%w[git tag -l v[0-9]*]).grep(/v(.*)/) {$1} +tags.sort_by! {|tag| tag.scan(/\d+/).map(&:to_i)} +tags.inject(nil) do |prev, tag| + task("logs/ChangeLog-#{tag}") {|t| changelog[t.name, tag, prev]} + tag +end + +desc "Make ChangeLog" +task "ChangeLog", [:ver, :prev] do |t, ver: nil, prev: tags.last| + changelog[t.name, ver, prev] +end + +changelogs = ["ChangeLog", *tags.map {|tag| "logs/ChangeLog-#{tag}"}] +task "changelogs" => changelogs +CLOBBER.concat(changelogs) << "logs" diff --git a/rakelib/epoch.rake b/rakelib/epoch.rake new file mode 100644 index 0000000..80f27c9 --- /dev/null +++ b/rakelib/epoch.rake @@ -0,0 +1,5 @@ +task "build" => "date_epoch" + +task "date_epoch" do + ENV["SOURCE_DATE_EPOCH"] = IO.popen(%W[git -C #{__dir__} log -1 --format=%ct], &:read).chomp +end diff --git a/rakelib/version.rake b/rakelib/version.rake new file mode 100644 index 0000000..bbb327f --- /dev/null +++ b/rakelib/version.rake @@ -0,0 +1,44 @@ +class << (helper = Bundler::GemHelper.instance) + def update_gemspec + path = gemspec.loaded_from + File.open(path, "r+b") do |f| + d = f.read + if d.sub!(/^(_VERSION\s*=\s*)".*"/) {$1 + gemspec.version.to_s.dump} + f.rewind + f.truncate(0) + f.print(d) + end + end + end + + def commit_bump + sh(%W[git commit -m bump\ up\ to\ #{gemspec.version} + #{gemspec.loaded_from}]) + end + + def version=(v) + gemspec.version = v + update_gemspec + commit_bump + end +end + +major, minor, teeny = helper.gemspec.version.segments + +task "bump:teeny" do + helper.version = Gem::Version.new("#{major}.#{minor}.#{teeny+1}") +end + +task "bump:minor" do + helper.version = Gem::Version.new("#{major}.#{minor+1}.0") +end + +task "bump:major" do + helper.version = Gem::Version.new("#{major+1}.0.0") +end + +task "bump" => "bump:teeny" + +task "tag" do + helper.__send__(:tag_version) +end diff --git a/ruby2_keywords.gemspec b/ruby2_keywords.gemspec index 5eac57b..e2cd397 100644 --- a/ruby2_keywords.gemspec +++ b/ruby2_keywords.gemspec @@ -1,18 +1,23 @@ -version = "0.0.3" -abort "Version must not reach 1" if version[/\d+/].to_i >= 1 +_VERSION = "0.0.5" +abort "Version must not reach 1" if _VERSION[/\d+/].to_i >= 1 Gem::Specification.new do |s| s.name = "ruby2_keywords" - s.version = version + s.version = _VERSION s.summary = "Shim library for Module#ruby2_keywords" s.homepage = "https://github.com/ruby/ruby2_keywords" s.licenses = ["Ruby", "BSD-2-Clause"] s.authors = ["Nobuyoshi Nakada"] s.require_paths = ["lib"] s.rdoc_options = ["--main", "README.md"] - s.files = [ + s.extra_rdoc_files = [ "LICENSE", "README.md", + "ChangeLog", + *Dir.glob("#{__dir__}/logs/ChangeLog-*[^~]").map {|path| path[(__dir__.size+1)..-1]}, + ] + s.files = [ "lib/ruby2_keywords.rb", ] + s.required_ruby_version = '>= 2.0.0' end diff --git a/test/test_keyword.rb b/test/test_keyword.rb index 5fcecb5..13d6041 100644 --- a/test/test_keyword.rb +++ b/test/test_keyword.rb @@ -22,7 +22,7 @@ def test_module_ruby2_keywords end def test_toplevel_ruby2_keywords - main = TOPLEVEL_BINDING.receiver + main = TOPLEVEL_BINDING.eval('self') assert_send([main, :respond_to?, :ruby2_keywords, true]) assert_operator(main.method(:ruby2_keywords).arity, :<, 0) end