loreanvictor / tmplr

Automate Code Scaffolding
MIT License
26 stars 0 forks source link

Is there a way to set variables depending on choices? #3

Closed Judahh closed 1 year ago

Judahh commented 1 year ago

Is there a way to programatically read a var? something like:

- read: database_type
    prompt: What database type do you want to use?
    choices:
      - MongoDB
      - PGSQL
      - MSSQL

  - if: database_type == 'MongoDB'
    read: database_var
    eval: "const database = new MongoPersistence(readDatabase, {\n\tsample: new SampleSchema(),\n});"
    else:
      read: database_var
      eval: "const database = new DAOPersistence(sql, {\n\tsample: new SampleDAO(),\n});"

  - if: database_type == 'PGSQL'
    steps:
      - read: database_import
        eval: "import { PGSQL } from '@flexiblepersistence/pgsql';\nimport SampleDAO from './dAOs/sampleDAO';"
      - read: database_sql
        eval: "const sql = new PGSQL(readDatabase);"
    else:
      if: database_type == 'MSSQL'
      steps:
      - read: database_import
        eval: "import { MSSQL } from '@flexiblepersistence/mssql';\nimport SampleDAO from './dAOs/sampleDAO';"
      - read: database_sql
        eval: "const sql = new MSSQL(readDatabase);"
      else:
        steps:
          - read: database_import
            eval: "import SampleSchema from './schemas/sampleSchema';"
          - read: database_sql
            eval: ""
loreanvictor commented 1 year ago

Yes, multiple ways. You can do it inline using eval with steps:

steps:
  - read: database
    prompt: Which database?
    choices:
      - MongoDB:
          steps:
            - read: var
              eval: 'X'
          eval: 'MongoDB'
      - Postgres:
          steps:
            - read: var2
              eval: 'Y'
          eval: 'Postgres'
  - update: '*.txt'

Or you can check inequality by combining if and skip:

steps:
  - read: database
    prompt: Which database?
    choices:
      - MongoDB
      - Postgres
  - if:
      eval: '{{ database | skip: MongoDB }}' # if database is NOT MongoDB
    read: var2
    eval: 'Y'
    else:
      read: var
      eval: 'X'
  - update: '*.txt'

That said, I would recommend NOT doing that unless you plan to also do the corresponding updates / copies alongside the reading/defining conditional variables, as otherwise your files would have variables that are not updated (since they are not defined). For example, if you have some_file.txt like this:

database: {{ tmplr.database }}
var: {{ tmplr.var }}
var2: {{ tmplr.var2 }}

and you run any of the templating recipes outlined above and choose MongoDB, then some_file.txt would become the following:

database: MongoDB
var: X
var2: {{ tmplr.var2 }}

Which is perhaps not the intended behavior. The correct version would be something like this:

steps:
  - read: database
    prompt: Which database?
    choices:
      - MongoDB
      - Postgres
  - if:
      eval: '{{ database | skip: MongoDB }}' # if database is NOT MongoDB
    steps:
      - read: var2
        eval: 'Y'
      - update: 'some_file.txt'
    else:
      steps:
        - read: var
          eval: 'X'
        # Update different files when different variables are defined.
        - update: 'some_other_file.txt'
loreanvictor commented 1 year ago

P.S. I recognise that the example with if is not as straightforward as it can be (since we can only check for inequality and not equality). If this becomes a recurring pattern, perhaps some form of syntactic support should be added. Alternatives would be:

Judahh commented 1 year ago

Thanks!

tommy-mitchell commented 1 year ago

@loreanvictor I think, barring equality signs, a match pipe is a good enough solution.

loreanvictor commented 1 year ago

@tommy-mitchell just added a matches pipe (via this, and this). You'd need to update to latest version (0.2.2) to access this pipe.

Note that this might be deprecated in a future major update if further support for conditionals is added (or it is proven not that common of a use-case, though I doubt the latter).