123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- /*++
- Copyright (c) 2017 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- config.ck
- Abstract:
- This module implements the config command for Santa.
- Author:
- Evan Green 24-May-2017
- Environment:
- Chalk
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- import io;
- from getopt import gnuGetopt;
- from json import dumps, loads;
- from santa.config import config;
- from santa.lib.santaconfig import SantaConfig;
- //
- // --------------------------------------------------------------------- Macros
- //
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- function
- _listConfig (
- actor,
- json
- );
- function
- _printConfigValue (
- prefix,
- value
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- var description = "Get or set application parameters";
- var shortOptions = "af:hjlrsu";
- var longOptions = [
- "add",
- "file=",
- "help",
- "json",
- "list",
- "remove",
- "system",
- "user"
- ];
- var usage =
- "usage: santa config [options] key\n"
- " santa config [options] key value [value...]\n"
- "santa config gets or sets an application configuration value.\n"
- "Valid options are:\n"
- " -f, --file=file -- Work on the specified config file.\n"
- " -j, --json -- Print the result in JSON or read the value as JSON.\n"
- " -s, --system -- Work on the system store rather than the user's store.\n"
- " -u, --user -- Work on the user store instead of the combination of "
- "all stores\n"
- " -r, --remove -- Remove the given key\n"
- " -a, --add -- Add to the given key instead of replacing it.\n"
- " -l, --list -- List all values found in the store.\n";
- //
- // ------------------------------------------------------------------ Functions
- //
- function
- command (
- args
- )
- /*++
- Routine Description:
- This routine implements the config command.
- Arguments:
- args - Supplies the arguments to the function.
- Return Value:
- Returns an exit code.
- --*/
- {
- var action = null;
- var actioncount = 0;
- var actor = config;
- var argc;
- var json = false;
- var list = false;
- var name;
- var options = gnuGetopt(args[1...-1], shortOptions, longOptions);
- var previous;
- var value;
- args = options[1];
- argc = args.length();
- options = options[0];
- for (option in options) {
- name = option[0];
- value = option[1];
- if ((name == "-a") || (name == "--add")) {
- action = "add";
- actioncount += 1;
- } else if ((name == "-f") || (name == "--file")) {
- config.__init(value, {});
- } else if ((name == "-s") || (name == "--system")) {
- actor = actor._global;
- } else if ((name == "-h") || (name == "--help")) {
- Core.print(usage);
- return 1;
- } else if ((name == "-j") || (name == "--json")) {
- json = true;
- } else if ((name == "-l") || (name == "--list")) {
- list = true;
- } else if ((name == "-r") || (name == "--remove")) {
- action = "remove";
- actioncount += 1;
- } else if ((name == "-u") || (name == "--user")) {
- actor = actor._user;
- } else {
- Core.raise(ValueError("Invalid option '%s'" % name));
- }
- }
- if (list) {
- if ((argc != 0) || (actioncount != 0)) {
- Core.raise(ValueError("Expected no arguments with --list"));
- }
- _listConfig(actor, json);
- return 0;
- }
- if (actioncount > 1) {
- Core.raise(ValueError("Specify only one action"));
- }
- if (argc == 0) {
- Core.raise(ValueError("Expected an argument"));
- }
- //
- // If no actor was specified and this is not a get operation, default to
- // the user store. Otherwise the action is performed on the override store,
- // causing no changes to stick, which is probably not what the user wanted.
- //
- if ((action != null) || (argc != 1)) {
- if (actor is SantaConfig) {
- actor = actor._user;
- }
- }
- if (argc == 1) {
- if (action == "remove") {
- actor.setKey(args[0], null);
- actor.save();
- } else if (action == null) {
- value = actor.getKey(args[0]);
- if ((value is Dict) || (value is List) || (json != false)) {
- Core.print(dumps(value, 4));
- } else {
- Core.print(value.__str());
- }
- } else {
- Core.raise(ValueError("Cannot perform %s with only one argument" %
- action));
- }
- } else if (argc == 2) {
- value = args[1];
- if (json != false) {
- value = loads(value);
- } else {
- //
- // Convert true, false, and anything that looks like a number. To
- // override this behavior, use the --json flag.
- //
- if (value == "true") {
- value = true;
- } else if (value == "false") {
- value = false;
- } else {
- try {
- value = Int.fromString(value);
- } except ValueError {}
- }
- }
- if (action == "add") {
- previous = actor.getKey(args[0]);
- if (previous != null) {
- if (previous is List) {
- previous.append(value);
- value = previous;
- } else {
- value = [previous, value];
- }
- }
- actor.setKey(args[0], value);
- actor.save();
- } else if (action == null) {
- actor.setKey(args[0], value);
- actor.save();
- } else {
- Core.raise(ValueError("Cannot perform %s with two arguments" %
- action));
- }
- //
- // Many arguments.
- //
- } else {
- value = [];
- if (action == "add") {
- previous = actor.getKey(args[0]);
- if (previous != null) {
- if (previous is List) {
- value = previous;
- } else {
- value = [previous];
- }
- }
- }
- for (arg in args[1...-1]) {
- if (json) {
- arg = loads(arg);
- }
- value.append(arg);
- }
- if ((action == null) || (action == "add")) {
- actor.setKey(args[0], value);
- actor.save();
- } else {
- Core.raise(ValueError("Cannot perform %s with many arguments" %
- action));
- }
- }
- return 0;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- function
- _listConfig (
- actor,
- json
- )
- /*++
- Routine Description:
- This routine lists the configuration for the given dictionary.
- Arguments:
- actor - Supplies the configuration to work on.
- json - Supplies whether or not to print in JSON format.
- Return Value:
- Returns an exit code.
- --*/
- {
- actor = actor.dict();
- if (json) {
- Core.print(dumps(actor, 4));
- } else {
- _printConfigValue("", actor);
- }
- return 0;
- }
- function
- _printConfigValue (
- prefix,
- value
- )
- /*++
- Routine Description:
- This routine prints a configuration value, recursively.
- Arguments:
- prefix - Supplies the prefix to print on all values.
- value - Supplies the value to print.
- Return Value:
- None.
- --*/
- {
- var index;
- if (value is Dict) {
- if (prefix != "") {
- prefix += ".";
- }
- for (key in value) {
- _printConfigValue("%s%s" % [prefix, key.__str()], value[key]);
- }
- } else if (value is List) {
- for (index in 0..value.length()) {
- _printConfigValue("%s[%d]" % [prefix, index], value[index]);
- }
- } else {
- Core.print("%s = %s" % [prefix, value.__str()]);
- }
- return;
- }
|