feat: add lfmf and ontology tooling#72
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds two new workspace CLI tools: lfmf-counter for tracking/printing lesson counters, and ontology-extractor for extracting Rust AST terms and emitting a simple ontology graph/summary, plus the workspace/lockfile wiring to build them.
Changes:
- Introduce
crates/lfmf-counterlibrary +lfmf-statsCLI for persisting and reporting tool-level counters. - Introduce
crates/ontology-extractorlibrary +ontology-extractorCLI for walking.rsfiles, collecting terms, and outputting a summary/JSON graph. - Register both crates in the workspace and update
Cargo.lock(notablyclap).
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/ontology-extractor/src/main.rs | New CLI entrypoint for running extraction and printing summary/JSON output. |
| crates/ontology-extractor/src/lib.rs | New extraction + graph-building library using walkdir + syn::visit. |
| crates/ontology-extractor/Cargo.toml | New crate manifest and deps for ontology extractor. |
| crates/lfmf-counter/src/main.rs | New lfmf-stats CLI with subcommands for summary/list/problematic/top. |
| crates/lfmf-counter/src/lib.rs | New persistent counter library (serde + json file) and basic tests. |
| crates/lfmf-counter/Cargo.toml | New crate manifest and deps for LFMF counter. |
| crates/lfmf-counter/.lfmf-counters.json | Added sample/state JSON counter file. |
| Cargo.toml | Add the two new crates to workspace members; small comment edit under lints. |
| Cargo.lock | Lockfile updates to include the new crates and bump clap. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [package] | ||
| name = "ontology-extractor" | ||
| version = "1.8.1" | ||
| edition = "2021" | ||
| description = "Rust AST extraction for ontological knowledge graph construction" | ||
| license = "MIT" | ||
|
|
| [package] | ||
| name = "lfmf-counter" | ||
| version = "1.8.1" | ||
| edition = "2021" | ||
| description = "LFMF lesson counter with $🦨++ and $🐛++ support" | ||
| license = "MIT" | ||
|
|
| impl Default for LfmfCounter { | ||
| fn default() -> Self { | ||
| Self { | ||
| counters: HashMap::new(), | ||
| storage_path: Self::default_storage_path(), | ||
| } | ||
| } |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
| let tools = counter.get_stats().await?; | ||
|
|
||
| if args.sort_by_activity { | ||
| let active_tools = counter | ||
| .get_tools_by_activity() | ||
| .into_iter() | ||
| .cloned() | ||
| .collect::<Vec<_>>(); | ||
| print_tools_list(&active_tools, args.show_suggestions, args.limit); | ||
| } else { | ||
| print_tools_list(&tools, args.show_suggestions, args.limit); | ||
| } |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
| pub async fn extract_rust_idioms(&self, crate_path: &Path) -> Result<Vec<RustTerm>> { | ||
| let mut terms = Vec::new(); | ||
|
|
||
| for entry in WalkDir::new(crate_path) | ||
| .into_iter() | ||
| .filter_entry(|entry| entry.file_name() != "target") | ||
| { | ||
| let entry = entry.context("failed to walk crate path")?; | ||
| if !entry.file_type().is_file() | ||
| || entry.path().extension().and_then(|ext| ext.to_str()) != Some("rs") | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| let source = fs::read_to_string(entry.path()) | ||
| .with_context(|| format!("failed to read {}", entry.path().display()))?; | ||
| let syntax = syn::parse_file(&source) | ||
| .with_context(|| format!("failed to parse {}", entry.path().display()))?; | ||
|
|
| fn default_storage_path() -> PathBuf { | ||
| std::env::current_dir().unwrap().join(COUNTER_FILE) | ||
| } |
| // Sort by activity (default) or tool name | ||
| #[arg(short, long)] | ||
| sort_by_activity: bool, | ||
|
|
||
| // Show suggestions for tools | ||
| #[arg(short, long)] | ||
| show_suggestions: bool, | ||
|
|
||
| // Limit number of tools to show |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Brian Horakh <35611074+elasticdotventures@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Brian Horakh <35611074+elasticdotventures@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Brian Horakh <35611074+elasticdotventures@users.noreply.github.com>
|
@copilot apply changes based on the comments in this thread |
- Use workspace inheritance (version/edition/license) in both Cargo.toml files - Add [lints] workspace = true to both crates - Replace unwrap() with expect() in default_storage_path() - Use doc comments (///) in ListArgs for clap --help output - Fix extract_rust_idioms dedup key to include classification (preserves distinct items with same name in different namespaces) - Wrap blocking I/O in spawn_blocking so async runtime is not blocked - Use eprintln! for verbose status so --format json output stays valid JSON Agent-Logs-Url: https://github.com/PromptExecution/l3dg3rr/sessions/b4d10f5c-691b-42f3-90f6-c321580465b8 Co-authored-by: elasticdotventures <35611074+elasticdotventures@users.noreply.github.com>
Agent-Logs-Url: https://github.com/PromptExecution/l3dg3rr/sessions/b4d10f5c-691b-42f3-90f6-c321580465b8 Co-authored-by: elasticdotventures <35611074+elasticdotventures@users.noreply.github.com>
Applied all changes from the review thread (commits
|
Summary
lfmf-counterworkspace crate and CLIontology-extractorworkspace crate and CLINotes
cargo check -p lfmf-counter,cargo test -p lfmf-counter, andcargo check -p ontology-extractortemp_lib.rsandtemp_ont.rsout of the PR