forcer 0.4.14 → 0.4.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6804c9fe68862c98350f9701974f02cd3590eef
4
- data.tar.gz: 58a9b0122341b63e0e1ad5367dc968b40d1797e7
3
+ metadata.gz: a6101468b6bfe4249a1f178acc2ad0ac8a41a86b
4
+ data.tar.gz: d16e4e974373d621a39bc3ebdf4e072b2676f046
5
5
  SHA512:
6
- metadata.gz: 9c987be478f97c95416cac231f256b5d20c31ff10547c7a591205146c179ae1778a40dc2a683abbc053b683c3f62190b7624650dec1bdfcf9f96881c4ae93631
7
- data.tar.gz: 412fac6b70a39ab2af75b019e05f5a30ba65b6204b6b1a5ba881ed3e27a803abbd1e6d359e99377f5d4e0d7cb0452605f04fe5adc22dd8998e22723522d327d1
6
+ metadata.gz: 5e1a2c5b9464d586d06715cc496347dd76da334bd74a72242713c7f11b88e943786b39935de483e23988d734a913ed9e268441e3f3d4ba7382e8a79c3aa03f14
7
+ data.tar.gz: b39ba5f19cc9c3c0b1adbf463dae0d80b06a8f19973f60c5fe732b29ac871a90db7ac76c4a39cb11eecb712134225a59a92be0813e32fb057473f9bf46ff7058
@@ -4,4 +4,4 @@ You are allowed to:
4
4
  1. Remove rake task
5
5
  2. Add existing rake tasks
6
6
  To add existing rake tasks automatically delete this file and reload the project.
7
- --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build forcer-0.4.13.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install forcer-0.4.13.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install forcer-0.4.13.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.4.13 and build and push forcer-0.4.13.gem to Rubygems" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
7
+ --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build forcer-0.4.15.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install forcer-0.4.15.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install forcer-0.4.15.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.4.15 and build and push forcer-0.4.15.gem to Rubygems" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectCodeStyleSettingsManager">
4
+ <option name="PER_PROJECT_SETTINGS">
5
+ <value>
6
+ <XML>
7
+ <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
8
+ </XML>
9
+ </value>
10
+ </option>
11
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
12
+ </component>
13
+ </project>
@@ -0,0 +1,3 @@
1
+ <component name="ProjectDictionaryState">
2
+ <dictionary name="gaziz" />
3
+ </component>
@@ -11,28 +11,32 @@
11
11
  </component>
12
12
  <component name="NewModuleRootManager">
13
13
  <content url="file://$MODULE_DIR$" />
14
- <orderEntry type="jdk" jdkName="RVM: ruby-2.2.0" jdkType="RUBY_SDK" />
14
+ <orderEntry type="jdk" jdkName="RVM: ruby-2.2-head" jdkType="RUBY_SDK" />
15
15
  <orderEntry type="sourceFolder" forTests="false" />
16
- <orderEntry type="library" scope="PROVIDED" name="akami (v1.3.0, RVM: ruby-2.2.0) [gem]" level="application" />
17
- <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.2, RVM: ruby-2.2.0) [gem]" level="application" />
18
- <orderEntry type="library" scope="PROVIDED" name="bundler (v1.9.4, RVM: ruby-2.2.0) [gem]" level="application" />
19
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, RVM: ruby-2.2.0) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="gyoku (v1.3.1, RVM: ruby-2.2.0) [gem]" level="application" />
21
- <orderEntry type="library" scope="PROVIDED" name="httpi (v2.4.0, RVM: ruby-2.2.0) [gem]" level="application" />
22
- <orderEntry type="library" scope="PROVIDED" name="macaddr (v1.7.1, RVM: ruby-2.2.0) [gem]" level="application" />
23
- <orderEntry type="library" scope="PROVIDED" name="mini_portile (v0.6.2, RVM: ruby-2.2.0) [gem]" level="application" />
24
- <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.6.6.2, RVM: ruby-2.2.0) [gem]" level="application" />
25
- <orderEntry type="library" scope="PROVIDED" name="rake (v10.4.2, RVM: ruby-2.2.0) [gem]" level="application" />
26
- <orderEntry type="library" scope="PROVIDED" name="rspec (v3.2.0, RVM: ruby-2.2.0) [gem]" level="application" />
27
- <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.2.3, RVM: ruby-2.2.0) [gem]" level="application" />
28
- <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.2.1, RVM: ruby-2.2.0) [gem]" level="application" />
29
- <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.2.1, RVM: ruby-2.2.0) [gem]" level="application" />
30
- <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.2.2, RVM: ruby-2.2.0) [gem]" level="application" />
31
- <orderEntry type="library" scope="PROVIDED" name="rubyzip (v1.1.7, RVM: ruby-2.2.0) [gem]" level="application" />
32
- <orderEntry type="library" scope="PROVIDED" name="savon (v2.11.0, RVM: ruby-2.2.0) [gem]" level="application" />
33
- <orderEntry type="library" scope="PROVIDED" name="systemu (v2.6.5, RVM: ruby-2.2.0) [gem]" level="application" />
34
- <orderEntry type="library" scope="PROVIDED" name="thor (v0.19.1, RVM: ruby-2.2.0) [gem]" level="application" />
35
- <orderEntry type="library" scope="PROVIDED" name="uuid (v2.3.7, RVM: ruby-2.2.0) [gem]" level="application" />
36
- <orderEntry type="library" scope="PROVIDED" name="wasabi (v3.5.0, RVM: ruby-2.2.0) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="akami (v1.3.1, RVM: ruby-2.2-head) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.2, RVM: ruby-2.2-head) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v1.10.6, RVM: ruby-2.2-head) [gem]" level="application" />
19
+ <orderEntry type="library" scope="PROVIDED" name="codeclimate-test-reporter (v0.4.7, RVM: ruby-2.2-head) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, RVM: ruby-2.2-head) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="docile (v1.1.5, RVM: ruby-2.2-head) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="gyoku (v1.3.1, RVM: ruby-2.2-head) [gem]" level="application" />
23
+ <orderEntry type="library" scope="PROVIDED" name="httpi (v2.4.1, RVM: ruby-2.2-head) [gem]" level="application" />
24
+ <orderEntry type="library" scope="PROVIDED" name="json (v1.8.2, RVM: ruby-2.2-head) [gem]" level="application" />
25
+ <orderEntry type="library" scope="PROVIDED" name="mini_portile (v0.6.2, RVM: ruby-2.2-head) [gem]" level="application" />
26
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.6.6.2, RVM: ruby-2.2-head) [gem]" level="application" />
27
+ <orderEntry type="library" scope="PROVIDED" name="nori (v2.6.0, RVM: ruby-2.2-head) [gem]" level="application" />
28
+ <orderEntry type="library" scope="PROVIDED" name="rack (v1.6.4, RVM: ruby-2.2-head) [gem]" level="application" />
29
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.4.2, RVM: ruby-2.2-head) [gem]" level="application" />
30
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v3.2.0, RVM: ruby-2.2-head) [gem]" level="application" />
31
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.2.3, RVM: ruby-2.2-head) [gem]" level="application" />
32
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.2.1, RVM: ruby-2.2-head) [gem]" level="application" />
33
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.2.1, RVM: ruby-2.2-head) [gem]" level="application" />
34
+ <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.2.2, RVM: ruby-2.2-head) [gem]" level="application" />
35
+ <orderEntry type="library" scope="PROVIDED" name="rubyzip (v1.1.7, RVM: ruby-2.2-head) [gem]" level="application" />
36
+ <orderEntry type="library" scope="PROVIDED" name="savon (v2.11.1, RVM: ruby-2.2-head) [gem]" level="application" />
37
+ <orderEntry type="library" scope="PROVIDED" name="simplecov (v0.10.0, RVM: ruby-2.2-head) [gem]" level="application" />
38
+ <orderEntry type="library" scope="PROVIDED" name="simplecov-html (v0.10.0, RVM: ruby-2.2-head) [gem]" level="application" />
39
+ <orderEntry type="library" scope="PROVIDED" name="thor (v0.19.1, RVM: ruby-2.2-head) [gem]" level="application" />
40
+ <orderEntry type="library" scope="PROVIDED" name="wasabi (v3.5.0, RVM: ruby-2.2-head) [gem]" level="application" />
37
41
  </component>
38
42
  </module>
data/README.md CHANGED
@@ -4,24 +4,29 @@
4
4
  [![Code Climate](https://codeclimate.com/github/gazazello/forcer/badges/gpa.svg)](https://codeclimate.com/github/gazazello/forcer)
5
5
  [![Test Coverage](https://codeclimate.com/github/gazazello/forcer/badges/coverage.svg)](https://codeclimate.com/github/gazazello/forcer/coverage)
6
6
 
7
- Forcer is a ruby command line application and gem designed to help force.com developers who utilize git and proper development process that includes:
7
+ Forcer is a ruby command line app and gem for interaction with Salesforce Metadata (Metadata API).
8
+ Calling deploy and other available metadata commands should be quicker than using traditional ANT tool
9
+ provided by Salesforce. So in some sense Forcer is an open source replacement for ANT migration tool.
10
+ Forcer is designed to help Force.com developers who use "proper" development process that includes:
8
11
 
9
- 1. every developer should have a separate dev_org\dev_sandbox
10
- 2. code reviews
11
- 3. parallel development of multiple features by a single developer
12
+ 1. Git (Every deployment and every change to any _tracked_ project component is committed to a git repo)
13
+ 1. A separate dev_org\dev_sandbox for every developer
14
+ 2. Parallel development of multiple features by a single developer (can use single Dev Org)
15
+ 3. Code reviews
12
16
 
13
- advantages over traditional ant scripts:
17
+
18
+ Advantages over traditional ANT tool scripts:
14
19
 
15
20
  1. Configurability
16
21
  2. Commands for specific tasks (i.e. delete components or rename components)
17
- 3. Easily add REST Api functionality (i.e. load initial data after new org created)
22
+ 3. Easily adding REST Api functionality (i.e. load initial data after new org created)
18
23
 
19
24
 
20
- This project is inspired by metaforce. It turned out to be easier to start my own project after trying to understand how metaforce
21
- is written and attempting to contribute into it. So after days of reading metaforces code and trying to understand, how
22
- SOAP api calls are done to salesforce and how 'thor' is used to create command line app, I was ready to write my own tool.
23
- The idea is to make structure of Forcer simpler than metaforce and let contributors understand code by reading smaller amount
24
- of files. I admit that my code is not perfect and far from professional ruby styles, so I will be glad if you help me.
25
+ This project is written in Ruby and inspired by Metaforce. It turned out to be easier to start my own project after trying to understand how Metaforce
26
+ is written and attempting to contribute into it. So after days of reading Metaforce's code and trying to understand, how
27
+ SOAP api calls are done to Salesforce and how 'thor' is used to create command line app, I was ready to write my own tool.
28
+ The idea is to make structure of Forcer simpler than Metaforce and let contributors understand code by reading smaller amount
29
+ of files. I admit that my code is not perfect and far from professional ruby styles, so help is appreciated.
25
30
  But please lets keep this tool simple with only necessary commands and functionality.
26
31
 
27
32
  ## System Requirements
@@ -31,7 +36,7 @@ Ruby version: 2.1.2 or later
31
36
 
32
37
  ## Installation
33
38
 
34
- Add this line to your application's Gemfile:
39
+ Add this line to application's Gemfile:
35
40
 
36
41
  ```ruby
37
42
  gem 'forcer'
@@ -41,13 +46,13 @@ And then execute:
41
46
 
42
47
  $ bundle
43
48
 
44
- Or install it yourself as:
49
+ Alternatively install it as:
45
50
 
46
51
  $ gem install forcer
47
52
 
48
- ## Usage
53
+ ## How to use?
49
54
  Currently the app is tested and being used only on Mac OS and Linux (I used Ubuntu). I have NOT tested on Windows yet, but
50
- if you try and report results on Windows, other developers would be thankful.
55
+ if help in testing and reporting results for Windows is appreciated by the rest.
51
56
 
52
57
  Call help to list all available operations for Forcer:
53
58
 
@@ -63,7 +68,7 @@ To list options and flags available for each command call help for each operatio
63
68
  --checkOnly ...
64
69
  ...
65
70
 
66
- To deploy your project (stored in local filesystem) to destination org first from terminal you need to change directory
71
+ To deploy project (stored in local filesystem) to destination org first from terminal users need to change directory
67
72
  to project folder that somewhere inside contains folder "src" with all metadata to deploy:
68
73
 
69
74
  $(master): cd ~/my_workspace/TestProject/
@@ -77,7 +82,8 @@ Here is a very simple deploy command:
77
82
  $(master): forcer deploy
78
83
 
79
84
  This command will start deployment recursively searching for sfdc project source folder "src" and using the first found for deployment.
80
- Please note that "src" folder must contain a valid package.xml file that you intend to use for deployment.
85
+
86
+ *NOTE: "src" folder must contain a valid package.xml file intended to be used for deployment.*
81
87
 
82
88
 
83
89
  ## Configuration
@@ -107,29 +113,42 @@ a template content:
107
113
  security_token: sample_token2
108
114
 
109
115
  #### Where should I place "configuration.yml"?
110
- It should be in the same directory where you call Forcer or inside "forcer_config" folder. First "forcer_config" folder
116
+ It should be in the same directory where users call Forcer or inside "forcer_config" folder. First "forcer_config" folder
111
117
  is scanned for configuration.yml file, then current directory (if not found in "forcer_config" folder). More about folder
112
118
  "forcer_config" at the end of Configuration section.
113
119
 
114
- $(master): ls
120
+ $(master): ls -R
121
+ forcer_config
122
+ forcer_config/configuration.yml
123
+ project
124
+ project/src
125
+ ...
126
+
127
+ Alternatively users can rely on default (same for all projects) exclude_... configuration files. And
128
+ use only "configuration.yml" for a project without folder "forcer_config":
129
+
130
+ $(master): ls -R
115
131
  ./configuration.yml
132
+ project
133
+ project/src
116
134
  ...
117
135
 
118
- $(master): forcer deploy ...
119
-
120
- This allows having separate "configuration.yml" file for each project. If you are calling Forcer from git repo directory
121
- with project files and keeping the file outside "forcer_config", please add "configuration.yml" to gitignore. This
122
- should help you avoiding committing sensitive data. For more information on setup and usage of configuration.yml please
123
- visit wiki pages of this project.
136
+ Each of two methods above allows having separate "configuration.yml" file for each project.
137
+
138
+ *NOTE: If users run Forcer from git repo directory with project files and keep the "configuration.yml"
139
+ outside of "forcer_config", then users should add "configuration.yml" to gitignore. This will help to avoid committing
140
+ sensitive data. For more information on setup and usage of configuration.yml please visit wiki pages of this project.*
124
141
 
125
- ### Excluding certain metadata from deployment
142
+ ## Excluding certain metadata from deployment
126
143
  Forcer is a flexible tool that allows developers:
127
144
 
128
- - Exclude certain components (metadata files) and even whole folders from deployment. For example object Idea.object (excluded by default) usually fails deployments.
145
+ ### Exclude components (metadata files) and even whole folders from deployment. For example object Idea.object (excluded by default) usually fails deployments.
146
+
147
+ #### How to exclude components and whole directories from deployment?
148
+ It is possible to make Forcer exclude components and directories by adding name of a "to-be-excluded"
149
+ component/directory into "exclude_components.yml" configuration file. _This will make Forcer skip the entire
150
+ component/directory from deployment._
129
151
 
130
- #### How to exclude components and and whole directories from deployment?
131
- Name of the file is "exclude_components.yml".
132
-
133
152
  #### "exclude_components.yml" contains:
134
153
 
135
154
  - objects/Idea.object
@@ -147,11 +166,20 @@ Forcer is a flexible tool that allows developers:
147
166
  [your_ruby_version_location (like ".../rvm/gems/ruby-[version]")]/gems/forcer-[version]/lib/metadata_services/exclude_components.yml
148
167
 
149
168
 
150
- - Exclude certain XML elements from deployment. For example all references to "Social..." layouts (excluded by default) in profiles fail deployments.
169
+ ### Exclude XML elements from deployment. For example all references to "Social..." layouts (excluded by default) in profiles fail deployments.
170
+
171
+ #### IMPORTANT NOTE! By default XML exclusion works only when deploy to sandboxes. You can force XML exclusion
172
+ when deploying to production using *--forceExclude* flag. Run _forcer help deploy_ to see all options.
173
+ *Excluding XML snippets for production deployment can cause loss of data*. Also be aware if you exclude
174
+ the whole node like field or weblink (assuming that node exists in target org), that node will be preserved
175
+ intact in the target org. But if you skip a sub-node of that parent node (like removing lookupFilter)
176
+ then it considered as modifying existing node and that node will be overwritten in target org. So
177
+ if you cannot deploy part of node it might be a good idea to skip deployment of whole node or file.
151
178
 
152
179
  #### How to exclude XML elements (snippets) from deployment?
153
- Name of the file is "exclude_xml_nodes.yml". Goal is to deploy the file/component but filter certain known XML elements
154
- from teh file.
180
+ It is possible to make Forcer exclude XML elements/snippets from deployment by adding nokogiri
181
+ search pattern of a "to-be-excluded" XML element/snippet into "exclude_xml_nodes.yml" configuration file.
182
+ _This will make Forcer deploy components but filter our certain undesired XML elements_.
155
183
 
156
184
  #### Sample "exclude_xml_nodes.yml":
157
185
 
@@ -210,16 +238,24 @@ apparent what "forcer_config" belongs to what project:
210
238
  project/src
211
239
  ...
212
240
 
213
- Forcer is designed to be used with git. So considering a project directory is git, folder "forcer_config" should be added
214
- to gitignore. Then it can be reused for any branch or salesforce project. The idea is to switch to any branch and be able
215
- to deploy it using "forcer_config" in current project git directory.
241
+ Forcer is designed to be used with Git. So considering a project directory is in git repo, folder "forcer_config" should be added
242
+ to gitignore. Alternatively if users want to share exclude_... configuration files with other team members,
243
+ then at least every team member should add "/forcer_config/configuration.yml" to gitignore in order to prevent committing sensitive
244
+ authorization information. But in any scenario "forcer_config" can be reused for any branch or Salesforce project on current computer.
245
+ *The idea is to switch to any branch and be able to deploy it using "forcer_config" in current project git directory.*
246
+
247
+ $(master): forcer deploy --dest my_dev_org1
248
+ ...
249
+ $(master): git checkout feature_branch1
250
+ $(feature_branch1): forcer deploy --dest my_dev_org2
251
+ ...
216
252
 
217
253
  ### Command line examples
218
- If you already filled configuration.yml correctly then deployments are much faster. Here is a sample command to start deployment of a project in current folder:
254
+ If users already filled configuration.yml correctly then deployments are much faster. Here is a sample command to start deployment of a project in current folder:
219
255
 
220
256
  $(master): forcer deploy --dest dest_alias_in_configuration_yml
221
257
 
222
- If you want to call validation-only request then, since it is part of "deploy" soap call, you need to just add flag --checkOnly :
258
+ In case users want to call validation-only request then, since it is part of "deploy" soap call, they need to simply dd flag --checkOnly :
223
259
 
224
260
  $(master): forcer deploy --dest dest_alias_in_configuration_yml --checkOnly
225
261
 
@@ -242,11 +278,11 @@ Please note that messages and language can and will change because the app devel
242
278
 
243
279
  ## Possible problems
244
280
 
245
- 1. When my friend tried to run Forcer on ruby version 2.1.5 on Ubuntu, the app threw exception about missing library
246
- "em-http-request". If you have ruby version 2.1.5 installed and cannot resolve dependencies, probably the simplest
247
- solution is switching to ruby version to 2.1.2 or 2.2.0 or later.
281
+ 1. When test run Forcer on ruby version 2.1.5 on Ubuntu, the app threw exception about missing library
282
+ "em-http-request". If installed ruby version is 2.1.5 and dependencies cannot be resolved, probably the simplest
283
+ solution is to switch ruby version to 2.1.2 or 2.2.0 or later.
248
284
  2. openssl library version 1.0.2 on Mac OS (maybe other platforms too) has problems with ruby 2.2.0 when deploy larger
249
- zip-files. In order to fix please follow steps:
285
+ zip-files. These are steps to fix the issue on Mac OS:
250
286
 
251
287
  $(master): brew update
252
288
  $(master): brew uninstall openssl
@@ -255,8 +291,9 @@ zip-files. In order to fix please follow steps:
255
291
  $(master): rvm remove 2.2.0
256
292
  $(master): rvm install 2.2.0 --with-openssl-dir=`brew --prefix openssl`
257
293
 
258
- 3. Most probably users will make multiple attempts before the very first deployment succeeds. The reason is Salesforce has
259
- numerous specific features in metadata deployment. And users of Forcer gem will have to:
294
+ 3. Most probably users will have to make multiple attempts before the very first deployment succeeds.
295
+ The reason is Salesforce has numerous specific features in metadata deployment. And users of Forcer
296
+ gem will have to:
260
297
 
261
298
  * skip/remove certain components from deployment (manually or using exclude_components.xml)
262
299
  * filter out certain XML elements from deployment (manually or using exclude_xml_nodes.xml)
@@ -265,16 +302,14 @@ numerous specific features in metadata deployment. And users of Forcer gem will
265
302
  find . -type f -name '*.profile' -exec sed -i '' s/username_org1/username_org2/ {} +
266
303
 
267
304
  * API version differences between orgs can create issues
268
- * Salesforce updates can make your current project folder undeployable sometimes
305
+ * Salesforce updates can make current project folder undeployable sometimes
269
306
  * other problems requiring modification of XML files
270
307
 
271
308
  4. Contributors may encounter problems with bundler and code-climate if run rspec. The easiest solution is to comment out
272
309
  these lines in file spec_helper.rb :
273
310
 
274
- if Gem.available?("codeclimate-test-reporter")
275
311
  require "codeclimate-test-reporter"
276
312
  CodeClimate::TestReporter.start
277
- end
278
313
 
279
314
 
280
315
  ## Contributing
@@ -1,3 +1,3 @@
1
1
  module Forcer
2
- VERSION = "0.4.14"
2
+ VERSION = "0.4.15"
3
3
  end
@@ -15,6 +15,8 @@ module Forcer
15
15
  "current project directory. Please read project documentation on github for more information."
16
16
 
17
17
  option :source, :aliases => :s, :desc => "Path to folder that contains 'src' directory somewhere. No restriction on exact 'src' location, except it should be somewhere in :source."
18
+ option :forceExclude, :type => :boolean, :desc => "To turn ON all xml exclusion for Production, set --forcerExclude to TRUE"
19
+ option :skipExclude, :type => :boolean, :desc => "To turn OFF absolutely all exclusions (package.mxl too), set --skipExclude to TRUE"
18
20
  option :checkOnly, :type => :boolean, :aliases => :c, :desc => "Only validates without actual deployment. Default is FALSE."
19
21
  option :rollbackOnError, :type => :boolean, :aliases => :b, :desc => "Rolls back whole deployment if error occurs. Default is TRUE."
20
22
  option :runAllTests, :type => :boolean, :aliases => :t, :desc => "Make all unit tests run. Default if FALSE. For production deployment it is always true."
@@ -85,6 +85,7 @@ module Metadata
85
85
 
86
86
  deploy_request_xml = File.read(File.dirname(__FILE__) + "/deploy_request.xml");
87
87
  xml_param = deploy_request_xml % [debug_options_snippet, @current_session_id, blob_zip, deploy_options_snippet]
88
+ p "Uploading project zip file. This may take a while."
88
89
  response = @metadata_client.call(:deploy, :xml => xml_param)
89
90
  # todo catch exceptions
90
91
 
@@ -13,11 +13,7 @@ module Metadata
13
13
  def initialize(args = {})
14
14
  @args = args
15
15
  @output_file_name = tempfile_name("zip")
16
- @files_to_exclude = Set.new()
17
- @snippets_to_exclude = {}
18
16
  find_source_dir
19
- prepare_files_to_exclude
20
- prepare_xml_nodes_to_exclude
21
17
  end
22
18
 
23
19
  # copy files from original directory to be xml_filtered when creating zip
@@ -35,7 +31,6 @@ module Metadata
35
31
 
36
32
  entries = dir_content(@input_dir_name)
37
33
  p "excluding specified components from deployment"
38
- p "filtering deployment files removing specified XML elements"
39
34
  write_entries(entries, "")
40
35
  ensure
41
36
  @zip_io.close # close before deleting tmpdir, or NOT_FOUND exception
@@ -94,6 +89,7 @@ module Metadata
94
89
 
95
90
  # Opens file. Removes all bad xml snippets. Rewrites results back into original file
96
91
  def filter_xml(filename)
92
+ prepare_xml_nodes_to_exclude if @snippets_to_exclude.nil?
97
93
  doc = Nokogiri::XML(File.read(filename))
98
94
  file_modified = false
99
95
  @snippets_to_exclude.each do |suffix, expressions|
@@ -119,7 +115,7 @@ module Metadata
119
115
  entries.each do |entry|
120
116
  # need relative local file path to use in new zip file too
121
117
  zip_file_path = (path == "" ? entry : File.join(path, entry)) # maybe without if/else
122
- next if @files_to_exclude.include?(zip_file_path.downcase) # avoid if directory/file excluded
118
+ next if exclude_file?(zip_file_path.downcase)
123
119
 
124
120
  # need full file path to use in copy/paste
125
121
  disk_file_path = File.join(@input_dir_name, zip_file_path)
@@ -129,12 +125,22 @@ module Metadata
129
125
  sub_dir = dir_content(disk_file_path)
130
126
  write_entries(sub_dir, zip_file_path)
131
127
  else
132
- filter_xml(disk_file_path)
128
+ filter_xml(disk_file_path) unless xml_exclusion_skipped_for?(disk_file_path)
133
129
  @zip_io.add(zip_file_path, disk_file_path)
134
130
  end
135
131
  end
136
132
  end
137
133
 
134
+ def exclude_file?(filename)
135
+ raise Exception if (filename.nil? or filename.empty?)
136
+ if (@files_to_exclude.nil? or @files_to_exclude.empty?)
137
+ @files_to_exclude = Set.new()
138
+ prepare_files_to_exclude
139
+ end
140
+
141
+ return @files_to_exclude.include?(filename)
142
+ end
143
+
138
144
  # Returns array of files for the specified directory (full_path) without current_dir "." and
139
145
  # prev directory ".."
140
146
  def dir_content(full_path)
@@ -173,5 +179,28 @@ module Metadata
173
179
  return false
174
180
  end
175
181
  end
182
+
183
+ # check if destination server is Production
184
+ def is_production
185
+ return (@args[:host].start_with?("https://login") or @args[:host].start_with?("login"))
186
+ end
187
+
188
+ # By default for Production it only processes package.xml and other files
189
+ # (objects, profiles, ...) are ignored (xml exclusions are OFF except package.xml). By default
190
+ # for Sandbox all xml exclusion are turned ON. Package.xml exclusions are OK because they allow
191
+ # skip deployment of certain objects/files.
192
+ # To turn ON all xml exclusion for Production, set --forcerExclude to TRUE
193
+ # To turn OFF absolutely all exclusions (package.mxl too), set --skipExclude to TRUE
194
+ def xml_exclusion_skipped_for?(full_filename)
195
+ raise Exception if (full_filename.nil? or full_filename.empty?)
196
+ return true if @args[:skipExclude]
197
+
198
+ if full_filename.end_with?("package.xml")
199
+ return false
200
+ else
201
+ return (is_production unless @args[:forceExclude])
202
+ end
203
+ end
176
204
  end # class SfdcDirectoryService
205
+
177
206
  end # module Metadata
@@ -7,19 +7,9 @@ module Forcer
7
7
  # directory can include 'configuration.yml', 'exclude_components.yml', 'exclude_xml_nodes.yml'
8
8
  # if directory not found tries to load only configuration.yml from local directory
9
9
  def self.load_config(old_options = {})
10
- options = {}
11
- old_options.each do |k, v|
12
- options.store(k.to_sym, v)
13
- end
10
+ options = clone_options(old_options)
14
11
 
15
- if options[:configs].nil? || !(Dir.exists?(File.expand_path(options[:configs], __FILE__)))
16
- p "config folder not specified or not found"
17
- options[:configs] = Dir.pwd + "/forcer_config"
18
- p "config folder in CURRENT DIRECTORY ? => #{Dir.exists?(options[:configs])}"
19
- else
20
- p "specified config folder FOUND"
21
- options[:configs] = File.expand_path(options[:configs], __FILE__)
22
- end
12
+ verify_config_folder(options)
23
13
 
24
14
  load_login_info(options)
25
15
 
@@ -32,43 +22,74 @@ module Forcer
32
22
 
33
23
  class << self
34
24
 
25
+ # Thor restricts options modification. Therefore have to clone hash "options"
26
+ def clone_options(old_options = {})
27
+ options = {}
28
+ old_options.each do |k, v|
29
+ options.store(k.to_sym, v)
30
+ end
31
+
32
+ return options
33
+ end
34
+
35
+ def verify_config_folder(options = {})
36
+ if options[:configs].nil? || !(Dir.exists?(File.expand_path(options[:configs], __FILE__)))
37
+ p "config folder not specified or not found"
38
+ options[:configs] = Dir.pwd + "/forcer_config"
39
+ p "config folder in CURRENT DIRECTORY ? => #{Dir.exists?(options[:configs])}"
40
+ else
41
+ p "specified config folder FOUND"
42
+ options[:configs] = File.expand_path(options[:configs], __FILE__)
43
+ end
44
+ end
45
+
35
46
  # attempts to read salesforce org information from forcer_config/configuration.yml
36
47
  # if forcer_config/configuration.yml not found, then try configuration.yml in current directory
37
48
  def load_login_info(options = {})
38
49
 
39
- if !(options[:configs].nil?) && File.exists?(File.join(options[:configs], "/configuration.yml"))
40
- p "CONFIGURATION.YML with org details FOUND in CONFIG FOLDER"
41
- config_file_path = File.join(options[:configs], "/configuration.yml")
42
- options[:login_info_path] = config_file_path
43
- else
44
- p "loading CONFIGURATION.YML from CURRENT DIRECTORY"
45
- config_file_path = File.join(Dir.pwd, "/configuration.yml")
46
- end
50
+ config_file_path = get_config_file_path(options)
47
51
 
52
+ # don't raise exception and let user enter all necessary information
48
53
  return options unless File.exists?(config_file_path)
49
54
 
50
- dest = options[:dest]
55
+ destination_org = options[:dest]
51
56
  configuration = YAML.load_file(config_file_path).to_hash
52
57
 
53
- return options if configuration[dest].nil?
58
+ return options if configuration[destination_org].nil?
54
59
 
55
- configuration[dest].each do |key, value|
60
+ configuration[destination_org].each do |key, value|
56
61
  options.store(key.to_sym, value.to_s) unless value.to_s.empty?
57
62
  end
63
+
58
64
  options[:host] = "https://#{options[:host]}" unless options[:host].include?("http")
59
- end # load_login_info
65
+ end
66
+
67
+ # defines which configuration.yml to use for authentication. Preference is to save configuration.yml
68
+ # in folder 'forcer_config' which itself should be placed in project git repo directory
69
+ def get_config_file_path(options = {})
70
+ config_file_path = File.join(options[:configs], "/configuration.yml")
71
+
72
+ if File.exists?(config_file_path)
73
+ p "CONFIGURATION.YML with org details FOUND in CONFIG FOLDER"
74
+ options[:login_info_path] = config_file_path
75
+ else
76
+ p "loading CONFIGURATION.YML from CURRENT DIRECTORY"
77
+ config_file_path = File.join(Dir.pwd, "/configuration.yml")
78
+ end
79
+
80
+ return config_file_path
81
+ end
60
82
 
61
83
 
62
84
  # add absolute paths to exclude_... files from focer_config directory
63
85
  def add_exclude_paths(options = {})
86
+ return if (options[:configs].nil?)
64
87
 
65
- if !(options[:configs].nil?) && File.exists?(File.join(options[:configs], "/exclude_components.yml"))
66
- options[:exclude_components] = File.join(options[:configs], "/exclude_components.yml")
67
- end
88
+ exclude_components_path = File.join(options[:configs], "/exclude_components.yml")
89
+ options[:exclude_components] = exclude_components_path if File.exists?(exclude_components_path)
68
90
 
69
- if !(options[:configs].nil?) && File.exists?(File.join(options[:configs], "/exclude_xml_nodes.yml"))
70
- options[:exclude_xml] = File.join(options[:configs], "/exclude_xml_nodes.yml")
71
- end
91
+ exclude_xml_path = File.join(options[:configs], "/exclude_xml_nodes.yml")
92
+ options[:exclude_xml] = exclude_xml_path if File.exists?(exclude_xml_path)
72
93
  end
73
94
 
74
95
  end # class << self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forcer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.14
4
+ version: 0.4.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - gaziz tazhenov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-11 00:00:00.000000000 Z
11
+ date: 2015-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon
@@ -134,6 +134,8 @@ files:
134
134
  - ".gitignore"
135
135
  - ".idea/.name"
136
136
  - ".idea/.rakeTasks"
137
+ - ".idea/codeStyleSettings.xml"
138
+ - ".idea/dictionaries/gaziz.xml"
137
139
  - ".idea/encodings.xml"
138
140
  - ".idea/forcer.iml"
139
141
  - ".idea/misc.xml"
@@ -181,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
183
  version: '0'
182
184
  requirements: []
183
185
  rubyforge_project:
184
- rubygems_version: 2.4.5
186
+ rubygems_version: 2.4.6
185
187
  signing_key:
186
188
  specification_version: 4
187
189
  summary: '"facilitates change management for dev teams who use force.com and git"'