mdata 1.0.1 → 1.1.0
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 +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
|