c3lang / c3c

Compiler for the C3 language
https://c3-lang.org
GNU Lesser General Public License v3.0
2.78k stars 168 forks source link

Create functions from c3c to manipulate the project.json #1311

Open lerno opened 2 months ago

lerno commented 2 months ago

Yes, it's straightforward to edit the project.json, but the downside is that it's currently actually json5. Plus there is some need to consult the documentation just to do simple things, and there is no way for a beginner to really know what the parts do.

So a first feature could be something like: c3c project view, which looks at the project.json and prints something like:

Authors: John Doe <john.doe@example.com>
Version: 0.1.0
Project language target: 1
Warnings used: no-unused
Search paths, .c3l files: lib
Dependencies, .c3l: *none*
Source folders: src/**
Source folders, c files: csource/**
Output location: build
Default optimization level: O0
Targets
   Name: foo
   Type: executable     

And then you could do things like c3c project add-target <name> executable c3c project update-target <name> set target windows-x64

Really trivial things to do, but this allows for a separate help on the project: c3c project project help-target which might list:

project update-target <name> set target [target name]
project update-target <name> set type [executable | static-lib | dynamic-lib]

As a first step, just getting project view done is enough.

cheese3660 commented 2 months ago

Alright, I'm thinking of taking a look at doing this, a question though, all the commands use the BuildOptions parser, but the way this is being described is almost as a separate set of commands of the form c3c project [subcommand], of which none of the other functions are prefixed like this, and the parser for build-options would also treat the add-target, executable, set, target, etc... part of the given commands as files instead. Therefore I'm thinking a specialized options struct and parser for this subset of commands might be a decent idea especially since none of the general options for building apply here, does this sound right to you, or would you like for this to still be fit into the BuildOptions struct?

lerno commented 2 months ago

I think it should be fairly straightforward to fit it in the build-options still. You just need to forward to a separate function that does the more complex parsing, e.g.

    if (arg_match("project"))
    {
        options->command = COMMAND_PROJECT;
        parse_project_options(options);
        return;
    }
cheese3660 commented 2 months ago

Gotcha, then I'll go ahead and do it that way

cheese3660 commented 2 months ago

How should project view handle JSON that doesn't conform to the schema, say someone has authors as a string rather than a list of strings for example? Should it print something like Authors: <expected a string array> or should it just error out?

lerno commented 2 months ago

Error out, saying it is invalid and what key is invalid.

lerno commented 2 months ago

I've been thinking of having a key "vendor" which has a completely free schema. That way IDEs and stuff can put things in there and it's just ignored by the compiler, but they can use it.

kostyavechkanov commented 2 months ago

I am looking for a good first issue and was playing with add-target locally. How should add-target and update-target be implemented?

I see 2 options:

  1. Use string template (as its done in project_manipulation.c) and insert into the project.json into specific line/column
  2. Read the whole project.json to build JSONObject hierarchy. Insert/Update JSONObject of the target. Serialize root JSONObject into file.

For the second option, I couldn't find any ready to use functions to convert JSONObject to string (json.c seems to be focused on parsing only). Should I write something similar to what is in json_output.c?

For vendor should we just accept a string that may be a JSON object (not just string value)? Or we should implement some sort of pathing, for example project update-target target1 set vendor.visual_studio.version 2022 to update to { ... "targets": { "target1": { ... "vendor": { "visual_studio": "version": "2022" } ... } } ... }

lerno commented 2 months ago

I think it should be "read the file as json, modify, print the json". It's fine to discard the comments. When it comes to a target you want to give:

  1. name
  2. type (exe/static-lib/dynamic-lib)
  3. Optionally the target (e.g. windows-x64)

Other commands can be used to manipulate the target further.

lerno commented 2 months ago

For vendor, maybe it should be:

"vendor" : {
  "com.foo.bar": ... arbitrary json ...
  "com.baz.Foo": ... arbitrary json ...
}

So a unique key, preferably reverse path like above, then any data inside of that.