Paste #9220: Config File Generator - It's Automagical!

Date: 2014/09/03 10:59:37 UTC-07:00
Type: Denizen Script

View Raw Paste Download This Paste
Copy Link


# ---------------------------------------------------------------------------- #
#                                                                              |
#                                                                              |
#                     C o n f i g F i l e G e n e r a t o r                    |
#                                                                              |
#         A system for extracting default config files for your scripts        |
#                                                                              |
#                                                                              |
#   Author: |Anthony|                                                          |
#   Version: 0.2                                                               |
#   dScript Version: 0.9.5-b1518                                               |
#                                                                              |
# ---------------------------------------------------------------------------- #
# 
# 
# ABOUT:
#       Use the ConfigFileGenerator for any scripts that use config files or 
#     YAML file storage. It will generate any default files for you based on
#     what you define in the Configurations Script Container.
# 
# -------------
# 
# USAGE:
# 
#   - Build your Configurations Script Container file as needed following the
#     examples shown here.
# 
#   - Run the ConfigFileGeneratorHelper to generate the files defined in the
#     Configurations Script Container.
#     - run s@ConfigFileGeneratorHelper def:%readID%|%basePath%
# 
# 
#--- Configurations Script Container:
#
#     The Configurations Script Container is the house for your default files.
#     It will be referenced when building your default files.
#     You are able to store any data needed inside this file. It can handle
#     recursive lists too.
# 
#   Naming the Container
#   * This is important!
# 
#     This script container should follow the naming convention:
#       YourScript_Configurations
#         %readID%_%basePath%
# 
#     We will refer to this later as %readID%_%basePath%
# 
#--- Example:
# 
#     There is an example Configurations Script Container at the end of this
#   file that you can use to see how the ConfigFileGenerator works.
#
#   There is also a command script supplied to make it easy to test. Assign
#   youself the denizen.cfg permission node to use the command:  /cfg
#
#   This will create 3 files inside /plugins/denizen/ConfigFileGeneratorTest
#
#   You can also specify the any or all of 3 options for the /cfg command.
#     /cfg --dryrun --verbose --force 
# 
#__________
#
################################################################################
#
# Config File Generator Helper
#
# This script tells the s@ConfigFileGenerator which files to generate based
# on the script container you reference.
#
# Bare minimum usage:
#   - run s@ConfigFileGeneratorHelper def:%readID%|%basePath%|%dryrun%|%verbose%|%forcewrite% instantly
#
#
# NOTES:
#
#  - I want to update this so you can specify a single file to build from any
#    config container. Currently it tries to build every file but will not
#    overwrite existing files by default (you CAN specify the --force option)
#

'ConfigFileGeneratorHelper':
  type: task
  debug: false
  script:
    - ^define readID '<def[readID]||%1%>'
    - ^define basePath '<def[basePath]||%readID%_%2%>'
    - ^define scriptPath '<s@<def[basePath]>.relative_filename||null>'
    - ^define dryrun '<def[dryrun]||<def[3]||false>>'
    - ^define verbose '<def[verbose]||<def[4]||false>>'
    - ^define forcewrite '<def[forcewrite]||<def[5]||false>>'
    - ^if <def[scriptPath].is[==].to[null]> {
      - announce "<&b>ConfigFileGenerator<&co> <&c><def[readID]> is not a valid readID." to_console
      - queue stop
      }
    - ^if <server.has_file[%scriptPath%]> {
      - yaml 'load:<def[scriptPath]>' 'id:%readID%'
      }
      else {
      - announce "<&b>ConfigFileGenerator<&co> <&c>%scriptPath% does not exist!" to_console
      - queue stop
      }
    - ^define keylist '<yaml[%readID%].list_keys[%basePath%].exclude[type|debug|scriptPath]>'
    - ^if <def[keylist].is_empty> {
      - announce "<&b>ConfigFileGenerator<&co> <&c>The default <def[readID]> config file is emtpy!" to_console
      - yaml unload 'id:%readID%'
      - queue stop
      }
    - ^foreach <def[keylist]> {
      - define node <def[value]>
      - inject s@ConfigFileGeneratorHelper p:buildFile
      }
    - ^announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> has Completed!" to_console
    - ^announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> has Completed!" to_flagged:ConfigFileGeneratorNotify
    - ^yaml unload 'id:%readID%'

  buildFile:
    - if !<server.has_file[%readID%/%node%.yml]> || <def[forcewrite]> {
      - announce "<&b>ConfigFileGenerator<&co> <&3>Generating default <def[readID]> %node%.yml file..." to_console
      - announce "<&b>ConfigFileGenerator<&co> <&3>Generating default <def[readID]> %node%.yml file..." to_flagged:ConfigFileGeneratorNotify
      - announce "<&b>" to_flagged:ConfigFileGeneratorNotify
      - define writePath '%node%'
      - define writeID '%readID%_%node%'
      - yaml create 'id:%writeID%'
      - run s@ConfigFileGenerator def:<def[readID]>|<def[writeID]>|<def[basePath]>|<def[writePath]>|<def[dryrun]>|<def[verbose]>|<def[forcewrite]> instantly
      - if !<def[dryrun]> {
        - yaml 'savefile:%readID%/%node%.yml' 'id:%writeID%'
        - announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> %node%.yml Save Complete!" to_console
        - announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> %node%.yml Save Complete!" to_flagged:ConfigFileGeneratorNotify
        - announce "" to_flagged:ConfigFileGeneratorNotify
        - yaml unload 'id:%writeID%'
        }
        else {
        - announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> %node%.yml Dryrun Complete!" to_console
        - announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> %node%.yml Dryrun Complete!" to_flagged:ConfigFileGeneratorNotify
        - announce "" to_flagged:ConfigFileGeneratorNotify
        - yaml unload 'id:%writeID%'
        }
      }
      else {
      - announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> %node%.yml already exists!" to_console
      - announce "<&b>ConfigFileGenerator<&co> <&a><def[readID]> %node%.yml already exists!" to_flagged:ConfigFileGeneratorNotify
      }


################################################################################
#
# Configuration File Generator
#
#
# This script generates default config files based on the definitions passed to
# it. It should be flexible enough to handle any script.
# 
# You shouldn't ever really need to call this script directly. Just use the
# ConfigFileGeneratorHelper to make your life easier!
#
#   - run s@ConfigFileGenerator def:%readID%|%writeID%|%basePath%|%writePath%|%dryrun%|%verbose%|%forcewrite% instantly
# 

'ConfigFileGenerator':
  type: task
  debug: false
  definitions: readID|writeID|basePath|writePath|dryrun|verbose|forcewrite
  script:
    - ^define keylist '<yaml[<def[readID]>].list_keys[<def[basePath]>.<def[writePath]>]>'
    - ^if <def[keylist]> != null {
      - inject s@ConfigFileGenerator p:foreachKeylist instantly
      }
      else {
      - define entry '<yaml[<def[readID]>].read[<def[basePath]>.<def[writePath]>]>'
      - if <def[dryrun]> || <def[verbose]> {
        - announce "<&b>ConfigFileGenerator<&co> <&a>Next Path<&co> <&b><def[basePath]>.<def[writePath]>" to_console
        - announce "<&b>ConfigFileGenerator<&co> <&a>Next Path<&co> <&b><def[basePath]>.<def[writePath]>" to_flagged:ConfigFileGeneratorNotify
        }
      - if <yaml[<def[readID]>].is_list[<def[basePath]>.<def[writePath]>]> {
        - inject s@ConfigFileGenerator p:foreachEntrylist instantly
        }
        else {
        - inject s@ConfigFileGenerator p:singleEntry instantly
        }
      }

  foreachKeylist:
    - foreach <def[keylist]> {
      - define key '<def[value]>'
      - define oldWritePath '<def[writePath]>'
      - define writePath '%writePath%.%key%'
      - run s@ConfigFileGenerator def:<def[readID]>|<def[writeID]>|<def[basePath]>|<def[writePath]>|<def[dryrun]>|<def[verbose]>|<def[forcewrite]> instantly
      - define writePath '%oldWritePath%'
      }

  foreachEntrylist:
    - yaml 'write:%writePath%' 'id:%writeID%'
    - foreach <def[entry]> {
      - if !<def[dryrun]> {
        - yaml set <def[writePath]>:->:<def[value]> 'id:<def[writeID]>'
        }
      - if <def[dryrun]> || <def[verbose]> {
        - announce "<&b>ConfigFileGenerator<&co> <&9>%writePath%<&co> <&2>%value%" to_console
        - announce "<&b>ConfigFileGenerator<&co> <&9>%writePath%<&co> <&2>%value%" to_flagged:ConfigFileGeneratorNotify
        }
      }
    - if <def[dryrun]> || <def[verbose]> {
      - announce "<&b>ConfigFileGenerator<&co> <&3>*-----*" to_flagged:ConfigFileGeneratorNotify
      - announce "" to_flagged:ConfigFileGeneratorNotify
      }

  singleEntry:
    - if <def[dryrun].is[==].to[false]> {
      - yaml 'write:<def[writePath]>' 'value:<def[entry]>' 'id:<def[writeID]>'
      }
    - if <def[dryrun].is[==].to[true]> || <def[verbose].is[==].to[true]> {
      - announce "<&b>ConfigFileGenerator<&co> <&c>%writePath%<&co> <&e>%entry%" to_console
      - announce "<&b>ConfigFileGenerator<&co> <&c>%writePath%<&co> <&e>%entry%" to_flagged:ConfigFileGeneratorNotify
      - announce "<&b>ConfigFileGenerator<&co> <&4>*-----*" to_flagged:ConfigFileGeneratorNotify
      - announce "<&b>ConfigFileGenerator<&co> " to_flagged:ConfigFileGeneratorNotify
      }





################################################################################
#
# Configuration File Generator Command
#
#  Use this to build the example config files. You /could/ use it to build files
# for other scripts, but use at your own risk!
#
# I suppose you could add something like this to accept container names...
#
#    - if <c.args.find[-b].is[MORE].than[0]> {
#      - define file <c.args.get[<c.args.find[-b].add[1].as_int>]>
#      }
#      else {
#      - narrate "<&4>You must specify the basePath!"
#      }
#    - if <c.args.find[-i].is[MORE].than[0]> {
#      - define readID <c.args.get[<c.args.find[-i].add[1].as_int>]>
#      - narrate "%readID%"
#      }
#      else {
#      - narrate "<&4>You must specify the readID!"
#      }
#
'ConfigFileGeneratorCommand':
  type: world
  debug: false
  events:

    on cfg command:
    - if !<player.has_permission[denizen.cfg]> queue stop
    - determine passively fulfilled
    - flag <player> ConfigFileGeneratorNotify:true
    - define dryrun '<tern[<c.args.contains[--dryrun]>]:true || false>'
    - define verbose '<tern[<c.args.contains[--verbose]>]:true || false>'
    - define forcewrite '<tern[<c.args.contains[--force]>]:true || false>'
    - run s@ConfigFileGeneratorHelper def:ConfigFileGeneratorTest|Configurations|%dryrun%|%verbose%|%forcewrite% instantly
    - flag <player> ConfigFileGeneratorNotify:!




################################################################################
#                                                                              #
# Example Configurations Script Container                                      #
#                                                                              #
# This is how a Configurations Script Container should be structured.          #
#                                                                              #
# Each parent node under the script container defines a file name to generate. #
# The child nodes that follow are the entries for that individual file.        #
#                                                                              #
# In this example, 3 files are generated in denizen/ConfigFileGeneratorTest/   #
#                                                                              #
# Although the examples are a bit robotic, they clearly illustrate a range of  #
# usage scenarios.                                                             #
#______________________________________________________________________________#
#                                                                              #
#______________________________DO_NOT_EDIT_THIS_FILE___________________________#
#                                                                              #
#______________________________________________________________________________#

'ConfigFileGeneratorTest_Configurations':
  type: task
  debug: false


# ------ Single Value file container ------ #

  singleValues:
    keyA: 1
    keyB: 0.1
    keyC: -1
    keyD: NaN
    keyE: This is a StRiNg!


# ------ Single Lists file container ------ #

  singleLists:
    listA:
      - 1
      - 0.1
      - -1
      - NaN
      - This is a StRiNg!
    listB:
      - 2
      - 0.2
      - -2
      - nAn
      - This is a sTrInG!

# ------ Recursive Lists file container ------ #

  recursiveLists:
    list1:
      list1A:
        list1A1:
          key1A1A: 1
          list1A1A:
            - 1
            - 2
        list1A2:
          list1A2A:
            key1A2A1: 1
            list1A2A1:
              - 1
              - 2
      list1B:
        - 1
        - 2
    list2:
      list2A:
        key2A1: 1
        list2A1:
          - 1
          - 2
      list2B:
        key2B1: 1
        list2B1:
          - 1
          - 2
      list2C:
        key2C1: 1
        list2C1:
          - 1
          - 2


################################################################################