c3c icon indicating copy to clipboard operation
c3c copied to clipboard

Create functions from c3c to manipulate the project.json

Open lerno opened this issue 1 year ago • 9 comments

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 <[email protected]>
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.

lerno avatar Aug 05 '24 08:08 lerno

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?

cheese3660 avatar Aug 05 '24 10:08 cheese3660

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;
	}

lerno avatar Aug 05 '24 11:08 lerno

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

cheese3660 avatar Aug 05 '24 11:08 cheese3660

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?

cheese3660 avatar Aug 05 '24 12:08 cheese3660

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

lerno avatar Aug 05 '24 12:08 lerno

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.

lerno avatar Aug 05 '24 12:08 lerno

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" } ... } } ... }

kid-regent avatar Aug 08 '24 07:08 kid-regent

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 avatar Aug 08 '24 11:08 lerno

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.

lerno avatar Aug 08 '24 11:08 lerno

Could this be expanded upon to have more options? I was thinking of a list-targets subcommand for project, that could take in an additional flag to print the shorthand version or the long version.

A mockup:

$ c3c project list-targets
Targets:
- hello
    Name: hello
    Type: executable
- world
    Name: world
    Type: executable

And

$ c3c project list-targets --short
hello
world

You'd have to decide whether '--short' prints the short version, or if the default one prints the short version and '--verbose' prints the full.

This subcommand could also be a subcommand or flag for project view, where the idea then is to show only a part of of what view shows.

The usecase for this would mostly be for other tooling (like completions) to query specific parts of the project-config. One example would be a completion script that after $ c3c run would look at c3c project list-targets --short to complete the command, enabling very smart completions without having to parse the whole output of c3c project view.

EDIT: After talking on Discord about this, I will try to implement this as a c3c project --list-project-targets or c3c project list-project-targets, not sure yet.

BWindey avatar Jan 16 '25 11:01 BWindey