From cbfb57459f8395676e53ed4abad23cdbedd3b36b Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 10 Sep 2020 16:59:53 +0200 Subject: [PATCH] Ensure `file` is relative to `GITHUB_WORKSPACE`. (#4) * Ensure `file` is relative to `GITHUB_WORKSPACE`. * Simplify implementation of `relative_path` and add tests. * Run `ci` workflow on `pull_request` event. Co-authored-by: Stef Schenkelaars --- .github/workflows/ci.yml | 2 +- lib/rspec/github/formatter.rb | 7 ++++ spec/rspec/github/formatter_spec.rb | 59 ++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ee5119..acc3aa2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,5 @@ name: CI -on: [push] +on: [pull_request, push] jobs: reviewdog: runs-on: ubuntu-latest diff --git a/lib/rspec/github/formatter.rb b/lib/rspec/github/formatter.rb index ff5e007..aadb518 100644 --- a/lib/rspec/github/formatter.rb +++ b/lib/rspec/github/formatter.rb @@ -8,13 +8,20 @@ module Github class Formatter < RSpec::Core::Formatters::BaseFormatter RSpec::Core::Formatters.register self, :example_failed, :example_pending + def self.relative_path(path) + workspace = File.realpath(ENV.fetch('GITHUB_WORKSPACE', '.')) + File.realpath(path).delete_prefix("#{workspace}#{File::SEPARATOR}") + end + def example_failed(failure) file, line = failure.example.location.split(':') + file = self.class.relative_path(file) output.puts "\n::error file=#{file},line=#{line}::#{failure.message_lines.join('%0A')}" end def example_pending(pending) file, line = pending.example.location.split(':') + file = self.class.relative_path(file) output.puts "\n::warning file=#{file},line=#{line}::#{pending.example.full_description}" end end diff --git a/spec/rspec/github/formatter_spec.rb b/spec/rspec/github/formatter_spec.rb index 8d6d0c9..7b7b6b9 100644 --- a/spec/rspec/github/formatter_spec.rb +++ b/spec/rspec/github/formatter_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'tmpdir' + RSpec.describe RSpec::Github::Formatter do let(:output) { StringIO.new } let(:formatter) { described_class.new(output) } @@ -22,6 +24,59 @@ ) end + before do + allow(File).to receive(:realpath).and_call_original + allow(File).to receive(:realpath).with('./spec/models/user_spec.rb') + .and_return(File.join(Dir.pwd, 'spec/models/user_spec.rb')) + end + + describe '::relative_path' do + around do |example| + saved_github_workspace = ENV['GITHUB_WORKSPACE'] + ENV['GITHUB_WORKSPACE'] = github_workspace + + FileUtils.mkpath File.dirname(absolute_path) + FileUtils.touch absolute_path + + Dir.chdir tmpdir do + example.run + end + ensure + FileUtils.rm_r tmpdir + ENV['GITHUB_WORKSPACE'] = saved_github_workspace + end + + let(:tmpdir) { Dir.mktmpdir } + let(:relative_path) { 'this/is/a/relative_path.rb' } + let(:absolute_path) { File.join(tmpdir, relative_path) } + + context 'if GITHUB_WORKSPACE is set' do + let(:github_workspace) { tmpdir } + + it 'returns the path relative to it when already inside it' do + expect(described_class.relative_path('this/is/a/relative_path.rb')).to eq('this/is/a/relative_path.rb') + end + + it 'returns the path relative to it when in a subdirectory of it' do + Dir.chdir 'this/is' do + expect(described_class.relative_path('a/relative_path.rb')).to eq('this/is/a/relative_path.rb') + end + end + end + + context 'if GITHUB_WORKSPACE is unset' do + let(:github_workspace) { nil } + + it 'returns the unchanged relative path' do + expect(described_class.relative_path('this/is/a/relative_path.rb')).to eq 'this/is/a/relative_path.rb' + end + + it 'returns the relative path without a ./ prefix' do + expect(described_class.relative_path('./this/is/a/relative_path.rb')).to eq 'this/is/a/relative_path.rb' + end + end + end + describe '#example_failed' do before { formatter.example_failed(notification) } @@ -43,7 +98,7 @@ it 'outputs the GitHub annotation formatted error' do is_expected.to eq <<~MESSAGE - ::error file=./spec/models/user_spec.rb,line=12::#{notification.message_lines.join('%0A')} + ::error file=spec/models/user_spec.rb,line=12::#{notification.message_lines.join('%0A')} MESSAGE end end @@ -61,7 +116,7 @@ it 'outputs the GitHub annotation formatted error' do is_expected.to eq <<~MESSAGE - ::warning file=./spec/models/user_spec.rb,line=12::#{example.full_description} + ::warning file=spec/models/user_spec.rb,line=12::#{example.full_description} MESSAGE end end