rust-raspberrypi-OS-tutorials/utils/devtool.rb

348 lines
8.2 KiB
Ruby
Raw Normal View History

2020-01-09 21:11:56 +00:00
#!/usr/bin/env ruby
# frozen_string_literal: true
# SPDX-License-Identifier: MIT OR Apache-2.0
#
2022-01-15 20:50:11 +00:00
# Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
2020-01-09 21:11:56 +00:00
require 'rubygems'
require 'bundler/setup'
require 'colorize'
require 'fileutils'
require_relative 'devtool/copyright'
# Actions for tutorial folders.
2020-01-09 21:11:56 +00:00
class TutorialCrate
attr_reader :folder
def initialize(folder)
@folder = folder
end
def tutorial?
/[0-9]/.match?(@folder[0])
end
def clean
puts 'Cleaning '.light_blue + @folder
# No output needed.
Dir.chdir(@folder) { `make clean` }
2020-01-09 21:11:56 +00:00
end
2020-05-05 19:48:56 +00:00
def update
puts "\n\n"
2020-05-05 19:48:56 +00:00
puts 'Updating '.light_blue + @folder
Dir.chdir(@folder) { system('cargo update') }
end
2020-03-24 20:57:58 +00:00
def clippy(bsp)
puts "\n\n"
2020-03-24 20:57:58 +00:00
puts "Clippy #{@folder} - BSP: #{bsp}".light_blue
2020-01-09 21:11:56 +00:00
2020-03-24 20:57:58 +00:00
Dir.chdir(@folder) { exit(1) unless system("BSP=#{bsp} make clippy") }
2020-01-09 21:11:56 +00:00
end
2020-09-25 19:24:02 +00:00
def fmt_cargo_rust(args)
2020-01-09 21:11:56 +00:00
Dir.chdir(@folder) { exit(1) unless system("cargo fmt #{args}") }
end
def make(bsp)
puts "\n\n"
2020-01-09 21:11:56 +00:00
puts "Make #{@folder} - BSP: #{bsp}".light_blue
Dir.chdir(@folder) { exit(1) unless system("BSP=#{bsp} make") }
end
def test(bsp)
return unless boot_test?
2020-01-09 21:11:56 +00:00
puts "\n\n"
puts "Test #{@folder} - BSP: #{bsp}".light_blue
2020-01-09 21:11:56 +00:00
Dir.chdir(@folder) { exit(1) unless system("BSP=#{bsp} make test") }
2020-01-09 21:11:56 +00:00
end
def test_boot(bsp)
return unless boot_test?
2020-01-09 21:11:56 +00:00
puts "\n\n"
puts "Test Boot #{@folder} - BSP: #{bsp}".light_blue
2020-01-09 21:11:56 +00:00
Dir.chdir(@folder) { exit(1) unless system("BSP=#{bsp} make test_boot") }
end
def test_unit(bsp)
return unless unit_integration_tests?
puts "\n\n"
puts "Test Unit #{@folder} - BSP: #{bsp}".light_blue
Dir.chdir(@folder) { exit(1) unless system("BSP=#{bsp} make test_unit") }
end
def test_integration(bsp)
return unless unit_integration_tests?
puts "\n\n"
puts "Test Integration #{@folder} - BSP: #{bsp}".light_blue
Dir.chdir(@folder) { exit(1) unless system("BSP=#{bsp} make test_integration") }
2020-01-09 21:11:56 +00:00
end
private
def boot_test?
2022-04-22 21:10:03 +00:00
Dir.exist?("#{@folder}/kernel/tests")
end
def unit_integration_tests?
2022-04-22 21:10:03 +00:00
!Dir.glob("#{@folder}/kernel/tests/00_*.rs").empty?
2020-01-09 21:11:56 +00:00
end
end
# Forks commands to all applicable receivers.
2020-01-09 21:11:56 +00:00
class DevTool
def initialize
2020-09-25 19:24:02 +00:00
@user_has_supplied_crates = false
@bsp = bsp_from_env || SUPPORTED_BSPS.first
2020-01-09 21:11:56 +00:00
cl = user_supplied_crate_list || Dir['*/Cargo.toml'].sort
@crates = cl.map { |c| TutorialCrate.new(c.delete_suffix('/Cargo.toml')) }
2020-01-09 21:11:56 +00:00
end
def clean
@crates.each(&:clean)
end
2020-05-05 19:48:56 +00:00
def update
@crates.each(&:update)
end
def clippy(bsp = nil)
bsp ||= @bsp
2020-03-24 20:57:58 +00:00
@crates.each { |c| c.clippy(bsp) }
2020-01-09 21:11:56 +00:00
end
def diff
tuts = tutorials.map(&:folder)
padding = tuts.map(&:length).max
tuts[0..-2].each_with_index do |original, i|
update = tuts[i + 1]
diff_pair(original, update, padding)
end
end
2020-09-25 19:24:02 +00:00
def fmt
fmt_cargo_rust(check: false)
puts
fmt_prettier(check: false)
2020-01-09 21:11:56 +00:00
end
def fmt_check
2020-09-25 19:24:02 +00:00
fmt_cargo_rust(check: true)
puts
fmt_prettier(check: true)
2020-01-09 21:11:56 +00:00
end
def make(bsp = nil)
bsp ||= @bsp
2020-01-09 21:11:56 +00:00
@crates.each { |c| c.make(bsp) }
2020-01-09 21:11:56 +00:00
end
def make_xtra
return if @user_has_supplied_crates
puts "\n\n"
puts 'Make Xtra stuff'.light_blue
2021-03-20 09:47:39 +00:00
system('cd *_uart_chainloader && bash update.sh')
2020-01-09 21:11:56 +00:00
system('cd X1_JTAG_boot && bash update.sh')
end
def test(bsp = nil)
bsp ||= @bsp
2021-04-29 20:54:57 +00:00
@crates.each { |c| c.test(bsp) }
2021-04-29 20:54:57 +00:00
end
def test_boot(bsp = nil)
bsp ||= @bsp
@crates.each { |c| c.test_boot(bsp) }
2020-01-09 21:11:56 +00:00
end
def test_unit(bsp = nil)
bsp ||= @bsp
@crates.each { |c| c.test_unit(bsp) }
end
def test_integration(bsp = nil)
bsp ||= @bsp
@crates.each { |c| c.test_integration(bsp) }
2020-01-09 21:11:56 +00:00
end
def copyright
exit(1) unless copyright_check_files(copyright_source_files)
end
def misspell
puts 'Misspell'.light_blue
translations = ['README.CN.md', 'README.ES.md']
files = tracked_files.reject { |f| translations.include?(File.basename(f)) }
files = files.join(' ')
exit(1) unless system(".vendor/misspell -error #{files}")
2020-01-09 21:11:56 +00:00
end
def rubocop
puts 'Rubocop'.light_blue
2020-09-25 19:24:02 +00:00
exit(1) unless system('bundle exec rubocop')
2020-01-09 21:11:56 +00:00
end
def ready_for_publish_no_rust
2020-01-09 21:11:56 +00:00
clean
fmt
rubocop
copyright
2020-09-25 19:24:02 +00:00
diff
misspell
2020-01-09 21:11:56 +00:00
clean
end
def ready_for_publish
ready_for_publish_no_rust
make_xtra
clippy('rpi4')
clippy('rpi3')
test_boot('rpi3')
test_unit('rpi3')
test_integration('rpi3')
clean
end
2020-01-09 21:11:56 +00:00
private
SUPPORTED_BSPS = %w[rpi3 rpi4].freeze
def bsp_from_env
2022-04-22 21:10:03 +00:00
bsp = ENV.fetch('BSP', nil)
return bsp if SUPPORTED_BSPS.include?(bsp)
nil
end
2020-09-25 19:24:02 +00:00
def fmt_cargo_rust(check: false)
args = '-- --check' if check
2021-03-23 23:00:40 +00:00
@crates.each do |c|
print 'Rust cargo fmt '.light_blue
print "#{args} ".light_blue unless args.nil?
puts c.folder
Process.fork { c.fmt_cargo_rust(args) }
end
Process.waitall
2020-09-25 19:24:02 +00:00
end
def fmt_prettier(check: false)
args = if check
'--check'
else
'--write'
end
args += if @user_has_supplied_crates
" #{@crates.map(&:folder).join(' ')}"
else
' .'
end
puts 'Prettier:'.light_blue
exit(1) unless system("./node_modules/.bin/prettier #{args}")
end
def user_supplied_crate_list
folders = ARGV.drop(1)
return nil if folders.empty?
2020-09-24 20:41:42 +00:00
crates = folders.map { |d| "#{d}/Cargo.toml" }.sort
crates.each do |c|
unless File.exist?(c)
puts "Crate not found: #{c}"
exit(1)
end
end
@user_has_supplied_crates = true
crates
end
2020-01-09 21:11:56 +00:00
def tutorials
@crates.select(&:tutorial?)
end
def tracked_files
crate_list = @crates.map(&:folder).join(' ') if @user_has_supplied_crates
`git ls-files #{crate_list}`.split("\n") # crates_list == nil means all files
2020-01-09 21:11:56 +00:00
end
def diff_pair(original, update, padding)
# Only diff adjacent tutorials. This checks the numbers of the tutorial folders.
return unless original[0..1].to_i + 1 == update[0..1].to_i
# Skip for tutorial 11. Due to the change to virtual manifest, the diff is rather
# unreadable.
if original[0..1].to_i == 11
puts 'Skipping '.light_yellow +
"#{original}: Too noisy due to change to virtual manifest"
return
end
puts 'Diffing '.light_blue + original.ljust(padding) + " -> #{update}"
2020-01-09 21:11:56 +00:00
system("bash utils/diff_tut_folders.bash #{original} #{update}")
end
def copyright_source_files
extensions = ['.S', '.rs', '.rb']
2020-11-14 09:25:00 +00:00
# NOTE: The selection result is the return value of the function.
2020-07-13 20:07:01 +00:00
tracked_files.select do |f|
2020-01-16 21:06:43 +00:00
next unless File.exist?(f)
next if f.include?('build.rs')
next if f.include?('boot_test_string.rb')
2020-01-16 21:06:43 +00:00
2020-01-09 21:11:56 +00:00
f.include?('Makefile') ||
f.include?('Dockerfile') ||
extensions.include?(File.extname(f))
end
end
end
##--------------------------------------------------------------------------------------------------
## Execution starts here
##--------------------------------------------------------------------------------------------------
tool = DevTool.new
cmd = ARGV[0]
commands = tool.public_methods(false).sort
2020-11-08 22:50:20 +00:00
if commands.include?(cmd&.to_sym)
tool.public_send(cmd)
else
puts "Usage: ./#{__FILE__.split('/').last} COMMAND [optional list of folders]"
2020-01-09 21:11:56 +00:00
puts
puts 'Commands:'
commands.each { |m| puts " #{m}" }
2022-04-25 21:37:21 +00:00
exit(1)
2020-01-09 21:11:56 +00:00
end