#!/usr/bin/env ruby #these are always used require 'rubygems' require 'fileutils' # Check for the main project file (either the one defined in the ENV or the default) main_filepath = ENV['CEEDLING_MAIN_PROJECT_FILE'] project_found = (!main_filepath.nil? && File.exists?(main_filepath)) if (!project_found) main_filepath = "project.yml" project_found = File.exists?(main_filepath) end def is_windows? return ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) if defined?(RbConfig) return ((Config::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) end unless (project_found) #===================================== We Do Not Have A Project ================================================ puts "Welcome to Ceedling!" require 'thor' def here File.dirname(__FILE__) + "/.." end class CeedlingTasks < Thor include Thor::Actions desc "new PROJECT_NAME", "create a new ceedling project" method_option :no_docs, :type => :boolean, :default => false, :desc => "No docs in vendor directory" method_option :nodocs, :type => :boolean, :default => false method_option :as_gem, :type => :boolean, :default => false, :desc => "Create the scaffold using Ceedling as a gem instead of filling in the vendor directory. Implies --no-docs." method_option :asgem, :type => :boolean, :default => false method_option :with_ignore, :type => :boolean, :default => false, :desc => "Create a gitignore file for ignoring ceedling generated files." method_option :withignore, :type => :boolean, :default => false method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files." method_option :noconfigs, :type => :boolean, :default => false def new(name, silent = false) copy_assets_and_create_structure(name, silent, false, options) end desc "upgrade PROJECT_NAME", "upgrade ceedling for a project (not req'd if gem used)" method_option :no_docs, :type => :boolean, :default => false, :desc => "No docs in vendor directory" method_option :nodocs, :type => :boolean, :default => false method_option :no_configs, :type => :boolean, :default => true, :desc => "Don't install starter configuration files." method_option :noconfigs, :type => :boolean, :default => false def upgrade(name, silent = false) copy_assets_and_create_structure(name, silent, true, options) end no_commands do def copy_assets_and_create_structure(name, silent=false, force=false, options = {}) no_docs = options[:no_docs] || options[:nodocs] || false no_configs = options[:no_configs] || options[:noconfigs] || false as_gem = options[:as_gem] || options[:asgem] || false with_ignore = options[:with_ignore] || options[:withignore] || false ceedling_path = File.join(name, 'vendor', 'ceedling') source_path = File.join(name, 'src') test_path = File.join(name, 'test') test_support_path = File.join(name, 'test/support') [source_path, test_path, test_support_path].each do |d| FileUtils.mkdir_p d end unless as_gem FileUtils.mkdir_p ceedling_path unless no_docs doc_path = File.join(ceedling_path, 'docs') FileUtils.mkdir_p doc_path in_doc_path = lambda {|f| File.join(doc_path, f)} doc_files = [ 'docs/CeedlingPacket.md', 'vendor/c_exception/docs/CException.md', 'vendor/cmock/docs/CMock_Summary.md', 'vendor/unity/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf', 'vendor/unity/docs/UnityAssertionsReference.md', 'vendor/unity/docs/UnityConfigurationGuide.md', 'vendor/unity/docs/UnityGettingStartedGuide.md', 'vendor/unity/docs/UnityHelperScriptsGuide.md', 'vendor/unity/docs/ThrowTheSwitchCodingStandard.md', ] doc_files.each do |f| copy_file(f, in_doc_path.call(File.basename(f)), :force => force) end end folders = if as_gem %w{plugins lib} else %w{plugins lib bin} end #copy full folders from ceedling gem into project folders.map do |f| {:src => f, :dst => File.join(ceedling_path, f)} end.each do |f| directory(f[:src], f[:dst], :force => force) end #copy necessary subcomponents from ceedling gem into project sub_components = [ {:src => 'vendor/c_exception/lib/', :dst => 'vendor/c_exception/lib'}, {:src => 'vendor/c_exception/release/', :dst => 'vendor/c_exception/release'}, {:src => 'vendor/cmock/config/', :dst => 'vendor/cmock/config'}, {:src => 'vendor/cmock/lib/', :dst => 'vendor/cmock/lib'}, {:src => 'vendor/cmock/release/', :dst => 'vendor/cmock/release'}, {:src => 'vendor/cmock/src/', :dst => 'vendor/cmock/src'}, {:src => 'vendor/deep_merge/lib/', :dst => 'vendor/deep_merge/lib'}, {:src => 'vendor/diy/lib', :dst => 'vendor/diy/lib'}, {:src => 'vendor/unity/auto/', :dst => 'vendor/unity/auto'}, {:src => 'vendor/unity/release/', :dst => 'vendor/unity/release'}, {:src => 'vendor/unity/src/', :dst => 'vendor/unity/src'}, ] sub_components.each do |c| directory(c[:src], File.join(ceedling_path, c[:dst]), :force => force) end end unless (no_configs) if as_gem copy_file(File.join('assets', 'project_as_gem.yml'), File.join(name, 'project.yml'), :force => force) else copy_file(File.join('assets', 'project_with_guts.yml'), File.join(name, 'project.yml'), :force => force) if is_windows? copy_file(File.join('assets', 'ceedling.cmd'), File.join(name, 'ceedling.cmd'), :force => force) else copy_file(File.join('assets', 'ceedling'), File.join(name, 'ceedling'), :force => force) end end end if (with_ignore) copy_file(File.join('assets', 'default_gitignore'), File.join(name, '.gitignore'), :force => force) end unless silent puts "\n" puts "Project '#{name}' #{force ? "upgraded" : "created"}!" puts " - Tool documentation is located in vendor/ceedling/docs" if (not no_docs) and (not as_gem) puts " - Execute 'ceedling help' to view available test & build tasks" puts '' end end end desc "examples", "list available example projects" def examples() puts "Available sample projects:" FileUtils.cd(File.join(here, "examples")) do Dir["*"].each {|proj| puts " #{proj}"} end end desc "example PROJ_NAME [DEST]", "new specified example project (in DEST, if specified)" def example(proj_name, dest=nil) if dest.nil? then dest = proj_name end invoke :new, [dest, true] dest_src = File.join(dest,'src') dest_test = File.join(dest,'test') dest_project = File.join(dest,'project.yml') directory "examples/#{proj_name}/src", dest_src directory "examples/#{proj_name}/test", dest_test remove_file dest_project copy_file "examples/#{proj_name}/project.yml", dest_project puts "\n" puts "Example project '#{proj_name}' created!" puts " - Tool documentation is located in vendor/ceedling/docs" puts " - Execute 'ceedling help' to view available test & build tasks" puts '' end desc "version", "return the version of the tools installed" def version() require 'ceedling/version.rb' puts " Ceedling:: #{Ceedling::Version::CEEDLING}" puts " CMock:: #{Ceedling::Version::CMOCK}" puts " Unity:: #{Ceedling::Version::UNITY}" puts " CException:: #{Ceedling::Version::CEXCEPTION}" end end if (ARGV[0] =~ /^\-T$/) puts "\n(No Project Detected, Therefore Showing Options to Create Projects)" CeedlingTasks.tasks.each_pair do |k,v| puts v.usage.ljust(25,' ') + v.description end puts "\n" else CeedlingTasks.source_root here CeedlingTasks.start end #===================================== We Have A Project Already ================================================ else require 'yaml' require 'rbconfig' #determine platform platform = begin case(RbConfig::CONFIG['host_os']) when /mswin|mingw|cygwin/i :mswin when /darwin/ :osx else :linux end rescue :linux end #create our default meta-runner option set options = { :pretest => nil, :args => [], :add_path => [], :path_connector => (platform == :mswin) ? ";" : ":", :graceful_fail => false, :which_ceedling => (Dir.exists?("vendor/ceedling") ? "vendor/ceedling" : 'gem'), :default_tasks => [ 'test:all' ], :list_tasks => false } #guess that we need a special script file first if it exists if (platform == :mswin) options[:pretest] = File.exists?("#{ platform.to_s }_setup.bat") ? "#{ platform.to_s }_setup.bat" : nil else options[:pretest] = File.exists?("#{ platform.to_s }_setup.sh") ? "source #{ platform.to_s }_setup.sh" : nil end #merge in project settings if they can be found here yaml_options = YAML.load_file(main_filepath) if (yaml_options[:paths]) options[:add_path] = yaml_options[:paths][:tools] || [] else options[:add_path] = [] end options[:graceful_fail] = yaml_options[:graceful_fail] if yaml_options[:graceful_fail] options[:which_ceedling] = yaml_options[:project][:which_ceedling] if (yaml_options[:project] && yaml_options[:project][:which_ceedling]) options[:default_tasks] = yaml_options[:default_tasks] if yaml_options[:default_tasks] #sort through command line options ARGV.each do |v| case(v) when /^(?:new|examples?|templates?)$/ puts "\nOops. You called ceedling with argument '#{v}'.\n" + " This is an operation that will create a new project... \n" + " but it looks like you're already in a project. If you really \n" + " want to do this, try moving to an empty folder.\n\n" abort when /^help$/ options[:list_tasks] = true when /^project:(\w+)/ ENV['CEEDLING_USER_PROJECT_FILE'] = "#{$1}.yml" else options[:args].push(v) end end #add to the path if (options[:add_path] && !options[:add_path].empty?) path = ENV["PATH"] options[:add_path].each do |p| f = File.expand_path(File.dirname(__FILE__),p) path = (f + options[:path_connector] + path) unless path.include? f end ENV["PATH"] = path end # Load Ceedling (either through the rakefile OR directly) if (File.exists?("rakefile.rb")) load 'rakefile.rb' else if (options[:which_ceedling] == 'gem') require 'ceedling' else load "#{options[:which_ceedling]}/lib/ceedling.rb" end Ceedling.load_project end Rake.application.standard_exception_handling do if options[:list_tasks] # Display helpful task list when requested. This required us to dig into Rake internals a bit Rake.application.define_singleton_method(:name=) {|n| @name = n} Rake.application.name = 'ceedling' Rake.application.options.show_tasks = :tasks Rake.application.options.show_task_pattern = /^(?!.*build).*$/ Rake.application.display_tasks_and_comments() else task :default => options[:default_tasks] # Run our Tasks! Rake.application.collect_command_line_tasks(options[:args]) Rake.application.top_level end end true #=================================================================================================================== end