diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-07 02:25:34 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-07 02:25:34 +0200 |
| commit | f9dfefc52fc792099b622ae47dafa32d2512e51e (patch) | |
| tree | 3be1fdc6d29bf04dc460684794ebfc566f7a2662 | |
| parent | e38f23a1bd6e0ee093655e1f241e524795f21fec (diff) | |
| download | elna-f9dfefc52fc792099b622ae47dafa32d2512e51e.tar.gz | |
Add some useful gems for ruby code
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | .rubocop.yml | 30 | ||||
| -rw-r--r-- | Gemfile | 12 | ||||
| -rw-r--r-- | Gemfile.lock | 139 | ||||
| -rw-r--r-- | Rakefile | 7 | ||||
| -rw-r--r-- | rakelib/compiler.rake | 7 | ||||
| -rw-r--r-- | rakelib/doc.rake | 1 | ||||
| -rw-r--r-- | rakelib/gcc.rake | 215 | ||||
| -rw-r--r-- | rakelib/ruby.rake | 11 | ||||
| -rw-r--r-- | rakelib/support/ui.rb | 25 | ||||
| -rw-r--r-- | rakelib/treesitter.rake | 9 |
11 files changed, 336 insertions, 124 deletions
@@ -3,6 +3,10 @@ jit/ .cache/ /compile_commands.json +# Tree-sitter. *.o *.so node_modules/ + +# Ruby. +/vendor/ diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..d69ffc7 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,30 @@ +plugins: + - rubocop-rake + +AllCops: + TargetRubyVersion: 4.0 + NewCops: enable + SuggestExtensions: false + Include: + - 'Rakefile' + - 'rakelib/**/*' + +Metrics/BlockLength: + AllowedMethods: + - namespace + - task + +Layout/ArgumentAlignment: + EnforcedStyle: with_fixed_indentation + +Layout/ParameterAlignment: + EnforcedStyle: with_fixed_indentation + +Layout/ArrayAlignment: + EnforcedStyle: with_fixed_indentation + +Layout/MultilineMethodCallIndentation: + EnforcedStyle: indented + +Layout/MultilineOperationIndentation: + EnforcedStyle: indented @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gem 'rake', '~> 13.4' +gem 'rubocop', '~> 1.91' +gem 'rubocop-rake', '~> 0.7' + +gem 'faraday', '~> 2.14' +gem 'faraday-follow_redirects', '~> 0.5' + +gem 'term-ansicolor', '~> 1.11' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..1c40795 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,139 @@ +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.3) + bigdecimal (4.1.3) + erb (6.0.7) + faraday (2.14.4) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-follow_redirects (0.5.0) + faraday (>= 1, < 3) + faraday-net_http (3.4.4) + net-http (~> 0.5) + io-console (0.9.4) + irb (1.18.0) + pp (>= 0.6.0) + prism (>= 1.3.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + json (3.0.2) + language_server-protocol (3.17.0.6) + lint_roller (1.1.0) + logger (1.7.0) + mize (0.6.1) + net-http (0.9.1) + uri (>= 0.11.1) + parallel (2.3.0) + parser (3.3.12.0) + ast (~> 2.4.1) + racc + pp (0.6.4) + prettyprint + prettyprint (0.2.0) + prism (1.9.0) + racc (1.8.1) + rainbow (3.1.1) + rake (13.4.2) + rbs (4.2.0) + logger + prism (>= 1.6.0) + tsort + rdoc (8.1.0) + erb + prism (>= 1.6.0) + rbs (>= 4.0.0) + tsort + readline (0.0.4) + reline + regexp_parser (2.13.1) + reline (0.7.0) + io-console (~> 0.5) + rubocop (1.91.0) + json (>= 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (>= 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.49.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.50.0) + parser (>= 3.3.7.2) + prism (~> 1.7) + rubocop-rake (0.7.1) + lint_roller (~> 1.1) + rubocop (>= 1.72.1) + ruby-progressbar (1.13.0) + sync (0.5.0) + term-ansicolor (1.11.3) + tins (~> 1) + tins (1.60.0) + bigdecimal + irb + mize (~> 0.6) + readline + sync + tsort (0.2.0) + unicode-display_width (3.3.0) + unicode-emoji (~> 4.3) + unicode-emoji (4.3.0) + uri (1.1.1) + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + faraday (~> 2.14) + faraday-follow_redirects (~> 0.5) + rake (~> 13.4) + rubocop (~> 1.91) + rubocop-rake (~> 0.7) + term-ansicolor (~> 1.11) + +CHECKSUMS + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + bigdecimal (4.1.3) sha256=61ebe1e5e559bdc3cc6f2c0ee7f427321fc838f59611c294356eb04d6e21cf66 + erb (6.0.7) sha256=c5ca6dc25b0ef974a44dc8f59fe847577122483b1968a38dec305c60bf91ee92 + faraday (2.14.4) sha256=9bb4408c44621b0dbaaaa39e5dbfc4dbe58cc6751b6eb94d16ae9e1f2f2fab6e + faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad + faraday-net_http (3.4.4) sha256=0e78af151747ed1b00f33e25973b4bc220d7f16c00c39676817c8b12331eb588 + io-console (0.9.4) sha256=a403304f32928ee85e56d457b4612ca43f2703b561a3258844992bd24085fbb1 + irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 + json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df + language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0 + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + mize (0.6.1) sha256=4031558979ff5426fda24c75a149b4e4c0faf4cacf2fae8938f83866ab94b780 + net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 + parallel (2.3.0) sha256=f75a3e904101ce6a1ccb6b8dc800cbafd42166d83330192438dcf29395167a6f + parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828 + pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570 + prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + rbs (4.2.0) sha256=51f7b886dcc05bc09e10b901daa6a81829f6adc03101d6ca9ea4aac6103e0674 + rdoc (8.1.0) sha256=befc37880a5cfd36dcb176c748b5fd5ee39dd3536a75e81824e4972ce230f60a + readline (0.0.4) sha256=6138eef17be2b98298b672c3ea63bf9cb5158d401324f26e1e84f235879c1d6a + regexp_parser (2.13.1) sha256=5aedb6b7c35688f51e86eef17a15374dfd287c83f4ca644b2c5f3ec50a33b44b + reline (0.7.0) sha256=5b012d8e55dbf9d450f12bde2cf7d15ff546ae80b3f8f3b30e570d431815583d + rubocop (1.91.0) sha256=9c82b7bf391c5d7e3798c5b9996e22a1fe3bd7468e351dfdeb96140c058296d0 + rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db + rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + sync (0.5.0) sha256=668356cc07c59ac7ed9ecf34fec3929831f179c07adb1f3e1c3b7a1609a638fd + term-ansicolor (1.11.3) sha256=8c01ec3abd095eb94dca8aed5a127d36e594239eb525eb306259c9e930534603 + tins (1.60.0) sha256=919f9b6e4cc3aa0d80fb37d43118c8fb093462a4482bbcf2728bde47d4a80791 + tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f + unicode-display_width (3.3.0) sha256=4b7aa66a4b11db50f6f7e98411215cd0dd10eaecb665d36eec5bcacb3fa0b613 + unicode-emoji (4.3.0) sha256=11c02fa73290378c066bb0562cd4c87d8e1b706fbbe0059ca12746a4244de8ce + uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 + +BUNDLED WITH + 4.0.20 @@ -7,9 +7,8 @@ require 'rake/clean' CLOBBER.include 'build' -task default: 'source/main.elna' -task default: 'build/gcc/elna' do |t| - sources, compiler = t.prerequisites.partition { |f| f.end_with? '.elna' } +task default: ['source/main.elna', 'build/gcc/elna'] do |t| + sources, compiler = t.prerequisites.partition { |f| f.end_with? '.elna' } - sh *compiler, '--parse', *sources + sh(*compiler, '--parse', *sources) end diff --git a/rakelib/compiler.rake b/rakelib/compiler.rake index f443407..4731e1d 100644 --- a/rakelib/compiler.rake +++ b/rakelib/compiler.rake @@ -11,7 +11,7 @@ CLEAN.include 'build/gcc' Rake.application.add_loader('d', Rake::MakefileLoader.new) FileList['build/gcc/**/*.d'].each { |file| import file } -rule(/gcc\/.+\.o$/ => ->(file) { +rule(%r{gcc/.+\.o$} => lambda { |file| source = Pathname.new('source') + Pathname.new(file).relative_path_from('build/gcc').sub_ext('.elna') @@ -22,9 +22,8 @@ rule(/gcc\/.+\.o$/ => ->(file) { sh t.prerequisites.last, '-c', '-MD', '-MP', '-O0', '-g', '-I', 'source', '-o', t.name, t.source.to_s end -file 'build/gcc/elna' => FileList['source/**/*.elna'].reject { |file| - file != file.downcase -}.map { |file| +sources = FileList['source/**/*.elna'].select { |file| file == file.downcase } +file 'build/gcc/elna' => sources.map { |file| Pathname.new('build/gcc') + Pathname.new(file).relative_path_from('source').sub_ext('.o') } do |t| diff --git a/rakelib/doc.rake b/rakelib/doc.rake index 5f40107..bf92293 100644 --- a/rakelib/doc.rake +++ b/rakelib/doc.rake @@ -18,6 +18,7 @@ rule '.bbl' => '.bcf' do |t| end namespace :doc do + desc 'Compile LaTeX documentation' task tex: 'build/doc' do |t| sh 'pdflatex', '-output-directory', "../#{t.prerequisites.first}", 'report', chdir: 'doc' diff --git a/rakelib/gcc.rake b/rakelib/gcc.rake index 7ee9f5c..6dce877 100644 --- a/rakelib/gcc.rake +++ b/rakelib/gcc.rake @@ -5,8 +5,18 @@ require 'fileutils' require 'uri' -require 'net/http' -require 'open3' +require 'faraday' +require 'faraday/follow_redirects' +require 'English' +require_relative 'support/ui' + +# Dependencies. +GCC_VERSION = '16.2.0' +GCC_HOST = 'build/host/gcc' +GCC_HOST_INSTALL = Pathname.new 'build/host/install' +GCC_TREE = Pathname.new "build/tools/gcc-#{GCC_VERSION}" +GCC_PATCH = + "https://raw.githubusercontent.com/Homebrew/homebrew-core/refs/heads/main/Patches/gcc/gcc-#{GCC_VERSION}.diff".freeze # Use Homebrew GCC if available (it uses libstdc++, avoiding # macOS-specific libc++ incompatibilities in GCC's own sources). @@ -34,59 +44,50 @@ end def gcc_verbose(gcc_binary) read, write = IO.pipe - sh({'LC_ALL' => 'C'}, gcc_binary, '--verbose', err: write) + sh({ 'LC_ALL' => 'C' }, gcc_binary, '--verbose', err: write) write.close output = read.read read.close output end -def find_build_target(gcc_version) - if RUBY_PLATFORM =~ /darwin/ - suffix = '-' + gcc_version.split('.').first - mac_os_sdk = '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk' - else - suffix = '' - end - build_target = gcc_verbose(ENV.fetch 'CC', "gcc#{suffix}") +def target_triple(cc_name) + gcc_verbose(cc_name) .lines .find { |line| line.start_with? 'Target: ' } - .split(' ') + .split .last .strip +end + +def find_build_target(gcc_version) + is_darwin = RUBY_PLATFORM =~ /darwin/ + suffix = is_darwin ? "-#{gcc_version.split('.').first}" : '' + mac_os_sdk = '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk' if is_darwin + build_target = target_triple(ENV.fetch('CC', "gcc#{suffix}")) GCCConfiguration.new suffix, build_target, mac_os_sdk end +def pipe_to_command(command, chdir:, &) + IO.popen(command, 'w', chdir:, &) + UI.fatal "Command #{command.join(' ')} failed" unless $CHILD_STATUS.success? +end + +def stream_http(url, &) + conn = Faraday.new do |f| + f.response :follow_redirects + f.response :raise_error + end + conn.get(url) do |req| + req.options.on_data = ->(chunk, _, env) { yield chunk if (200..299).cover?(env.status) && !chunk.empty? } + end +end + def download_and_pipe(url, target, command) target.mkpath - - Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https') do |http| - request = Net::HTTP::Get.new url.request_uri - - http.request request do |response| - case response - when Net::HTTPRedirection - download_and_pipe URI.parse(response['location']), target, command - when Net::HTTPSuccess - Dir.chdir target.to_path do - Open3.popen2(*command) do |stdin, stdout, wait_thread| - Thread.new do - stdout.each { |line| puts line } - end - - response.read_body do |chunk| - stdin.write chunk - end - stdin.close - - wait_thread.value - end - end - else - response.error! - end - end + pipe_to_command(command, chdir: target.to_path) do |stdin| + stream_http(url) { |chunk| stdin.write chunk } end end @@ -104,60 +105,69 @@ def convert_directive(line, directive, dg_name) end end +def test_trailer_lines(category, extra_lines = []) + lines = [] + lines << '(* { dg-do run } *)' if category == 'runnable' + lines.concat extra_lines + lines << '(* { dg-prune-output .* } *)' + case category + when 'compilable' then lines << '(* { dg-final { output-exists } } *)' + when 'fail_compilation' then lines << '(* { dg-final { output-exists-not } } *)' + end + lines +end + def convert_test(source, target, category, extra_lines = []) File.open(target, 'wb') do |output| File.foreach(source) do |line| line = convert_directive(line, '@Error', 'dg-error') - line = convert_directive(line, '@Flags', 'dg-additional-options') - - output.puts line + output.puts convert_directive(line, '@Flags', 'dg-additional-options') end - # Runnable tests compile, link and execute. - output.puts '(* { dg-do run } *)' if category == 'runnable' + test_trailer_lines(category, extra_lines).each { |line| output.puts line } + end +end + +def multi_module_extra_sources(test_target) + sources = test_target.glob('**/*.elna') + .map { |extra| %("#{extra.relative_path_from(test_target)}") } + "(* { dg-additional-sources #{sources * ' '} } *)" +end - extra_lines.each { |line| output.puts line } +def convert_multi_module_test(test_path, test_target, category) + main = test_path / 'sut.elna' + UI.fatal "Multi-module test directory \"#{test_path}\" must contain sut.elna." unless main.file? - # Suppress excess output so stray diagnostics do not fail the test. - output.puts '(* { dg-prune-output .* } *)' + test_target.mkdir + (test_path.children - [main]).each { |extra| cp_r extra, test_target } + extra_lines = ["(* { dg-additional-options \"-I#{test_target.expand_path}\" } *)"] + extra_lines << multi_module_extra_sources(test_target) if category == 'runnable' - case category - when 'compilable' - # Assert that an output file was produced. - output.puts '(* { dg-final { output-exists } } *)' - when 'fail_compilation' - # Assert that no output file was produced. - output.puts '(* { dg-final { output-exists-not } } *)' - end - end + convert_test main, test_target / 'sut.elna', category, extra_lines end namespace :gcc do - # Dependencies. - GCC_VERSION = "16.2.0" - HOST_GCC = 'build/host/gcc' - HOST_INSTALL = Pathname.new 'build/host/install' - GCC_TREE = Pathname.new "build/tools/gcc-#{GCC_VERSION}" - GCC_PATCH = - "https://raw.githubusercontent.com/Homebrew/homebrew-core/refs/heads/main/Patches/gcc/gcc-#{GCC_VERSION}.diff" - - directory HOST_GCC - directory HOST_INSTALL.to_path + directory GCC_HOST + directory GCC_HOST_INSTALL.to_path directory 'build/tools' desc 'Download the bootstrap compiler and its prerequisites' task download: 'build/tools' do + UI.step "Downloading bootstrap compiler and prerequisites (GCC #{GCC_VERSION})..." url = URI.parse "https://gcc.gnu.org/pub/gcc/releases/gcc-#{GCC_VERSION}/gcc-#{GCC_VERSION}.tar.xz" + UI.debug "Downloading #{url}..." download_and_pipe url, GCC_TREE.dirname, ['tar', '-Jxv'] + UI.debug "Downloading and applying patch #{GCC_PATCH}..." download_and_pipe URI.parse(GCC_PATCH), GCC_TREE, ['patch', '-p1'] # GCC 16.1.0 registers 17 languages but CL_PARAMS is at bit 16, # which collides with the 17th language class (CL_Rust). Shift # every CL_* constant from bit 16 upward by one position. - File.open(GCC_TREE + 'gcc/opts.h', 'r+') do |opts_h| - content = opts_h.read.gsub(/\(1U << (\d+)\)/) do |m| - "(1U << #{$1.to_i + 1})" + UI.debug 'Patching gcc/opts.h to shift CL_* flags...' + File.open(GCC_TREE / 'gcc/opts.h', 'r+') do |opts_h| + content = opts_h.read.gsub(/\(1U << (\d+)\)/) do + "(1U << #{Regexp.last_match(1).to_i + 1})" end opts_h.seek 0, IO::SEEK_SET opts_h.write content @@ -168,8 +178,9 @@ namespace :gcc do desc 'Link the frontend into the GCC source tree' task :link do - source_destination = GCC_TREE + 'gcc/elna' - test_destination = GCC_TREE + 'gcc/testsuite/elna.dg' + UI.step 'Linking Elna frontend into the GCC source tree...' + source_destination = GCC_TREE / 'gcc/elna' + test_destination = GCC_TREE / 'gcc/testsuite/elna.dg' rm_rf [source_destination, test_destination] mkdir_p [source_destination, test_destination] @@ -180,16 +191,17 @@ namespace :gcc do FileList['gcc/dg.exp', 'README.md'].each do |file| link_frontend file, test_destination end - destination = GCC_TREE + 'gcc/testsuite/lib' + destination = GCC_TREE / 'gcc/testsuite/lib' FileList['gcc/testlib/*'].each do |file| - rm_f (destination + File.basename(file)) + rm_f destination / File.basename(file) link_frontend file, destination end end desc 'Configure the bootstrap compiler' - task configure: [HOST_GCC, HOST_INSTALL.to_path] do |t| + task configure: [GCC_HOST, GCC_HOST_INSTALL.to_path] do |t| build_target = find_build_target GCC_VERSION + UI.step "Configuring bootstrap compiler for #{build_target.target}..." configure_options = [ "--prefix=#{File.realpath t.prerequisites.last}", '--enable-languages=c,c++,jit,elna', @@ -208,25 +220,28 @@ namespace :gcc do } env['CFLAGS'] = env['CXXFLAGS'] = '-O0 -g -fPIC -I/opt/homebrew/opt/flex/include' - configure = GCC_TREE.relative_path_from(HOST_GCC) + 'configure' - sh env, configure.to_path, *configure_options, chdir: HOST_GCC + configure = GCC_TREE.relative_path_from(GCC_HOST) / 'configure' + sh env, configure.to_path, *configure_options, chdir: GCC_HOST end desc 'Make and install the bootstrap compiler' task :make do - sh 'make', '-j', Etc.nprocessors.to_s, chdir: HOST_GCC - sh 'make', 'install', chdir: HOST_GCC + UI.step "Building bootstrap compiler (jobs: #{Etc.nprocessors})..." + sh 'make', '-j', Etc.nprocessors.to_s, chdir: GCC_HOST + sh 'make', 'install', chdir: GCC_HOST end desc 'Convert the testsuite into dejagnu format' task :convert do - destination = GCC_TREE + 'gcc/testsuite/elna.dg' + UI.step 'Converting testsuite to DejaGnu format...' + destination = GCC_TREE / 'gcc/testsuite/elna.dg' destination.mkpath source = Pathname.new 'testsuite' # Regenerate the category directories from scratch: this removes # converted tests whose sources are gone and adds new ones. %w[compilable fail_compilation runnable].each do |category| + UI.debug "Converting #{category} tests..." category_destination = destination + category category_source = source + category @@ -235,32 +250,8 @@ namespace :gcc do category_source.each_child do |test_path| test_target = category_destination + test_path.basename - - # Multi-module tests: directories containing a sut.elna (system under - # test) and any helper files, compiled and linked together. if test_path.directory? - main = test_path + 'sut.elna' - raise %(multi-module test directory \"#{test_path}\" must contain sut.elna) unless main - - test_target.mkdir - modules = test_path.children - [main] - - modules.each do |extra| - cp_r extra, test_target - end - extra_lines = ["(* { dg-additional-options \"-I#{test_target.expand_path}\" } *)"] - - # Only 'runnable' tests link the helper modules into an executable, - # so only they need the helper sources compiled as separate - # translation units via dg-additional-sources. Elna resolves imports - # on its own, so passing it as an additional source there would add a - # second positional. - if category == 'runnable' - extra_sources = test_target.glob("**/*.elna") - .map { |extra| %("#{extra.relative_path_from test_target}") } - extra_lines << "(* { dg-additional-sources #{extra_sources * ' '} } *)" - end - convert_test main, (test_target + 'sut.elna'), category, extra_lines + convert_multi_module_test test_path, test_target, category else convert_test test_path, test_target, category end @@ -270,25 +261,27 @@ namespace :gcc do desc 'Run tests' task check: 'gcc:convert' do - log_file = Pathname.new(HOST_GCC) + 'gcc/testsuite/elna/elna.log' - - sh 'make', 'check-elna', chdir: File.join(HOST_GCC, 'gcc') + UI.step 'Running DejaGnu testsuite...' + log_file = Pathname.new(GCC_HOST) / 'gcc/testsuite/elna/elna.log' - fail "\nSee #{log_file}." if log_file.file? and log_file.read =~ /^(FAIL|XPASS|UNRESOLVED|ERROR):/ + sh 'make', 'check-elna', chdir: File.join(GCC_HOST, 'gcc') + UI.fatal "See #{log_file}." if log_file.file? && log_file.read =~ /^(FAIL|XPASS|UNRESOLVED|ERROR):/ end desc 'Run clang-tidy' task :tidy do compile_db = Pathname.new 'compile_commands.json' - raise "#{compile_db} is missing. Run: bear -- rake gcc:make" unless compile_db.exist? + UI.fatal "#{compile_db} is missing.", hint: 'Run: bear -- rake gcc:make' unless compile_db.exist? + sources = FileList['boot/*.cc', 'gcc/gcc/*.cc', 'include/elna/**/*.h'] .reject do |file| ['/elna1.', '/elna-spec.'].any? { |pattern| file.include? pattern } end + UI.step "Running clang-tidy on #{sources.size} files..." build_target = find_build_target GCC_VERSION includes = ['.', build_target.target].collect do |inc| - HOST_INSTALL + 'include/c++' + GCC_VERSION + inc + GCC_HOST_INSTALL / 'include/c++' / GCC_VERSION / inc end sh 'clang-tidy', '-p', compile_db.to_path, '--extra-arg=-w', '--warnings-as-errors=*', @@ -298,7 +291,7 @@ namespace :gcc do desc 'Build documentation' task :doc do - sh 'make', 'html', chdir: File.join(HOST_GCC, 'gcc') + sh 'make', 'html', chdir: File.join(GCC_HOST, 'gcc') end desc 'Run GCC linters and tests' diff --git a/rakelib/ruby.rake b/rakelib/ruby.rake new file mode 100644 index 0000000..c3db30a --- /dev/null +++ b/rakelib/ruby.rake @@ -0,0 +1,11 @@ +# This Source Code Form is subject to the terms of the Mozilla Public License, +# v. 2.0. If a copy of the MPL was not distributed with this file, You can +# obtain one at https://mozilla.org/MPL/2.0/. +# frozen_string_literal: true + +require 'rubocop/rake_task' + +namespace :ruby do + desc 'Run RuboCop' + RuboCop::RakeTask.new :lint +end diff --git a/rakelib/support/ui.rb b/rakelib/support/ui.rb new file mode 100644 index 0000000..3120721 --- /dev/null +++ b/rakelib/support/ui.rb @@ -0,0 +1,25 @@ +# This Source Code Form is subject to the terms of the Mozilla Public License, +# v. 2.0. If a copy of the MPL was not distributed with this file, You can +# obtain one at https://mozilla.org/MPL/2.0/. +# frozen_string_literal: true + +require 'term/ansicolor' + +# Terminal UI helpers for build milestones, debug logging, and operational errors. +module UI + extend Term::ANSIColor + + def self.step(message) + puts green(message) + end + + def self.debug(message) + puts "#{dark(' ->')} #{dark(message)}" if Rake.verbose + end + + def self.fatal(message, hint: nil) + output = red(message) + output += "\n#{bold(cyan('Hint:'))} #{hint}" if hint + abort output + end +end diff --git a/rakelib/treesitter.rake b/rakelib/treesitter.rake index 7e48865..ca0c8d0 100644 --- a/rakelib/treesitter.rake +++ b/rakelib/treesitter.rake @@ -18,8 +18,8 @@ namespace :ts do cp_r TREE_SITTER_TREE, TREE_SITTER_BUILD unless TREE_SITTER_BUILD.directory? sh 'tree-sitter', 'generate', - '--output', (TREE_SITTER_BUILD + 'src').to_path, - (TREE_SITTER_TREE + 'grammar.js').to_path + '--output', (TREE_SITTER_BUILD / 'src').to_path, + (TREE_SITTER_TREE / 'grammar.js').to_path build_test = TREE_SITTER_BUILD / 'test' build_corpus = build_test / 'corpus' @@ -44,7 +44,7 @@ namespace :ts do File.open target, 'w' do |output| output.write "==================\n" - output.write(File.basename(test, '.elna') + "\n") + output.write "#{File.basename(test, '.elna')}\n" output.write "==================\n\n" output.write File.read(test) output.write "\n---\n\n" @@ -61,5 +61,4 @@ namespace :ts do end desc 'Build a tree-sitter parser' -task ts: 'ts:generate' -task ts: "#{TREE_SITTER_BUILD}/parser.so" +task ts: ['ts:generate', "#{TREE_SITTER_BUILD}/parser.so"] |
