salesforce-deploy-tool 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8e39596fd885ddd07e3a1c9c0e8bd363170069c6
4
+ data.tar.gz: ded4c4ea15c4858612ffbcb0e287913d67de420a
5
+ SHA512:
6
+ metadata.gz: 1549f9f350fcdb641200351f7676a372b10637445b108033548993ea5d7e65d6206f363b8862c0e00a3151999b31879fbe511ec8f5fb8219b11ec23ae4fb7c80
7
+ data.tar.gz: 00c66b5e8c2c3dc9fe611c617028adf87d65985e58f22cbef21bdcb061169491b5d2dd835fac2f26da3f5b381674f656ae3baff198f095554eec44681f0bf1d1
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in salesforce-deploy-tool.gemspec
4
+ gemspec
5
+
6
+ gem 'git'
7
+ gem 'colorize'
8
+ gem 'dcgen'
9
+ gem 'commander'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Juan Breinlinger
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Salesforce::Deploy::Tool
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'salesforce-deploy-tool'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install salesforce-deploy-tool
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/salesforce-deploy-tool/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/sfd ADDED
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ require 'salesforcedeploytool'
4
+
5
+ CONFIG_FILE = '/etc/salesforce.yaml'
6
+
7
+ if File.exists? CONFIG_FILE
8
+ config = YAML::load File.open(CONFIG_FILE).read
9
+ else
10
+ puts "error: /etc/salesforce.yaml not found"
11
+ exit 1
12
+ end
13
+
14
+ program :version, SalesforceDeployTool::VERSION
15
+ program :description, 'A cli tool to help manage and deploy salesforce environments with git'
16
+
17
+ command :init do |c|
18
+ c.syntax = 'sf init [options]'
19
+ c.summary = 'Initialize salesforce environment from git'
20
+ c.description = "Clone the #{config[:git_repo]} to #{config[:git_dir]}"
21
+ c.example 'usage', 'sf init'
22
+ c.action do |args, options|
23
+
24
+ # Initialize
25
+ sfdt = SalesforceDeployTool::App.new config
26
+
27
+ # Clone
28
+ sfdt.clone
29
+
30
+ end
31
+ end
32
+
33
+ command :pull do |c|
34
+ c.syntax = 'sf pull'
35
+ c.summary = 'Pull code from the environment'
36
+ c.description = "Pull code from environment and update #{config[:git_dir]}"
37
+ c.example 'usage:', 'sf pull'
38
+ c.example 'usage:', 'sf pull -c -d'
39
+ c.option "--no-clean", "Do not clean the currrent source code before pulling"
40
+ c.option "--debug", "Verbose output"
41
+ c.option "--env NAME", "use 'prod' to deploy production or sandbox name"
42
+ c.action do |args, options|
43
+
44
+ # Parameter validation:
45
+ if options.env.nil?
46
+ puts "error: please specify the environment to pull from using --env"
47
+ exit 1
48
+ end
49
+ config[:env] = options.env
50
+ config[:debug] = options.debug.nil? ? false : true
51
+
52
+ # Initialize
53
+ sfdt = SalesforceDeployTool::App.new config
54
+
55
+ # Clean all files from repo
56
+ sfdt.clean_git_dir unless options.no_clean
57
+
58
+ # Pull the changes
59
+ sfdt.pull "INFO: Pulling changes from #{config[:env]}"
60
+
61
+ end
62
+
63
+ end
64
+
65
+
66
+ command :push do |c|
67
+ c.syntax = 'sf push [options]'
68
+ c.summary = 'Push code into a sandbox'
69
+ c.description = ''
70
+ c.example 'description', "Push the code that is located into #{config[:git_dir]} into the active sandbox"
71
+ c.option "--env NAME", "use 'prod' to deploy production or sandbox name"
72
+ c.option "--debug", "Verbose output"
73
+ c.option "--test", "Deploy and test"
74
+ c.option "--exclude LIST", "a CSV list of metadata to exclude when creating destructiveChange.xml"
75
+ c.option "--append", "Disable destructive change and do an append deploy"
76
+ c.action do |args, options|
77
+
78
+ # Parameter validation:
79
+ if options.env.nil?
80
+ puts "error: please specify the environment to pull from using --env"
81
+ exit 1
82
+ end
83
+ config[:env] = options.env
84
+ config[:debug] = options.debug.nil? ? false : true
85
+ config[:test] = options.test.nil? ? false : true
86
+
87
+ # Initialize
88
+ sfdt = SalesforceDeployTool::App.new config
89
+
90
+ # Pull changes from sandbox to temporary directory:
91
+ config_tmp = config.clone
92
+ config_tmp[:git_dir] = config_tmp[:tmp_dir]
93
+ FileUtils.rm_rf config_tmp[:git_dir] if File.exists? config_tmp[:git_dir]
94
+ sfdt_tmp = SalesforceDeployTool::App.new config_tmp
95
+ sfdt_tmp.clone
96
+ sfdt_tmp.clean_git_dir
97
+ sfdt_tmp.pull "INFO: Pulling changes from #{config[:env]} to temporary directory #{config[:tmp_dir]} to generate destructiveChanges.xml "
98
+
99
+ # Create destructiveChanges.xml
100
+ if ! options.append
101
+ puts "INFO: Creating destructive changes xml"
102
+ dc_gen = Dcgen::App.new
103
+ dc_gen.master = File.join(config[:git_dir],'src')
104
+ dc_gen.destination = File.join(config[:tmp_dir],'src')
105
+ dc_gen.output = File.join(config[:git_dir],'src','destructiveChanges.xml')
106
+ dc_gen.exclude = options.exclude.split(',') unless options.exclude.nil?
107
+
108
+ # Capture stdout when running generate_destructive_Changes, TODO: fix dcgen
109
+ stringio = StringIO.new
110
+ stdout_tmp = $stdout
111
+ $stdout = stringio unless options.debug
112
+ dc_gen.generate_destructive_changes
113
+ $stdout = stdout_tmp
114
+ end
115
+
116
+ # Finally push:
117
+ sfdt.push
118
+
119
+ end
120
+ end
121
+
122
+ default_command :help
123
+
124
+
@@ -0,0 +1,14 @@
1
+ require "rubygems"
2
+ require "commander/import"
3
+ require "git"
4
+ require "pp"
5
+ require "colorize"
6
+ require "logger"
7
+ require "open3"
8
+ require "yaml"
9
+ require "dcgen"
10
+ require "stringio"
11
+ require "salesforcedeploytool/version"
12
+ require "salesforcedeploytool/functions"
13
+ require "salesforcedeploytool/app"
14
+
@@ -0,0 +1,115 @@
1
+ module SalesforceDeployTool
2
+
3
+ class App
4
+
5
+ def initialize config
6
+
7
+ @git_repo = config[:git_repo]
8
+ @git_dir = config[:git_dir]
9
+ @env = config[:env]
10
+ @username = config[:username]
11
+ @password = config[:password]
12
+ @debug = config[:debug]
13
+
14
+ @server_url = @env == 'prod' ? 'https://login.salesforce.com' : 'https://test.salesforce.com'
15
+
16
+ end
17
+
18
+ def clone
19
+
20
+ if Dir.exists? File.join(@git_dir,'.git')
21
+ return
22
+ end
23
+
24
+ begin
25
+ Git.clone(@git_repo, File.basename(@git_dir), :path => File.dirname(@git_dir))
26
+ rescue => e
27
+ STDERR.puts "ERROR: A problem occured when cloning #{@git_repo}, error was\n\n"
28
+ puts e
29
+ exit 1
30
+ end
31
+
32
+ end
33
+
34
+ def clean_git_dir message = nil
35
+
36
+ print message
37
+ Dir[File.join(@git_dir,'src','*')].each do |dir|
38
+ FileUtils.rm_rf dir unless dir =~ /.*package.xml$/
39
+ end
40
+ puts "OK" unless message.nil?
41
+
42
+ end
43
+
44
+ def pull message = nil
45
+
46
+ env_vars = ""
47
+ env_vars += " SF_USERNAME=" + @username + "." + @env
48
+ env_vars += " SF_PASSWORD=" + @password
49
+ env_vars += " SF_SERVERURL=" + @server_url
50
+ cmd = " ant retrieveCode"
51
+
52
+ full_cmd = env_vars + cmd
53
+
54
+ Dir.chdir @git_dir
55
+
56
+ exec_options = {
57
+ :stderr => @debug,
58
+ :stdout => @debug,
59
+ :spinner => ! @debug,
60
+ :message => message,
61
+ :okmsg => "OK",
62
+ :failmsg => "FAILED",
63
+ }
64
+
65
+ if @debug
66
+ exec_options[:message] += "\n\n"
67
+ exec_options[:okmsg] = nil
68
+ exec_options[:failmsg] = nil
69
+ end
70
+
71
+ exit_code = myexec full_cmd, exec_options
72
+
73
+ exit exit_code if exit_code != 0
74
+
75
+ end
76
+
77
+ def push
78
+
79
+ # Set env variables to run ant
80
+ env_vars = ""
81
+ env_vars += " SF_USERNAME=" + @username + "." + @env
82
+ env_vars += " SF_PASSWORD=" + @password
83
+ env_vars += " SF_SERVERURL=" + @server_url
84
+
85
+ # myexec options
86
+ exec_options = {
87
+ :stderr => @debug,
88
+ :stdout => @debug,
89
+ :spinner => ! @debug,
90
+ :okmsg => "OK",
91
+ :failmsg => "FAILED",
92
+ }
93
+
94
+ if @debug
95
+ exec_options[:okmsg] = nil
96
+ exec_options[:failmsg] = nil
97
+ end
98
+
99
+ # Deploy code
100
+ exec_options[:message] = @test ? "INFO: Deploying and Testing code to #{@env}: " : "INFO: Deploying code to #{@env}: "
101
+ exec_options[:message] += "\n\n" if @debug
102
+
103
+ cmd = @test ? " ant deployAndTestCode" : " ant deployCode"
104
+ full_cmd = env_vars + cmd
105
+
106
+ Dir.chdir @git_dir
107
+ exit_code = myexec full_cmd, exec_options
108
+
109
+ exit exit_code if exit_code != 0
110
+
111
+ end
112
+
113
+ end
114
+
115
+ end
@@ -0,0 +1,122 @@
1
+
2
+ class Pinwheel
3
+
4
+ def initialize
5
+ @pinwheel = %w{| / - \\}
6
+ end
7
+
8
+ def spin_it
9
+ print "\b" + @pinwheel.rotate!.first
10
+ end
11
+
12
+ def clean
13
+ print "\b"
14
+ end
15
+
16
+ end
17
+
18
+
19
+ def myexec cmd, opts = {}
20
+
21
+ opts[:stderr] = false if opts[:stderr].nil?
22
+ opts[:stdout] = false if opts[:stdout].nil?
23
+ opts[:exit_on_error] = true if opts[:exit_on_error].nil?
24
+ opts[:timeout] = 600 if opts[:timeout].nil?
25
+ opts[:spinner] = true if opts[:spinner].nil?
26
+ opts[:message] = false if opts[:message].nil?
27
+ opts[:okmsg] = false if opts[:okmsg].nil?
28
+ opts[:failmsg] = false if opts[:failmsg].nil?
29
+ logger = opts[:logger].nil? ? false : opts[:logger]
30
+
31
+ command = File.basename($0)
32
+ exit_status = 0
33
+ start = Time.new
34
+ pinwheel = Pinwheel.new if opts[:spinner]
35
+
36
+ # Print header message
37
+ print opts[:message] if opts[:message]
38
+
39
+ stdout_all = ""
40
+ stderr_all = ""
41
+ begin
42
+ stdin,stdout,stderr,wait_thr = Open3.popen3(cmd)
43
+ pid = wait_thr.pid
44
+ # This block uses kernel.select to monitor if there is data on stdout IO
45
+ # object every 1 second. Then we use a nonblocking read ... so the whole
46
+ # idea is: Check if there is stdin to read, in 1 second unblock and
47
+ # try to read. Loop every 1 second over and over the same process until
48
+ # the process finishes or timeout is reached.
49
+ elapsed = 0
50
+ while wait_thr.status and (elapsed = Time.now - start) < opts[:timeout]
51
+ Kernel.select([stdout,stderr],nil,nil,1)
52
+
53
+ # Read STDIN in a nonblock way.
54
+ begin
55
+ stdout_line = stdout.read_nonblock(100)
56
+ print stdout_line if opts[:stdout]
57
+ stdout_all += stdout_line
58
+ # spin the pinwheel
59
+ pinwheel.spin_it if opts[:spinner]
60
+ rescue IO::WaitReadable
61
+ # Exception raised when there is nothing to read
62
+ rescue EOFError
63
+ # Exception raised EOF is reached
64
+ break
65
+ end
66
+
67
+ # Read STDERR in a nonblock way.
68
+ begin
69
+ stderr_line = stderr.read_nonblock(100)
70
+ print stderr_line if opts[:stderr]
71
+ stderr_all += stderr_line
72
+ # spin the pinwheel
73
+ pinwheel.spin_it if opts[:spinner]
74
+ rescue IO::WaitReadable
75
+ # Exception raised when there is nothing to read
76
+ rescue EOFError
77
+ # Exception raised EOF is reached
78
+ break
79
+ end
80
+
81
+ end
82
+
83
+ # Log stdout output
84
+ logger.info "\n" + stdout_all if logger and ! stdout_all.empty?
85
+ logger.error "\n" + stderr_all if logger and ! stderr_all.empty?
86
+
87
+ if elapsed > opts[:timeout]
88
+ # We need to kill the process
89
+ Process.kill("KILL", pid)
90
+ timeout_error_message = "Timeout #{opts[:timeout]} exceeded for #{cmd}"
91
+ logger.error timeout_error_message if logger
92
+ raise timeout_error_message
93
+ end
94
+
95
+ # Clean the pinwheel
96
+ pinwheel.clean if opts[:spinner]
97
+
98
+ # Handle the exit status:
99
+ exit_status = wait_thr.value.exitstatus
100
+
101
+ # Print fail or ok message
102
+ if exit_status == 0
103
+ puts opts[:okmsg] if opts[:okmsg]
104
+ else
105
+ puts opts[:failmsg] if opts[:failmsg]
106
+ end
107
+
108
+ # Exit on error
109
+ if exit_status > 0
110
+ $stderr.puts "#{command} error: Command returned non zero - error was:\n#{stderr_all}" if opts[:stderr]
111
+ exit 1 if opts[:exit_on_error]
112
+ end
113
+
114
+ rescue => e
115
+ $stderr.puts "\n#{command} error: Command failed, error was:\n#{e}".red
116
+ exit 1 if opts[:exit_on_error]
117
+ exit_status = 127
118
+ end
119
+
120
+ exit_status
121
+
122
+ end
@@ -0,0 +1,3 @@
1
+ module SalesforceDeployTool
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'salesforcedeploytool/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "salesforce-deploy-tool"
8
+ spec.version = SalesforceDeployTool::VERSION
9
+ spec.authors = ["Juan Breinlinger"]
10
+ spec.email = ["<juan.brein@breins.net>"]
11
+ spec.summary = %q{A tool to help you at deploying and pulling code and metadata from salesforce}
12
+ spec.description = %q{}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: salesforce-deploy-tool
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Juan Breinlinger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: ''
42
+ email:
43
+ - "<juan.brein@breins.net>"
44
+ executables:
45
+ - sfd
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/sfd
55
+ - lib/salesforcedeploytool.rb
56
+ - lib/salesforcedeploytool/app.rb
57
+ - lib/salesforcedeploytool/functions.rb
58
+ - lib/salesforcedeploytool/version.rb
59
+ - salesforce-deploy-tool.gemspec
60
+ homepage: ''
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.2.2
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: A tool to help you at deploying and pulling code and metadata from salesforce
84
+ test_files: []