hrszpuk / rectx

The powerful little project manager for the ReCT programming language!
GNU General Public License v3.0
6 stars 1 forks source link

Config file enhancement (config.toml project file) #6

Closed hrszpuk closed 2 years ago

hrszpuk commented 2 years ago

Project files: config.toml

ReCTx will generate several files and directories on project creation. Currently, it will generate a src directory storing a main.rct, and a REAADME.md. Currently the project's generated by ReCTx have no form of configuration (customisation)...

The config.toml

As you can probably guess, the config.toml file aims to store configuration settings, project information, etc... The config file will be generated by rectx new along with the other generated files and directories. The ReCT programmer can then modify the config file which will be read by rectx during building and running do customise how they want rectx to perform certain tasks.

An example of how the config file could look:

[project]
# For storing project information
name = "example-project"
version = "0.1.0"
authors = ["user"]
remote = "github.com/user/example-project"

[profile.build]
# For storing build information (for rectx build)
compiler = "rgoc"
compiler.flags = ["-xx", "-O2"]
output.name = "program"
output.dir = "target/"
source.dir = "src/"
source.main = "main.rct"

[profile.run]
# For storing run information (for rectx run)
compiler = "rctc"
compiler.flags = ["--example-flag"]
output.name = "program"
output.dir = "target/"
source.dir = "src/"
source.main = "main.rct"

Benefits of a config.toml file

This would allow for a lot of customisation on how ReCT programmers would like their programs to compile/run. This also keeps everything in one place and could be committed to repositories allowing for easy compilation by collaborators (instead of having to explain how to compile, people will be able to just do rectx build!).

A config file also has wide-scale expand-ability! It would be very easy to add a new benchmark profile or custom profiles with something like rectx run custom-profile-name (this of course being a completely custom way for the user build/run their programs). Not to mention the example provided above is only an example of what could be possible, more fields and options could definitely be added.

hrszpuk commented 2 years ago

Created branch configtoml for development on this feature!

mauro-balades commented 2 years ago

I think there is a more clean solution to this (I also think that ends in syntax errors).

here:

[profile]
[[build]]
# For storing build information (for rectx build)
compiler = "rgoc"
compiler.flags = ["-xx", "-O2"]
output.name = "program"
output.dir = "target/"
source.dir = "src/"
source.main = "main.rct"

[[run]]
# For storing run information (for rectx run)
compiler = "rctc"
compiler.flags = ["--example-flag"]
output.name = "program"
output.dir = "target/"
source.dir = "src/"
source.main = "main.rct"
hrszpuk commented 2 years ago

@mauro-balades Thank you for your suggestion πŸ‘πŸΌ

The TOML Specification for table header naming follows the same rules as key naming. This means profile.build and profile.run are normal ways of declaring tables, and the dotted key syntax is specifically mentioned in the specification.

The syntax you've provided is an array of tables. While utilising table arrays is a really good idea, the naming you've assigned them makes them less distinct and I feel it would impact readability of the config.toml if more tables were added in the future.

Furthermore, I think it would be harder to parse your table into structures as using table arrays like that would create a structure containing two lists containing a single structure element. Meanwhile, the example provided in the original issue post is much simpler as it is precisely two structures. As a rule of thumb, I think keeping configuration serialisation and deserialisation as simple as possible would be overall more beneficial to the projects development.

Below I've posted two JSON objects that are examples of both of our TOML configs. Although this discussion has nothing to do with JSON, I feel this is a good way to visual the differing complexity between the two configs as JSON objects can loosely look like how a structure with it's members can look.

This is your example from above converted into JSON. This would require the config module to read out of the profile struct both build and run which would be lists containing a single structure.

{
    "profile": {
        "build": [
            {
                "compiler": "rgoc",
                "compiler.flags": ["-xx", "-O2"],
                "output.name": "program",
                "output.dir": "target/",
                "source.dir": "src/",
                "source.main": "main.rct"
            }
        ],
        "run": [
            {
                "compiler": "rctc",
                "compiler.flags": ["--example-flag"],
                "output.name": "program",
                "output.dir": "target/",
                "source.dir": "src/",
                "source.main": "main.rct"
            }
        ]
    }
}

Below is the original issue example. As you can see this is much simpler and the config module would only have to read two structures.

{
    "profile.build": {
        "compiler": "rgoc",
        "compiler.flags": ["-xx", "-O2"],
        "output.name": "program",
        "output.dir": "target/",
        "source.dir": "src/",
        "source.main": "main.rct"
    },
    "profile.run": {
        "compiler": "rctc",
        "compiler.flags": ["--example-flag"],
        "output.name": "program",
        "output.dir": "target/",
        "source.dir": "src/",
        "source.main": "main.rct"
    }
}

In conclusion, I think it the original issue post's config is better as it would be easier for the config module to read, and is more explicit to exactly what run and build are (build profiles) therefore the addition of new tables would reduce the readability of the config.toml less than the example you have posted.

Thank you for your suggestion, it is duly noted, and I may utilise your TOML table array idea in a future addition to the config module. πŸ‘πŸΌ

hrszpuk commented 2 years ago

Update on implementation

Currently testing some deserialisation and noticed dotted keys and dotted tables are being wrapped in double quotes. I dislike the wrapper; I think the wrapper makes the dotted keys and tables ugly. Perhaps I should use dashes ("-") for table headers and underscores ("_") for keys in replacement for dots? This is a shame because I liked the dotted style, and the dotted style is in the specification so I don't understand why toml-rs would wrap dotted keys and tables in a string.

Current example of outputted "default" config in TOML format.

[project]
name = "test"
version = "0.1.0"
authors = []
remote = ""

["profile.build"]
compiler = "rgoc"
"compiler.flags" = ["-xx", "-O"]
"source.dir" = "src"
"source.main" = "main.rct"
"output.dir" = "target/build"
"output.name" = "test"

["profile.run"]
compiler = "rgoc"
"compiler.flags" = ["-xx"]
"source.dir" = "src"
"source.main" = "main.rct"
"output.dir" = "target/run"
"output.name" = "test"
mauro-balades commented 2 years ago

Update on implementation

Currently testing some deserialisation and noticed dotted keys and dotted tables are being wrapped in double quotes. I dislike the wrapper; I think the wrapper makes the dotted keys and tables ugly. Perhaps I should use dashes ("-") for table headers and underscores ("_") for keys in replacement for dots? This is a shame because I liked the dotted style, and the dotted style is in the specification so I don't understand why toml-rs would wrap dotted keys and tables in a string.

Current example of outputted "default" config in TOML format.

[project]
name = "test"
version = "0.1.0"
authors = []
remote = ""

["profile.build"]
compiler = "rgoc"
"compiler.flags" = ["-xx", "-O"]
"source.dir" = "src"
"source.main" = "main.rct"
"output.dir" = "target/build"
"output.name" = "test"

["profile.run"]
compiler = "rgoc"
"compiler.flags" = ["-xx"]
"source.dir" = "src"
"source.main" = "main.rct"
"output.dir" = "target/run"
"output.name" = "test"

Just use my idea πŸ‘πŸ½