Port auto-style to GitHub Actions
This commit is contained in:
parent
8c6f250dcf
commit
3e1dae8d2a
Notes:
git
2025-04-17 23:53:08 +00:00
15
.github/workflows/check_misc.yml
vendored
15
.github/workflows/check_misc.yml
vendored
@ -28,15 +28,20 @@ jobs:
|
|||||||
# Skip overwriting MATZBOT_GITHUB_TOKEN
|
# Skip overwriting MATZBOT_GITHUB_TOKEN
|
||||||
checkout: '' # false (ref: https://github.com/actions/runner/issues/2238)
|
checkout: '' # false (ref: https://github.com/actions/runner/issues/2238)
|
||||||
|
|
||||||
|
# Run this step first to make sure auto-style commits are pushed
|
||||||
|
- name: ${{ (github.repository == 'ruby/ruby' && github.ref == 'refs/heads/master') && 'Auto-correct' || 'Check for' }} code styles
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
ruby tool/auto-style.rb "$GITHUB_OLD_SHA" "$GITHUB_NEW_SHA" "$PUSH_REF"
|
||||||
|
env:
|
||||||
|
GITHUB_OLD_SHA: ${{ startsWith(github.event_name, 'pull') && github.event.pull_request.base.sha || github.before }}
|
||||||
|
GITHUB_NEW_SHA: ${{ startsWith(github.event_name, 'pull') && github.event.pull_request.merge_commit_sha || github.sha }}
|
||||||
|
PUSH_REF: ${{ (github.repository == 'ruby/ruby' && github.ref == 'refs/heads/master') && github.ref || '' }}
|
||||||
|
|
||||||
- name: Check if C-sources are US-ASCII
|
- name: Check if C-sources are US-ASCII
|
||||||
run: |
|
run: |
|
||||||
grep -r -n --include='*.[chyS]' --include='*.asm' $'[^\t-~]' -- . && exit 1 || :
|
grep -r -n --include='*.[chyS]' --include='*.asm' $'[^\t-~]' -- . && exit 1 || :
|
||||||
|
|
||||||
# - name: Check for trailing spaces
|
|
||||||
# run: |
|
|
||||||
# git grep -I -n $'[\t ]$' -- '*.rb' '*.[chy]' '*.rs' '*.yml' && exit 1 || :
|
|
||||||
# git grep -n $'^[\t ][\t ]*$' -- '*.md' && exit 1 || :
|
|
||||||
|
|
||||||
- name: Check for bash specific substitution in configure.ac
|
- name: Check for bash specific substitution in configure.ac
|
||||||
run: |
|
run: |
|
||||||
git grep -n '\${[A-Za-z_0-9]*/' -- configure.ac && exit 1 || :
|
git grep -n '\${[A-Za-z_0-9]*/' -- configure.ac && exit 1 || :
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# Usage:
|
# Usage:
|
||||||
# auto-style.rb [repo_path] [args...]
|
# auto-style.rb [oldrev] [newrev] [pushref]
|
||||||
|
|
||||||
require 'shellwords'
|
require 'shellwords'
|
||||||
require 'tmpdir'
|
require 'tmpdir'
|
||||||
@ -9,10 +9,15 @@ ENV['LC_ALL'] = 'C'
|
|||||||
class Git
|
class Git
|
||||||
attr_reader :depth
|
attr_reader :depth
|
||||||
|
|
||||||
def initialize(oldrev, newrev, branch)
|
def initialize(oldrev, newrev, branch = nil)
|
||||||
@oldrev = oldrev
|
@oldrev = oldrev
|
||||||
@newrev = newrev
|
@newrev = newrev
|
||||||
@branch = branch
|
@branch = branch
|
||||||
|
|
||||||
|
# GitHub may not fetch github.event.pull_request.base.sha at checkout
|
||||||
|
git('fetch', '--depth=1', 'origin', @oldrev)
|
||||||
|
git('fetch', '--depth=100', 'origin', @newrev)
|
||||||
|
|
||||||
with_clean_env do
|
with_clean_env do
|
||||||
@revs = {}
|
@revs = {}
|
||||||
IO.popen(['git', 'log', '--format=%H %s', "#{@oldrev}..#{@newrev}"]) do |f|
|
IO.popen(['git', 'log', '--format=%H %s', "#{@oldrev}..#{@newrev}"]) do |f|
|
||||||
@ -34,7 +39,7 @@ class Git
|
|||||||
end
|
end
|
||||||
|
|
||||||
# [0, 1, 4, ...]
|
# [0, 1, 4, ...]
|
||||||
def updated_lines(file)
|
def updated_lines(file) # NOTE: This doesn't work well on pull requests, so not used anymore
|
||||||
lines = []
|
lines = []
|
||||||
revs = @revs.map {|rev, subj| rev unless subj.start_with?("Revert ")}.compact
|
revs = @revs.map {|rev, subj| rev unless subj.start_with?("Revert ")}.compact
|
||||||
revs_pattern = /\A(?:#{revs.join('|')}) /
|
revs_pattern = /\A(?:#{revs.join('|')}) /
|
||||||
@ -49,13 +54,21 @@ class Git
|
|||||||
def commit(log, *files)
|
def commit(log, *files)
|
||||||
git('add', *files)
|
git('add', *files)
|
||||||
git('commit', '-m', log)
|
git('commit', '-m', log)
|
||||||
|
end
|
||||||
|
|
||||||
|
def push
|
||||||
git('push', 'origin', @branch)
|
git('push', 'origin', @branch)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def diff
|
||||||
|
git('--no-pager', 'diff')
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def git(*args)
|
def git(*args)
|
||||||
cmd = ['git', *args].shelljoin
|
cmd = ['git', *args].shelljoin
|
||||||
|
puts "+ #{cmd}"
|
||||||
unless with_clean_env { system(cmd) }
|
unless with_clean_env { system(cmd) }
|
||||||
abort "Failed to run: #{cmd}"
|
abort "Failed to run: #{cmd}"
|
||||||
end
|
end
|
||||||
@ -160,80 +173,79 @@ IGNORED_FILES = [
|
|||||||
%r{\Asample/trick[^/]*/},
|
%r{\Asample/trick[^/]*/},
|
||||||
]
|
]
|
||||||
|
|
||||||
repo_path, *rest = ARGV
|
oldrev, newrev, pushref = ARGV
|
||||||
rest.each_slice(3).map do |oldrev, newrev, refname|
|
unless dry_run = pushref.empty?
|
||||||
branch = IO.popen({ 'GIT_DIR' => repo_path }, ['git', 'rev-parse', '--symbolic', '--abbrev-ref', refname], &:read).strip
|
branch = IO.popen(['git', 'rev-parse', '--symbolic', '--abbrev-ref', pushref], &:read).strip
|
||||||
next if branch != 'master' # Stable branches are on svn, and for consistency we should not make a git-specific commit.
|
end
|
||||||
vcs = Git.new(oldrev, newrev, branch)
|
git = Git.new(oldrev, newrev, branch)
|
||||||
|
|
||||||
Dir.mktmpdir do |workdir|
|
paths = git.updated_paths
|
||||||
depth = vcs.depth + 1
|
paths.select! {|l|
|
||||||
system "git clone --depth=#{depth} --branch=#{branch} file:///#{repo_path} #{workdir}"
|
/^\d/ !~ l and /\.bat\z/ !~ l and
|
||||||
Dir.chdir(workdir)
|
(/\A(?:config|[Mm]akefile|GNUmakefile|README)/ =~ File.basename(l) or
|
||||||
|
/\A\z|\.(?:[chsy]|\d+|e?rb|tmpl|bas[eh]|z?sh|in|ma?k|def|src|trans|rdoc|ja|en|el|sed|awk|p[ly]|scm|mspec|html|)\z/ =~ File.extname(l))
|
||||||
|
}
|
||||||
|
files = paths.select {|n| File.file?(n) }
|
||||||
|
files.reject! do |f|
|
||||||
|
IGNORED_FILES.any? { |re| f.match(re) }
|
||||||
|
end
|
||||||
|
if files.empty?
|
||||||
|
puts "No files are a auto-style target:\n#{paths.join("\n")}"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
paths = vcs.updated_paths
|
trailing = eofnewline = expandtab = false
|
||||||
paths.select! {|l|
|
|
||||||
/^\d/ !~ l and /\.bat\z/ !~ l and
|
edited_files = files.select do |f|
|
||||||
(/\A(?:config|[Mm]akefile|GNUmakefile|README)/ =~ File.basename(l) or
|
src = File.binread(f) rescue next
|
||||||
/\A\z|\.(?:[chsy]|\d+|e?rb|tmpl|bas[eh]|z?sh|in|ma?k|def|src|trans|rdoc|ja|en|el|sed|awk|p[ly]|scm|mspec|html|)\z/ =~ File.extname(l))
|
eofnewline = eofnewline0 = true if src.sub!(/(?<!\A|\n)\z/, "\n")
|
||||||
}
|
|
||||||
files = paths.select {|n| File.file?(n) }
|
trailing0 = false
|
||||||
files.reject! do |f|
|
expandtab0 = false
|
||||||
IGNORED_FILES.any? { |re| f.match(re) }
|
src.gsub!(/^.*$/).with_index do |line, lineno|
|
||||||
|
trailing = trailing0 = true if line.sub!(/[ \t]+$/, '')
|
||||||
|
line
|
||||||
|
end
|
||||||
|
|
||||||
|
if f.end_with?('.c') || f.end_with?('.h') || f == 'insns.def'
|
||||||
|
# If and only if unedited lines did not have tab indentation, prevent introducing tab indentation to the file.
|
||||||
|
expandtab_allowed = src.each_line.with_index.all? do |line, lineno|
|
||||||
|
!line.start_with?("\t")
|
||||||
end
|
end
|
||||||
next if files.empty?
|
|
||||||
|
|
||||||
trailing = eofnewline = expandtab = false
|
if expandtab_allowed
|
||||||
|
src.gsub!(/^.*$/).with_index do |line, lineno|
|
||||||
edited_files = files.select do |f|
|
if line.start_with?("\t") # last-committed line with hard tabs
|
||||||
src = File.binread(f) rescue next
|
expandtab = expandtab0 = true
|
||||||
eofnewline = eofnewline0 = true if src.sub!(/(?<!\A|\n)\z/, "\n")
|
line.sub(/\A\t+/) { |tabs| ' ' * (8 * tabs.length) }
|
||||||
|
else
|
||||||
trailing0 = false
|
|
||||||
expandtab0 = false
|
|
||||||
updated_lines = vcs.updated_lines(f)
|
|
||||||
if !updated_lines.empty?
|
|
||||||
src.gsub!(/^.*$/).with_index do |line, lineno|
|
|
||||||
if updated_lines.include?(lineno)
|
|
||||||
trailing = trailing0 = true if line.sub!(/[ \t]+$/, '')
|
|
||||||
end
|
|
||||||
line
|
line
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !updated_lines.empty? && (f.end_with?('.c') || f.end_with?('.h') || f == 'insns.def')
|
|
||||||
# If and only if unedited lines did not have tab indentation, prevent introducing tab indentation to the file.
|
|
||||||
expandtab_allowed = src.each_line.with_index.all? do |line, lineno|
|
|
||||||
updated_lines.include?(lineno) || !line.start_with?("\t")
|
|
||||||
end
|
|
||||||
|
|
||||||
if expandtab_allowed
|
|
||||||
src.gsub!(/^.*$/).with_index do |line, lineno|
|
|
||||||
if updated_lines.include?(lineno) && line.start_with?("\t") # last-committed line with hard tabs
|
|
||||||
expandtab = expandtab0 = true
|
|
||||||
line.sub(/\A\t+/) { |tabs| ' ' * (8 * tabs.length) }
|
|
||||||
else
|
|
||||||
line
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if trailing0 or eofnewline0 or expandtab0
|
|
||||||
File.binwrite(f, src)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
unless edited_files.empty?
|
|
||||||
msg = [('remove trailing spaces' if trailing),
|
|
||||||
('append newline at EOF' if eofnewline),
|
|
||||||
('expand tabs' if expandtab),
|
|
||||||
].compact
|
|
||||||
message = "* #{msg.join(', ')}. [ci skip]"
|
|
||||||
if expandtab
|
|
||||||
message += "\nPlease consider using misc/expand_tabs.rb as a pre-commit hook."
|
|
||||||
end
|
|
||||||
vcs.commit(message, *edited_files)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if trailing0 or eofnewline0 or expandtab0
|
||||||
|
File.binwrite(f, src)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if edited_files.empty?
|
||||||
|
puts "All edited lines are formatted well:\n#{paths.join("\n")}"
|
||||||
|
else
|
||||||
|
msg = [('remove trailing spaces' if trailing),
|
||||||
|
('append newline at EOF' if eofnewline),
|
||||||
|
('expand tabs' if expandtab),
|
||||||
|
].compact
|
||||||
|
message = "* #{msg.join(', ')}. [ci skip]"
|
||||||
|
if expandtab
|
||||||
|
message += "\nPlease consider using misc/expand_tabs.rb as a pre-commit hook."
|
||||||
|
end
|
||||||
|
if dry_run
|
||||||
|
git.diff
|
||||||
|
abort message
|
||||||
|
else
|
||||||
|
git.commit(message, *edited_files)
|
||||||
|
git.push
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user