mdata 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +55 -0
- data/bin/mdata +148 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb30d8e4bfb780f9646c13b55283838aec62116b
|
4
|
+
data.tar.gz: 131491a48e2859fdcb9fd6fe069258b987996542
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ba3b975c4f20280b21234a5ca2c447bb7c43350d0ca0752fe73306d5fb99e0da34d7b02d039242ba8306008182b56786eab68cf29132f840b5b7063955c2eae
|
7
|
+
data.tar.gz: 0bc5a2faf3395705495289ac1a9816ea8d19023d6c1a0ceb18b3af8ef00b83d13726bed29baa3d2e198eda559177ed2482c441332125ede84a69b35f73b15b4b
|
data/README.markdown
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# mdata
|
2
|
+
|
3
|
+
`mdata` is a command line tool for interacting with Salesforce metadata XML files. To install, just use `gem install mdata`.
|
4
|
+
|
5
|
+
You can get a list of options by running `mdata help`. By default, `mdata` looks in the right directory for the object. The general command format is:
|
6
|
+
|
7
|
+
mdata OBJECT PROPERTY:ACTION OPTIONS
|
8
|
+
|
9
|
+
For example, running `mdata profile fieldPermissions:read --profile Admin` would look for a file named `./src/profiles/Admin.profile`. If you need to look in another directory, there is a global `--dir` option that you can set.
|
10
|
+
|
11
|
+
Since these commands get long, there are also shortcuts. The two commands below are synonymous:
|
12
|
+
|
13
|
+
mdata profile fieldPermissions:read --profile Admin
|
14
|
+
mdata pr fp:r --profile Admin
|
15
|
+
|
16
|
+
A full list of aliases is available by running `mdata help`.
|
17
|
+
|
18
|
+
## Currently Supported Actions
|
19
|
+
|
20
|
+
* Create a new profile
|
21
|
+
* Read field permissions from a profile
|
22
|
+
* Set field permissions for a field on a profile
|
23
|
+
* Add field permissions to a field on a profile
|
24
|
+
* Remove field permissions from a field on a profile
|
25
|
+
* Copy field permissions from one field to another and/or one profile to another
|
26
|
+
* Delete field permissions from a profile (e.g. field was deleted)
|
27
|
+
|
28
|
+
## Contribute!
|
29
|
+
|
30
|
+
Command you need isn't yet implemented? Add it!
|
31
|
+
|
32
|
+
0. Top-level metadata object classes go in `lib/mdata/metadata`.
|
33
|
+
0. Classes that encapsulate field types go in `lib/mdata/types`.
|
34
|
+
0. Add your commands to the `bin/mdata` script using existing commands as an example.
|
35
|
+
0. You may also want to add an alias down at the bottom of the script.
|
36
|
+
0. Create unit tests in the `tests/` directory, and run `rake` to ensure they pass.
|
37
|
+
|
38
|
+
## Making a release
|
39
|
+
|
40
|
+
Making a release is not hard, but there are several steps. Perform these steps from the command line in the project directory.
|
41
|
+
|
42
|
+
In this example, we will release version 0.0.0 of `mdata`. The version number should conform to semver standards.
|
43
|
+
|
44
|
+
*Note: These are the ONLY changes that should be made in `master`, all others should be made in topic branches.*
|
45
|
+
|
46
|
+
0. Create an entry in `CHANGELOG.markdown` for v0.0.0 and list the newly added features, fixed bugs, deprecated commands, etc.
|
47
|
+
0. Make sure any newly-created files have been added to `mdata.gemspec` (if necessary)
|
48
|
+
0. Run `rake`. **DO NOT PROCEED IF THERE ARE ERRORS/FAILURES.**
|
49
|
+
0. Update the version to 0.0.0 in `bin/mdata`.
|
50
|
+
0. Update the version to 0.0.0 in `mdata.gemspec`.
|
51
|
+
0. `git add bin/mdata mdata.gemspec`
|
52
|
+
0. `git commit -m "Bump version to 0.0.0"`
|
53
|
+
0. `git tag -a v0.0.0 -m "Release version 0.0.0 to RubyGems"`
|
54
|
+
0. `gem build mdata.gemspec`
|
55
|
+
0. `gem push mdata-0.0.0.gem`
|
data/bin/mdata
CHANGED
@@ -5,7 +5,7 @@ require 'commander/import'
|
|
5
5
|
require 'mdata/metadata'
|
6
6
|
require 'terminal-table'
|
7
7
|
|
8
|
-
program :version, '1.0
|
8
|
+
program :version, '1.1.0'
|
9
9
|
program :description, 'Your Salesforce metadata navigator and manipulator'
|
10
10
|
program :help, 'Author', 'Ben Burwell <ben.burwell@trifecta.com>'
|
11
11
|
|
@@ -244,9 +244,156 @@ command :'profile fieldPermissions:delete' do |c|
|
|
244
244
|
end
|
245
245
|
end
|
246
246
|
|
247
|
+
# Profile - Class Access - Read
|
248
|
+
command :'profile classAccess:read' do |c|
|
249
|
+
c.syntax = 'mdata profile classAccess:read --profile PROFILE [options]'
|
250
|
+
c.summary = 'View Apex class access for a profile'
|
251
|
+
c.option '--profile PROFILE', String, 'The profile to read'
|
252
|
+
c.option '--class CLASS', String, 'Optionally, a particular class to look for'
|
253
|
+
c.action do |args, opts|
|
254
|
+
begin
|
255
|
+
raise ArgumentError, 'no profile specified' if opts.profile.nil?
|
256
|
+
profile = Salesforce::Metadata::Profile.read opts.profile, opts.dir
|
257
|
+
profile.classAccesses.keep_if { |x| x.apexClass == opts.class } unless opts.class.nil?
|
258
|
+
profile.classAccesses.sort! { |a, b| a.apexClass <=> b.apexClass }
|
259
|
+
rows = []
|
260
|
+
profile.classAccesses.each do |cls|
|
261
|
+
rows << [ cls.apexClass, cls.enabled ]
|
262
|
+
end
|
263
|
+
table = Terminal::Table.new :rows => rows, :headings => ['Class', 'Enabled']
|
264
|
+
puts table
|
265
|
+
rescue ArgumentError => e
|
266
|
+
puts "Error executing command: #{e.message}"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# Profile - Class Access - Grant
|
272
|
+
command :'profile classAccess:grant' do |c|
|
273
|
+
c.syntax = 'mdata profile classAccess:grant --profile PROFILE --class CLASS [options]'
|
274
|
+
c.summary = 'Grant Apex class access for a profile'
|
275
|
+
c.option '--profile PROFILE', String, 'The profile to grant access on'
|
276
|
+
c.option '--class CLASS', String, 'The class to grant access to'
|
277
|
+
c.action do |args, opts|
|
278
|
+
begin
|
279
|
+
raise ArgumentError, 'no profile specified' if opts.profile.nil?
|
280
|
+
raise ArgumentError, 'no class specified' if opts.class.nil?
|
281
|
+
profile = Salesforce::Metadata::Profile.read opts.profile, opts.dir
|
282
|
+
idx = profile.classAccesses.find_index { |x| x.apexClass == opts.class }
|
283
|
+
if idx.nil?
|
284
|
+
ca = Salesforce::Types::ProfileApexClassAccess.new
|
285
|
+
ca.apexClass = opts.class
|
286
|
+
profile.classAccesses.push ca
|
287
|
+
idx = profile.classAccesses.count - 1
|
288
|
+
end
|
289
|
+
profile.classAccesses[idx].enabled = 'true'
|
290
|
+
profile.save
|
291
|
+
rescue ArgumentError => e
|
292
|
+
puts "Error executing command: #{e.message}"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Profile - Class Access - Disable
|
298
|
+
command :'profile classAccess:revoke' do |c|
|
299
|
+
c.syntax = 'mdata profile classAccess:revoke --profile PROFILE --class CLASS [options]'
|
300
|
+
c.summary = 'Revoke Apex class access for a profile'
|
301
|
+
c.option '--profile PROFILE', String, 'The profile to revoke access on'
|
302
|
+
c.option '--class CLASS', String, 'The class to revoke access to'
|
303
|
+
c.action do |args, opts|
|
304
|
+
begin
|
305
|
+
raise ArgumentError, 'no profile specified' if opts.profile.nil?
|
306
|
+
raise ArgumentError, 'no class specified' if opts.class.nil?
|
307
|
+
profile = Salesforce::Metadata::Profile.read opts.profile, opts.dir
|
308
|
+
idx = profile.classAccesses.find_index { |x| x.apexClass == opts.class }
|
309
|
+
if idx.nil?
|
310
|
+
ca = Salesforce::Types::ProfileApexClassAccess.new
|
311
|
+
ca.apexClass = opts.class
|
312
|
+
profile.classAccesses.push ca
|
313
|
+
idx = profile.classAccesses.count - 1
|
314
|
+
end
|
315
|
+
profile.classAccesses[idx].enabled = 'false'
|
316
|
+
profile.save
|
317
|
+
rescue ArgumentError => e
|
318
|
+
puts "Error executing command: #{e.message}"
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
# Profile - Class Access - Delete
|
324
|
+
command :'profile classAccess:delete' do |c|
|
325
|
+
c.syntax = 'mdata profile classAccess:delete --profile PROFILE --class CLASS [options]'
|
326
|
+
c.summary = 'Delete Apex class access for a profile'
|
327
|
+
c.option '--profile PROFILE', String, 'The profile to delete access on'
|
328
|
+
c.option '--class CLASS', String, 'The class to delete access to'
|
329
|
+
c.action do |args, opts|
|
330
|
+
begin
|
331
|
+
raise ArgumentError, 'no profile specified' if opts.profile.nil?
|
332
|
+
raise ArgumentError, 'no class specified' if opts.class.nil?
|
333
|
+
profile = Salesforce::Metadata::Profile.read opts.profile, opts.dir
|
334
|
+
profile.classAccesses.delete_if { |x| x.apexClass == opts.class }
|
335
|
+
profile.save
|
336
|
+
rescue ArgumentError => e
|
337
|
+
puts "Error executing command: #{e.message}"
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# Profile - Class Access - Copy
|
343
|
+
command :'profile classAccess:copy' do |c|
|
344
|
+
c.syntax = 'mdata profile classAccess:copy [options]'
|
345
|
+
c.summary = 'Copy class access from one class to another or one profile to another.'
|
346
|
+
c.option '--fromProfile PROFILE', String, 'The profile to copy from'
|
347
|
+
c.option '--toProfile PROFILE', String, 'The profile to copy to'
|
348
|
+
c.option '--profile PROFILE', String, 'A shortcut for specifying the same source and destination profile'
|
349
|
+
c.option '--fromClass CLASS', String, 'The class to copy from'
|
350
|
+
c.option '--toClass CLASS', String, 'The class to copy to'
|
351
|
+
c.option '--class CLASS', String, 'A shortcut for specifying the same source and destination class'
|
352
|
+
c.action do |args, opts|
|
353
|
+
opts.fromProfile = opts.profile unless opts.profile.nil?
|
354
|
+
opts.toProfile = opts.profile unless opts.profile.nil?
|
355
|
+
opts.fromClass = opts.class unless opts.class.nil?
|
356
|
+
opts.toClass = opts.class unless opts.class.nil?
|
357
|
+
|
358
|
+
begin
|
359
|
+
raise ArgumentError, 'no source profile' if opts.fromProfile.nil?
|
360
|
+
raise ArgumentError, 'no destination profile' if opts.toProfile.nil?
|
361
|
+
raise ArgumentError, 'no source class' if opts.fromClass.nil?
|
362
|
+
raise ArgumentError, 'no destination class' if opts.toClass.nil?
|
363
|
+
|
364
|
+
from_profile = Salesforce::Metadata::Profile.read opts.fromProfile, opts.dir
|
365
|
+
src_idx = from_profile.classAccesses.find_index { |x| x.apexClass == opts.fromClass }
|
366
|
+
raise ArgumentError, 'source class not found in source profile' if src_idx.nil?
|
367
|
+
|
368
|
+
to_profile = Salesforce::Metadata::Profile.read opts.toProfile, opts.dir
|
369
|
+
dst_idx = to_profile.classAccesses.find_index { |x| x.apexClass == opts.toClass }
|
370
|
+
|
371
|
+
if dst_idx.nil?
|
372
|
+
ca = Salesforce::Types::ProfileApexClassAccess.new
|
373
|
+
ca.apexClass = opts.toClass
|
374
|
+
to_profile.classAccesses.push ca
|
375
|
+
dst_idx = to_profile.classAccesses.count - 1
|
376
|
+
end
|
377
|
+
|
378
|
+
val = from_profile.classAccesses[src_idx]
|
379
|
+
to_profile.classAccesses[dst_idx] = val
|
380
|
+
|
381
|
+
to_profile.save
|
382
|
+
rescue ArgumentError => e
|
383
|
+
puts "Error executing command: #{e.message}"
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
247
388
|
alias_command :'pr fp:r', :'profile fieldPermissions:read'
|
248
389
|
alias_command :'pr fp:s', :'profile fieldPermissions:set'
|
249
390
|
alias_command :'pr fp:g', :'profile fieldPermissions:grant'
|
250
391
|
alias_command :'pr fp:v', :'profile fieldPermissions:revoke'
|
251
392
|
alias_command :'pr fp:c', :'profile fieldPermissions:copy'
|
252
393
|
alias_command :'pr fp:d', :'profile fieldPermissions:delete'
|
394
|
+
|
395
|
+
alias_command :'pr ca:r', :'profile classAccess:read'
|
396
|
+
alias_command :'pr ca:g', :'profile classAccess:grant'
|
397
|
+
alias_command :'pr ca:v', :'profile classAccess:revoke'
|
398
|
+
alias_command :'pr ca:d', :'profile classAccess:delete'
|
399
|
+
alias_command :'pr ca:c', :'profile classAccess:copy'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mdata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Burwell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: commander
|
@@ -60,6 +60,7 @@ executables:
|
|
60
60
|
extensions: []
|
61
61
|
extra_rdoc_files: []
|
62
62
|
files:
|
63
|
+
- README.markdown
|
63
64
|
- lib/mdata.rb
|
64
65
|
- lib/mdata/metadata.rb
|
65
66
|
- lib/mdata/metadata/Profile.rb
|