#!/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 :docs, :type => :boolean, :default => false, :desc => "Add docs in project vendor directory" method_option :local, :type => :boolean, :default => false, :desc => "Create a copy of Ceedling in the project vendor directory" method_option :gitignore, :type => :boolean, :default => false, :desc => "Create a gitignore file for ignoring ceedling generated files" method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files" method_option :noconfigs, :type => :boolean, :default => false #deprecated: method_option :no_docs, :type => :boolean, :default => false method_option :nodocs, :type => :boolean, :default => false method_option :as_gem, :type => :boolean, :default => false method_option :asgem, :type => :boolean, :default => false method_option :with_ignore, :type => :boolean, :default => false method_option :withignore, :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 :docs, :type => :boolean, :default => false, :desc => "Add docs in project vendor directory" method_option :local, :type => :boolean, :default => false, :desc => "Create a copy of Ceedling in the project vendor directory" method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files" method_option :noconfigs, :type => :boolean, :default => false #deprecated: method_option :no_docs, :type => :boolean, :default => false method_option :nodocs, :type => :boolean, :default => false def upgrade(name, silent = false) copy_assets_and_create_structure(name, silent, true, options || {:upgrade => true}) end no_commands do def copy_assets_and_create_structure(name, silent=false, force=false, options = {}) puts "WARNING: --no_docs deprecated. It is now the default. Specify -docs if you want docs installed." if (options[:no_docs] || options[:nodocs]) puts "WARNING: --as_gem deprecated. It is now the default. Specify -local if you want ceedling installed to this project." if (options[:as_gem] || options[:asgem]) puts "WARNING: --with_ignore deprecated. It is now called -gitignore" if (options[:with_ignore] || options[:with_ignore]) use_docs = options[:docs] || false use_configs = !(options[:no_configs] || options[:noconfigs] || false) use_gem = !(options[:local]) use_ignore = options[:gitignore] || false is_upgrade = options[:upgrade] || 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') # If it's not an upgrade, make sure we have the paths we expect if (!is_upgrade) [source_path, test_path, test_support_path].each do |d| FileUtils.mkdir_p d end end # Genarate gitkeep in test support path FileUtils.touch(File.join(test_support_path, '.gitkeep')) # If documentation requested, create a place to dump them and do so if use_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 # If installed locally to project, copy ceedling, unity, cmock, & supports to vendor unless use_gem FileUtils.mkdir_p ceedling_path #copy full folders from ceedling gem into project %w{plugins lib bin}.map do |f| {:src => f, :dst => File.join(ceedling_path, f)} end.each do |f| directory(f[:src], f[:dst], :force => force) end # mark ceedling as an executable File.chmod(0755, File.join(ceedling_path, 'bin', 'ceedling')) unless is_windows? #copy necessary subcomponents from ceedling gem into project sub_components = [ {:src => 'vendor/c_exception/lib/', :dst => 'vendor/c_exception/lib'}, {:src => 'vendor/cmock/config/', :dst => 'vendor/cmock/config'}, {:src => 'vendor/cmock/lib/', :dst => 'vendor/cmock/lib'}, {: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/src/', :dst => 'vendor/unity/src'}, ] sub_components.each do |c| directory(c[:src], File.join(ceedling_path, c[:dst]), :force => force) end end # We're copying in a configuration file if we haven't said not to if (use_configs) if use_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) File.chmod(0755, File.join(name, 'ceedling')) end end end # Copy the gitignore file if requested if (use_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 use_docs 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 copy_assets_and_create_structure(dest, true, false, {:local=>true, :docs=>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 /^-T$/ 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