Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions entire-sem/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

`entire-sem` is an Entire CLI plugin prototype for entity-level checkpoint context.

Entire already knows a checkpoint touched `auth.py` or `.github/workflows/ci.yml`.
This plugin answers the next question: which semantic entities changed inside that file?
Entire already knows a checkpoint touched `auth.py`. This plugin answers the next question:
which functions, classes, types, or methods changed inside that file?

Once built as `entire-sem` and installed as an Entire plugin, it is invoked as:

Expand All @@ -25,7 +25,6 @@ The MVP uses a tree-sitter-backed parser for:
- Python
- JavaScript / TypeScript
- Rust, including inherent `impl` methods
- YAML, including GitHub Actions workflow sections and jobs

The parser is isolated behind `internal/sem`, so the command surface can stay stable
while the semantic model gets richer.
Expand Down Expand Up @@ -88,8 +87,7 @@ checkpoint context at the entity level instead of stopping at "this file changed
`entire-sem` is a plugin-shaped proof of concept for that idea:

- parse the before and after git trees with tree-sitter
- extract named entities like functions, classes, methods, structs, traits, types,
YAML workflow sections, and GitHub Actions jobs
- extract named entities like functions, classes, methods, structs, traits, and types
- compare signatures and normalized bodies
- build a heuristic dependent count from parsed references in the target tree,
marking same-short-name method references as ambiguous when they cannot be
Expand Down
59 changes: 0 additions & 59 deletions entire-sem/internal/sem/analyze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,65 +80,6 @@ func TestAnalyzeGitRangeDependentCounts(t *testing.T) {
}
}

func TestAnalyzeGitRangeIncludesGitHubWorkflowYAML(t *testing.T) {
repo := t.TempDir()
git(t, repo, "init")
git(t, repo, "config", "user.name", "Entire Sem Test")
git(t, repo, "config", "user.email", "sem@example.com")

write(t, repo, ".github/workflows/ci.yml", `name: CI
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: go test ./...
`)
git(t, repo, "add", ".")
git(t, repo, "commit", "-m", "initial")
base := rev(t, repo, "HEAD")

write(t, repo, ".github/workflows/ci.yml", `name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: go test -race ./...
`)
git(t, repo, "add", ".")
git(t, repo, "commit", "-m", "update workflow")
head := rev(t, repo, "HEAD")

result, err := AnalyzeGitRange(context.Background(), repo, base, head, nil)
if err != nil {
t.Fatal(err)
}
if len(result.Files) != 1 {
t.Fatalf("files = %#v", result.Files)
}
file := result.Files[0]
if file.Path != ".github/workflows/ci.yml" {
t.Fatalf("path = %q", file.Path)
}
if file.Language != "YAML" {
t.Fatalf("language = %q", file.Language)
}
if change := requireChangeKind(t, result, "job", "jobs.test"); change.Type != "body_changed" {
t.Fatalf("workflow job change = %#v, want body_changed", change)
}
if change := requireChangeKind(t, result, "section", "on"); change.Type != "body_changed" {
t.Fatalf("workflow trigger change = %#v, want body_changed", change)
}
}

func TestAnalyzeGitRangePythonAssignedLambdaSignatureChange(t *testing.T) {
repo := t.TempDir()
git(t, repo, "init")
Expand Down
20 changes: 7 additions & 13 deletions entire-sem/internal/sem/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/smacker/go-tree-sitter/rust"
treesittertsx "github.com/smacker/go-tree-sitter/typescript/tsx"
treesitterts "github.com/smacker/go-tree-sitter/typescript/typescript"
treesitteryaml "github.com/smacker/go-tree-sitter/yaml"
)

type languageSpec struct {
Expand All @@ -24,15 +23,13 @@ type languageSpec struct {
}

var treeSitterLanguages = map[string]languageSpec{
".go": {language: "Go", grammar: golang.GetLanguage()},
".py": {language: "Python", grammar: python.GetLanguage()},
".js": {language: "JavaScript", grammar: javascript.GetLanguage()},
".jsx": {language: "JavaScript", grammar: treesittertsx.GetLanguage()},
".ts": {language: "TypeScript", grammar: treesitterts.GetLanguage()},
".tsx": {language: "TypeScript", grammar: treesittertsx.GetLanguage()},
".rs": {language: "Rust", grammar: rust.GetLanguage()},
".yaml": {language: "YAML", grammar: treesitteryaml.GetLanguage()},
".yml": {language: "YAML", grammar: treesitteryaml.GetLanguage()},
".go": {language: "Go", grammar: golang.GetLanguage()},
".py": {language: "Python", grammar: python.GetLanguage()},
".js": {language: "JavaScript", grammar: javascript.GetLanguage()},
".jsx": {language: "JavaScript", grammar: treesittertsx.GetLanguage()},
".ts": {language: "TypeScript", grammar: treesitterts.GetLanguage()},
".tsx": {language: "TypeScript", grammar: treesittertsx.GetLanguage()},
".rs": {language: "Rust", grammar: rust.GetLanguage()},
}

type TreeSitterParser struct{}
Expand All @@ -47,9 +44,6 @@ func (TreeSitterParser) Parse(path, content string) ([]Entity, string) {
if err != nil || root == nil || root.IsNull() {
return nil, spec.language
}
if spec.language == "YAML" {
return yamlEntities(path, content), spec.language
}

var entities []Entity
walkEntities(root, src, "", &entities)
Expand Down
57 changes: 0 additions & 57 deletions entire-sem/internal/sem/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -622,29 +622,6 @@ impl<T: Clone> IntoIterator for Bag<T> { fn into_iter(self) -> Iter<T> { todo!()
`,
names: []string{"User", "Bag", "validate", "Run", "Run.run", "User.active", "Bag.unwrap_owned", "User.fmt", "Bag.into_iter"},
},
{
path: ".github/workflows/ci.yml",
language: "YAML",
input: `name: CI
on:
push:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: go test ./...
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./scripts/deploy.sh
`,
names: []string{"ci", "on", "permissions", "jobs.test", "jobs.deploy"},
},
}

for _, tt := range tests {
Expand All @@ -664,40 +641,6 @@ jobs:
}
}

func TestTreeSitterParserSupportsYAMLWorkflowExtensions(t *testing.T) {
if !Supported(".github/workflows/ci.yml") {
t.Fatal(".yml workflow should be supported")
}
if !Supported(".github/workflows/deploy.yaml") {
t.Fatal(".yaml workflow should be supported")
}

entities, language := TreeSitterParser{}.Parse(".github/workflows/deploy.yaml", `name: Deploy
on: workflow_dispatch
jobs:
publish:
runs-on: ubuntu-latest
steps:
- run: echo deploy
`)
if language != "YAML" {
t.Fatalf("language = %q", language)
}
seen := map[string]string{}
for _, entity := range entities {
seen[entity.Name] = entity.Kind
}
for name, kind := range map[string]string{
"deploy": "workflow",
"on": "section",
"jobs.publish": "job",
} {
if seen[name] != kind {
t.Fatalf("%s kind = %q, want %q in %#v", name, seen[name], kind, entities)
}
}
}

func TestTreeSitterParserIgnoresNonFunctionTypeScriptProperties(t *testing.T) {
entities, language := TreeSitterParser{}.Parse("app.ts", `interface Api {
url: string
Expand Down
Loading