lib/tasks/tooling.rb in faster_support-0.1.2 vs lib/tasks/tooling.rb in faster_support-0.1.3

- old
+ new

@@ -1,33 +1,195 @@ # frozen_string_literal: true require 'forwardable' require 'pathname' require 'json' +require 'rake' +require 'rake/tasklib' + module Tooling class << self + include ::Rake::DSL + + def cc_jsons + @cc_jsons ||= [] + end + + def add_cc_json(text) + cc_jsons << JSON.parse(text) + end + + def cc_json(as: :hash) + result = [] + cc_jsons.each { |json| result += json } + return result if :hash == as + + JSON.pretty_generate(result) + end + + def color_coded_commands + @color_coded_commands ||= [Tooling::PRE_COMPILE_FLAGS, + inner_cc_commands, + Tooling::POST_COMPILE_FLAGS].uniq + end + + def add_task(*args, ext:, **opts) + Tooling::Task.new(ext, *args, **opts) + end + + def tasks + @tasks ||= [] + end + + def define(name = :tooling) + desc 'Prerequisites for compile_commands.json' + task "#{name}:pre_compile_commands" => pre_compile_commands + + define_ccjson(name) + # define_color_coded + + # CLEAN.include('.color_coded') + CLEAN.include('compile_commands.json') + + desc 'Default vim tooling task' + task "#{name}:default" => ['compile_commands.json'] + + desc 'Generate vim tooling' + task name => [:compile, "#{name}:default"] + end + + private + + def define_ccjson(name) + file 'compile_commands.json' => "#{name}:pre_compile_commands" do + puts "Generating compile_commands.json at #{Rake.original_dir}" + Dir.chdir(Rake.original_dir) do + File.open('compile_commands.json', 'w') do |io| + io.write cc_json(as: :json) + end + end + puts 'Done' + end + end + + def define_color_coded + file '.color_coded' => 'compile_commands.json' do + puts 'Generating .color_coded...' + File.open('.color_coded', 'w') { |io| io.puts color_coded_commands } + puts 'Done' + end + end + + def pre_compile_commands + @pre_compile_commands ||= tasks.map(&:cc_json_task_name) + end + + def inner_cc_commands # rubocop:disable Metrics/AbcSize,MethodLength + @inner_cc_commands ||= + begin + commands = [] + raw = File.read(File.join(Rake.original_dir, 'compile_commands.json')) + JSON.parse(raw).each do |cmd_def| + commands << cmd_def['command'].split(' ')[2..-4].map do |string| + string.strip + .sub('../../../..', Rake.original_dir.to_s) + .sub('/../', '/') + .sub(/-I\.\z/, "-I#{Rake.original_dir}/ext/.") + end + end + commands.uniq + rescue Errno::ENOENT + puts "File not found: #{raw}" + exit 2 + end + end + end + + class Task < ::Rake::TaskLib + include ::Rake::DSL extend Forwardable - attr_writer :exttask - def exttask - @exttask || raise('No extension task present!') + attr_accessor :ext_task + + def initialize(ext_task, *args, **opts) + @ext_task = ext_task + @_name = args.shift || ext_task.name + @namespace = opts.fetch(:namespace, :tooling) + @namespaced = opts.fetch(:namespaced, !@namespace.nil?) + yield self if block_given? + + Tooling.tasks << self + + define(args) end - def_delegators :exttask, :tmp_dir, :platform - def_delegator :exttask, :name, :extname + def name + @_name ||= extname.dup + end + def_delegators :ext_task, :tmp_dir, :platform + def_delegator :ext_task, :name, :extname + def platform_tmp_dir - Pathname.new(File.join(exttask.tmp_dir, exttask.platform, exttask.name)) + Pathname.new(File.join(ext_task.tmp_dir, ext_task.platform, ext_task.name)) end def build_dir platform_tmp_dir.join(RUBY_VERSION.to_s) end + + def cc_json_task_name + task_name :pre_compile_commands + end + + protected + + def namespaced? + @namespaced + end + + def define(args) + desc "Required setup for compile_commands.json for #{name}" + task cc_json_task_name, *args do + add_cc_json + end + + task 'tooling:pre_compile_commands' => cc_json_task_name + end + + private + + def run_file_tasks(_args) + add_cc_json + end + + def cc_json + @cc_json ||= + begin + file = File.join(build_dir, 'compile_commands.json') + JSON.parse(File.read(file)) + rescue Errno::ENOENT => e + puts nil, '=' * 70 + puts "File not found: #{File.expand_path(file)} (#{e})" + puts '=' * 70 + exit 1 + end + end + + def add_cc_json + # puts "Adding compile_commands.json for #{name}" + Tooling.cc_jsons << cc_json + end + + def task_name(task) + "#{name}:#{task}" unless namespaced? + "#{@namespace}:#{name}:#{task}" + end end XCODE_TOOLCHAIN_PATH = '/Applications/Xcode.app/Contents/Developer' \ - '/Toolchains/XcodeDefault.xctoolchain'.freeze + '/Toolchains/XcodeDefault.xctoolchain' PRE_COMPILE_FLAGS = %w(-x c -std=c99).freeze POST_COMPILE_FLAGS = %W( -isystem /usr/local/include @@ -40,9 +202,9 @@ -isystem /System/Library/Frameworks -isystem /Library/Frameworks -isystem - #{XCODE_TOOLCHAIN_PATH}/usr/lib/clang/7.3.0/include + #{XCODE_TOOLCHAIN_PATH}/usr/lib/clang/8.0.0/include -fspell-checking ).freeze end