diff --git a/lib/abusetheforce.rb b/lib/abusetheforce.rb index 57e302c..ba2bac6 100644 --- a/lib/abusetheforce.rb +++ b/lib/abusetheforce.rb @@ -42,14 +42,26 @@ module AbuseTheForce build_client end + # Backup old Manifest + FileUtils.copy( + File.join(Atf_Config.get_project_path, 'package.xml'), + File.join(Atf_Config.get_project_path, 'package.xml-bak') + ) + manifest = Metaforce::Manifest.new(metadata_type => [full_name]) @client.retrieve_unpackaged(manifest). - extract_to(Atf_Config.src). + extract_to(Atf_Config.get_project_path). on_complete { |job| puts "Finished retrieve #{job.id}!" }. on_error { |job| puts "Something bad happened!" }. on_poll { |job| puts "Polling for #{job.id}!" }. perform + + # Restore old Manifest + FileUtils.move( + File.join(Atf_Config.get_project_path, 'package.xml-bak'), + File.join(Atf_Config.get_project_path, 'package.xml') + ) end # Fetches a whole project from the server @@ -59,25 +71,25 @@ module AbuseTheForce build_client end - if File.file?(Atf_Config.src + '/package.xml') + if File.file? File.join(Atf_Config.get_project_path, 'package.xml') @client.retrieve_unpackaged(File.expand_path(Atf_Config.src + '/package.xml')). - extract_to(Atf_Config.src). + extract_to(Atf_Config.get_project_path). on_complete { |job| puts "Finished retrieve #{job.id}!" }. on_error { |job| puts "Something bad happened!" }. on_poll { |job| puts "Polling for #{job.id}!" }. perform else - puts "#{Atf_Config.src}: Not a valid project path" + puts "#{Atf_Config.get_project_path}: Not a valid project path" end end - def self.deploy_project(dpath=Atf_Config.src) + def self.deploy_project(dpath=Atf_Config.get_project_path) if @client == nil build_client end - if File.file?(dpath + '/package.xml') + if File.file? File.join(dpath, 'package.xml') @client.deploy(File.expand_path(dpath)). on_complete { |job| puts "Finished deploy #{job.id}!" @@ -118,13 +130,46 @@ module AbuseTheForce class Atf_Config class << self - attr_accessor :targets, :active_target, :src - SETTINGS_FILE="./.abusetheforce.yaml" + attr_accessor :targets, :active_target, :src, :root_dir + SETTINGS_FILE=".abusetheforce.yaml" + + def locate_root(path = '.') + + temp_path = path + + # Look for a settings file in this path and up to root + until File.file? File.join(temp_path, SETTINGS_FILE) + # If we hit root, stop + if temp_path == '/' + break + end + + # Didn't find one so go up one level + temp_path = File.absolute_path File.dirname(temp_path) + end + + # If we actually found it + if File.file? File.join(temp_path, SETTINGS_FILE) + # Return + return temp_path + else + # Return the original path + return path + end + + end # Loads configurations from yaml def load() - if File.file?(SETTINGS_FILE) == false + # Get the project root directory + @root_dir = locate_root + + if File.file? File.join(@root_dir, SETTINGS_FILE) + settings = YAML.load_file File.join(@root_dir, SETTINGS_FILE) + @targets = settings[:targets] + @src = settings[:src] + else puts "No settings file found, creating one now" # Settings file doesn't exist # Create it @@ -133,10 +178,6 @@ module AbuseTheForce @src = './src' dump_settings - else - settings = YAML.load_file(SETTINGS_FILE) - @targets = settings[:targets] - @src = settings[:src] end # Set the default target @@ -216,7 +257,7 @@ module AbuseTheForce # Sets project path from default ./src def set_project_path(ppath) - if File.file?(ppath + '/package.xml') + if File.file? File.join(ppath, 'package.xml') @src = ppath dump_settings else @@ -224,6 +265,11 @@ module AbuseTheForce end end + # Gets the full path to the src folder + def get_project_path + return File.absolute_path File.join(root_dir, src) + end + end end diff --git a/lib/abusetheforce/cli.rb b/lib/abusetheforce/cli.rb index 3289eb2..5782ccd 100644 --- a/lib/abusetheforce/cli.rb +++ b/lib/abusetheforce/cli.rb @@ -13,10 +13,10 @@ module AbuseTheForce # Store the original target's name @last_target = Atf_Config.active_target.name # Switch to the new target - Atf_Config.set_active_target(name) + Atf_Config.set_active_target name else # Switch back to the old target - Atf_Config.set_active_target(@last_target) + Atf_Config.set_active_target @last_target end end @@ -38,7 +38,7 @@ module AbuseTheForce LONG_DESC option :sandbox, :type => :boolean, :aliases => :s, :default => false def add(name, username, security_token) - password = AbuseTheForce.get_password() + password = AbuseTheForce.get_password host = (options[:sandbox] ? "test.salesforce.com" : "login.salesforce.com") # Add the target to the config @@ -66,7 +66,7 @@ module AbuseTheForce if target != nil if options[:password] - target.set_password(AbuseTheForce.get_password) + target.set_password AbuseTheForce.get_password end if options[:token] != nil target.security_token = options[:token] @@ -84,7 +84,7 @@ module AbuseTheForce desc "remove ", "Removes a remote target" def remove(name) - Atf_Config.targets.delete(name) + Atf_Config.targets.delete name # Save to yaml Atf_Config.dump_settings end @@ -97,7 +97,7 @@ module AbuseTheForce LONG_DESC def activate(name) # Activate the target - Atf_Config.set_active_target(name) + Atf_Config.set_active_target name end desc "current", "Shows currently active target" @@ -128,7 +128,8 @@ module AbuseTheForce class_option :target, :banner => "", :aliases => :t #class_option :delete, :aliases => :d - TEMP_DIR="./.atf_tmp" + TEMP_DIR=".atf_tmp" + RESOURCE_DIR="resources" desc "file ", "Deploy a single file" long_desc <<-LONG_DESC @@ -136,28 +137,93 @@ module AbuseTheForce LONG_DESC def file(fpath) + # Make the filepath absolute + fpath = File.absolute_path fpath + abs_root = File.absolute_path Atf_Config.root_dir + + # Check that file path is in root dir + unless fpath.starts_with? abs_root + pute("File does not exist within root project: #{Atf_Config.root_dir}", true) + end + + # Check if in resource directory + if fpath.starts_with? File.join(abs_root, RESOURCE_DIR) + # This is a resource file + # Zip the resource up and then deploy new fpath + + resource_path = File.dirname fpath + + # Until we find the parent directory of the current location is the root resource dir + until File.dirname(resource_path) == File.join(abs_root, RESOURCE_DIR) + # Go up to the next parent + resource_path = File.dirname resource_path + end + + # TODO: Extract this logic for full deploy as well + resource_path = resource_path + resource_name = File.basename resource_path + + zip_path = File.join(Atf_Config.get_project_path, 'staticresources', resource_name + '.resource') + + static_resource_xml = <<-eos + + + Public + application/zip + Static resource uploaded with Abuse the Force + + eos + + # Compress the resource + `zip -r #{zip_path} #{resource_path}` + + # Write the meta.xml + File.open(zip_path + '-meta.xml', 'w') {|f| f.write(static_resource_xml) } + + # Set the fpath to the new zip file + fpath = zip_path + end + + # Get path to temp project directory + temp_path = File.join(Atf_Config.root_dir, TEMP_DIR) + # If a new target was provided, switch to it if options[:target] != nil - AbuseTheForce.temp_switch_target(options[:target]) + AbuseTheForce.temp_switch_target options[:target] end # Clear temp dir - if Dir.exists?('./.atf_tmp') - FileUtils.rm_r('./.atf_tmp') + if Dir.exists? temp_path + FileUtils.rm_r temp_path end - # Make it again - Dir.mkdir('./.atf_tmp') - mdir = File.dirname(fpath).split('/').last + # Get the metadata directory right before filename + mdir = File.basename(File.dirname(fpath)) - FileUtils.copy(Atf_Config.src + '/package.xml', TEMP_DIR + '/package.xml') + # Create the temp directories + FileUtils.mkdir_p File.join(temp_path, mdir) - FileUtils.mkdir_p('./.atf_tmp/' + mdir) - basename = File.basename(fpath) - FileUtils.cp(Atf_Config.src + '/' + mdir + '/' + basename, TEMP_DIR + '/' + mdir + '/') - FileUtils.cp(Atf_Config.src + '/' + mdir + '/' + basename + '-meta.xml', TEMP_DIR + '/' + mdir + '/') + # Copy the package file + FileUtils.copy( + File.join(Atf_Config.get_project_path, 'package.xml'), + File.join(temp_path, 'package.xml') + ) + # File basename + basename = File.basename fpath - AbuseTheForce.deploy_project('./.atf_tmp') + # Copy the file + FileUtils.copy( + File.join(Atf_Config.get_project_path, mdir, basename), + File.join(temp_path, mdir, '/') + ) + + # Copy the metadata + FileUtils.copy( + File.join(Atf_Config.get_project_path, mdir, basename + '-meta.xml'), + File.join(temp_path, mdir, '/') + ) + + AbuseTheForce.deploy_project temp_path # if using a temp target, switch back if options[:target] != nil @@ -166,12 +232,16 @@ module AbuseTheForce end desc "project", "Deploy a whole project" - def project() + def project(target=nil) # If a new target was provided, switch to it if options[:target] != nil AbuseTheForce.temp_switch_target(options[:target]) end + if target != nil + AbuseTheForce.temp_switch_target(target) + end + # Deploy the project AbuseTheForce.deploy_project() @@ -214,9 +284,9 @@ module AbuseTheForce # No metadata passed in, this should be a file path if metadata_type == nil - if File.file?(full_name) + if File.file? full_name # Get the file extension - extname = File.extname(full_name) + extname = File.extname full_name # Get the base name of the metadata full_name = File.basename(full_name, extname) @@ -252,7 +322,7 @@ module AbuseTheForce # If a new target was provided, switch to it if options[:target] != nil - AbuseTheForce.temp_switch_target(options[:target]) + AbuseTheForce.temp_switch_target options[:target] end # Retrieve the project @@ -271,6 +341,7 @@ module AbuseTheForce # Load the abuse-the-force config Atf_Config.load + # ATF Subcommands desc "target SUBCOMMAND ...ARGS", "Manage deploy targets" subcommand "target", TargetCLI @@ -287,9 +358,6 @@ module AbuseTheForce end - # Start the command line - #AtfCLI.start(ARGV) - end # end module AbuseTheForce