Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support export of software dependencies from OCaml modules in the format “JSON” #7560

Closed
vicuna opened this issue Jun 17, 2017 · 16 comments · May be fixed by #9538
Closed

Support export of software dependencies from OCaml modules in the format “JSON” #7560

vicuna opened this issue Jun 17, 2017 · 16 comments · May be fixed by #9538

Comments

@vicuna
Copy link

vicuna commented Jun 17, 2017

Original bug ID: 7560
Reporter: @elfring
Status: acknowledged (set by @xavierleroy on 2017-06-22T18:08:59Z)
Resolution: open
Priority: normal
Severity: feature
Version: 4.03.0
Category: tools (ocaml{lex,yacc,dep,debug,...})
Tags: junior_job
Related to: #7559
Child of: #7558

Bug description

I imagine that it would be occasionally nice to perform higher level data processing with dependency information.
How do you think about to export corresponding data from referenced OCaml modules in the format “JavaScript Object Notation” (by the tool “ocamldep”)?

Additional information

https://en.wikipedia.org/wiki/JSON

@vicuna
Copy link
Author

vicuna commented Jun 22, 2017

Comment author: @xavierleroy

Sounds reasonable. A proof-of-concept implementation as a pull request would be welcome.

@gasche
Copy link
Member

gasche commented Mar 16, 2019

Having to add a json printer to the compiler sounds cumbersome (at least with the current state without vendoring (we cannot depend on third-party OCaml libraries)). On the other hand, several libraries represent JSON with structural types (polymorphic variants), and we could add a function that exports to that without introducing any extra dependency.

type t = [
    | `Null
    | `Bool of bool
    | `Int of int
    | `Float of float
    | `String of string
    | `Assoc of (string * t) list
    | `List of t list
]

To use this, users would then have to build their own executable program, linking with Compilerlibs and their favorite JSON serialization library. It sounds easy to add an external ocamldep-json program to opam that does just that.

This would still require a refactoring of the ocamldep codebase; typing/depend.ml is too low-level for this to be convenient (it is not a good user-facing API), and driver/makedepend.ml hides all its content behind a main : unit -> unit function. We should expose more high-level functions in driver/makedepend.ml for this to be practical. The functions could take a list of files and return, for one, an OCaml-datatype representation of the dependency graph (for example (string * file_kind * String.Set.t * string list) list as used internally, preferably with better type definitions to make this nicer to read!), and for the other a JSON-isomorphic representation of the same dependency graph.

@dbuenzli
Copy link
Contributor

Having to add a json printer to the compiler sounds cumbersome

To be honest JSON is easy enough to output things by hand, it is just a matter of escaping strings correctly (20 lines).

In this particular case I more doubt the usefulness of JSON output given the current complexity of the data being output (and unless part of a larger change to output machine readable format in the whole tooling chain, e.g. error messages, etc).

We should expose more high-level functions in driver/makedepend.ml for this to be practical.

Having recently cargo-culted and tweaked the AST recursion of death that is in parsing/depend.ml to output more precise dependency information for another tool, I'd be glad if that could be the case.

I hate when my tools are dependent on the AST since they break at almost every new version of the compiler (moreover the persons evolving the language would do the right thing for me there when they change it...)

@gasche
Copy link
Member

gasche commented Mar 16, 2019

Yes, I think that exposing better, high-level APIs to some compilation services should be a side-effect of any "produce machine-readable output for foo" work for the compiler.

(Would you be willing to send a PR for this part?)

@dbuenzli
Copy link
Contributor

(Would you be willing to send a PR for this part?)

Assuming you meant pull request and not problem report, that would be premature for now. But when I think I have the right thing, I might.

@gasche
Copy link
Member

gasche commented Mar 16, 2019

What I had in mind was very simple: I would add a function in makedepend.ml that would take a list of filenames as input (or maybe Implem of path | Interf of path), call file_dependencies on each of them, and return the content of the !files reference after the call. I might give it a try.

@dbuenzli
Copy link
Contributor

I see, I'm more interested in getting module usage/definition outlines of the following form:

type mod_path = string
type import =
| Open of mod_path * import list
| Using of String.Set.t

type imports = import list
type exports = String.Set.t
type outline = { imports : imports; exports : exports }

val outline_of_file  : string -> outline

@Octachron
Copy link
Member

What is the second argument of Open? The list of imports in the scope of the open statement?

Also codept can already output a more precise version of exports with codept -sig <module> [-format json].

@dbuenzli
Copy link
Contributor

What is the second argument of Open? The list of imports in the scope of the open statement?

Yes.

@Octachron
Copy link
Member

May I ask what is your use case? I am asking because there is not enough information left in this format for inferring precise dependency for instance.

@dbuenzli
Copy link
Contributor

Best-effort automatic dependency discovery.

I am asking because there is not enough information left in this format for inferring precise dependency for instance.

What would you add ?

@Octachron
Copy link
Member

The minimal information (location information excepted) needed is more or less
https://github.com/Octachron/codept/blob/master/lib/m2l.mli#L39
because definitions, opens and includes interact with each other.
(and yes codept ast can be outputed as json or sexp codept -m2l).
May I suggest you to try codept and tell me what changes would be needed to fit your needs?

@elfring
Copy link

elfring commented Apr 15, 2019

I am still curious how affected software components can be improved also for this issue.

@github-actions
Copy link

github-actions bot commented May 8, 2020

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 8, 2020
@nojb
Copy link
Contributor

nojb commented May 8, 2020

This is being worked on #9538

@github-actions github-actions bot closed this as completed Jun 8, 2020
@nojb nojb removed the Stale label Jun 8, 2020
@nojb nojb reopened this Jun 8, 2020
@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants