Sibyl2
The missing fact layer in codebases.
Install / Use
/learn @opensibyl/Sibyl2README
sibyl 2
The missing logical layer in codebases.
Status
| Name | Badge |
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Latest Version | |
| Unit Tests |
|
| Docker Image |
|
| Perf Tests |
|
| Code Coverage |
|
| Code Style |
|
Overview
2023.08.03
At present, the implementation of function relationships is too rough. If you want an accurate function call relationship diagram, you should prioritize using srctx.
This is because it is difficult for us to obtain an accurate call relationship without relying on compilation (or something like compilation). In the future, the focus of Sibyl2 will be on extracting more factual information from the language rather than relationship information.
sibyl2 is a service for extracting, managing and offering metadata of your code in codebase.
<img width="1217" alt="image" src="https://user-images.githubusercontent.com/13421694/227231024-3fff016d-4866-4061-8704-b8c9e4f880f3.png">Although Git is a widely used platform for version control and collaboration, it does not have the capability to analyze and interpret the logic of code.
Assuming my program now wants to know what is on line 35 of the extract_test.go file. If using GitLab, it is possible to find the corresponding text information, which may look like this:
func TestExtractString(t *testing.T) {
fileResult, err := ExtractFromString(javaCodeForExtract, &ExtractConfig{
LangType: core.LangJava,
ExtractType: extractor.TypeExtractFunction,
})
if err != nil {
panic(err)
}
for _, each := range fileResult.Units {
core.Log.Debugf("result: %s", each.GetDesc())
}
}
However, my program does not know what this text represents. This is even more difficult for programs written in other languages (such as Java or Python).
With sibyl2 API, you can get:
{
"repo_id": "sibyl2",
"rev_hash": "e995ef44372a93394199ea837b1e2eed375a71a0",
"path": "extract_test.go",
"signature": "sibyl2||TestExtractString|*testing.T|",
"tags": [],
"func": {
"name": "TestExtractString",
"receiver": "",
"namespace": "sibyl2",
"parameters": [
{
"type": "*testing.T",
"name": "t"
}
],
"returns": null,
"span": {
"start": {
"row": {
"$numberLong": "34"
},
"column": {
"$numberLong": "0"
}
},
"end": {
"row": {
"$numberLong": "45"
},
"column": {
"$numberLong": "1"
}
}
},
"extras": {},
"lang": "GOLANG"
}
}
And even its relationships?
{
"name": "TestExtractString",
...,
"calls": [
"object|*Function|GetDesc||string",
"object|*Symbol|GetDesc||string",
"sibyl2||ExtractFromString|string,*ExtractConfig|*extractor.FileResult,error",
"object|*Call|GetDesc||string",
"object|*Clazz|GetDesc||string"
],
"reverseCalls": []
}
And even all the relationships?

Also class, module and something else. See Reference for details.
In addition, sibyl2's unified logic layer can also convert different language logics into the same data structure for storage, which is friendly to OLAP and other tools.
You can use various mature analysis tools (such as clickhouse, superset, metabase, etc.) to further deconstruct your code repository based on sibyl2. For example, you can view the distribution of methods with the @Test annotation throughout the repository.
<img width="699" alt="image" src="https://user-images.githubusercontent.com/13421694/227699919-a6080730-ccea-42a3-b5ae-1ef3198426bb.png">Applying some global analysis:
<img width="1347" alt="image" src="https://user-images.githubusercontent.com/13421694/227760234-d8c5244b-d65d-4d5d-b984-a0f154baf9ac.png">Comparing the differences in methods, classes, and modules across each version:
<img width="1214" alt="image" src="https://user-images.githubusercontent.com/13421694/227701624-2a6fd71e-8733-480a-802c-ed1833652763.png">In summary, sibyl2 aims to build a layer of common logic on top of your code repository in a simple way, helping businesses better understand, analyze, and use the data in their code repository.
Deployment
With Docker (recommended for start up)
We have provided an official compose file. Just:
- copy and paste to your own
docker-compose.ymlfile docker-compose up
With an existed MongoDB
- download our binaries from the release page.
- add a
sibyl-server-config.jsonfile:
{
"binding": {
"dbtype": "MONGO",
"mongodbname": "sibyl2",
"mongouri": "mongodb+srv://<USERNAME>:<YOURPASSWORD>@XXXXXXXX.mongodb.net/test"
}
}
./sibyl server
With nothing
It can also run with no middleware and database installed, if you just want to take a try.
Just ./sibyl server without config file.
Usage
Upload

./sibyl upload --src . --url http://127.0.0.1:9876
You can upload from different machines (just correct the url). Usually it only takes a few seconds.
Now everything is ready.
Access with Mongo URI
There are many mature visualization tools that support MONGO URI, such as official compass and metabase. With this, accessing all your data is easy.

Our docker-compose file includes metabase, allowing you to connect to MongoDB and start analyzing your data by simply opening 127.0.0.1:3000.
Currently, our data is divided into three collections:
- fact_func: Function Information
- fact_clazz: Class Information
- rel_funcctx: Function Context Information
Access with sibyl2 clients
Of course, at the most time, developers access data programmatically. You can access all the data via different kinds of languages, to build your own tools:
For example, git diff with logical?
// assume that we have edited these lines
affectedFileMap := map[string][]int{
"pkg/core/parser.go": {4, 89, 90, 91, 92, 93, 94, 95, 96},
"pkg/core/unit.go": {27, 28, 29},
}
for fileName, lineList := range affectedFileMap {
strLineList := make([]string, 0, len(lineList))
for _, each := range lineList {
strLineList = append(strLineList, strconv.Itoa(each))
}
affectedFunctions, _, err := apiClient.BasicQueryApi.
ApiV1FuncctxGet(ctx).
Repo(projectName).
Rev(head.Hash().String()).
File(fileName).
Lines(strings.Join(strLineList, ",")).
Execute()
for _, eachFunc := range affectedFunctions {
// get all the calls details?
for _, eachCall := range eachFunc.Calls {
detail, _, err := apiClient.SignatureQueryApi.
ApiV1SignatureFuncGet(ctx).
Repo(projectName).
Rev(head.Hash().String()).
Signature(eachCall).
Execute()
assert.Nil(t, err)
core.Log.Infof("call: %v", detail)
}
}
}
| Language | Link | |------------|------------------------------------------------------| | Golang | https://github.com/opensibyl/sibyl-go-client | | Java | https://github.com/opensibyl/sibyl-java-client | | JavaScript | https://github.com/opensibyl/sibyl-javascript-client |
See more examples about how to use for details.
Languages support
| Languages | Function | Function Context | Class | |------------|----------|------------------|-------| | Golang | Yes | Yes | Yes | | Java | Yes | Yes | Yes | | Python | Yes | Yes | Yes | | Kotlin | Yes | Yes | Yes | | JavaScript | Yes | Yes | Yes |
Based on tree-sitter, it's very easy to add an extra language support.
Performance
We have tested it on some famous repos, like guava. And that's why we can say it is " fast enough".
See https://github.com/williamfzc/sibyl2/actions/workflows/perf.yml for details.
| Language | Repo
