chore: import upstream snapshot with attribution
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
exportFormat string
|
||||
exportOut string
|
||||
exportOutDir string
|
||||
exportRepo string
|
||||
exportKinds []string
|
||||
exportLanguages []string
|
||||
exportDropSynthetic bool
|
||||
exportMermaidScope string
|
||||
exportMermaidMinComm int
|
||||
exportMermaidMaxComm int
|
||||
exportOnCommit bool
|
||||
)
|
||||
|
||||
var exportCmd = &cobra.Command{
|
||||
Use: "export [path]",
|
||||
Short: "Export the graph to Cypher (Neo4j/Memgraph) or GraphML (yEd/Gephi/Cytoscape)",
|
||||
Long: `Export the graph the daemon owns to a portable file for visualization or
|
||||
external query. Runs export_graph against the daemon that tracks the repo
|
||||
(requires a running daemon).
|
||||
|
||||
Loading a Cypher export into Neo4j:
|
||||
cypher-shell -u neo4j -p <password> -f graph.cypher
|
||||
|
||||
Loading a GraphML export into Gephi: File → Open → graph.graphml
|
||||
`,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: runExport,
|
||||
}
|
||||
|
||||
func init() {
|
||||
exportCmd.Flags().StringVar(&exportFormat, "format", "cypher", "output format: cypher | graphml | mermaid")
|
||||
exportCmd.Flags().StringVar(&exportOut, "out", "", "output file (default: stdout)")
|
||||
exportCmd.Flags().StringVar(&exportOutDir, "out-dir", "",
|
||||
"output directory (mermaid scope=all writes one file per scope here)")
|
||||
exportCmd.Flags().StringVar(&exportRepo, "repo", "", "filter to one repo prefix (default: all)")
|
||||
exportCmd.Flags().StringSliceVar(&exportKinds, "kinds", nil,
|
||||
"comma-separated node kinds to include (function,method,field,type,interface,...). Default: all.")
|
||||
exportCmd.Flags().StringSliceVar(&exportLanguages, "languages", nil,
|
||||
"comma-separated languages to include. Default: all.")
|
||||
exportCmd.Flags().BoolVar(&exportDropSynthetic, "no-synthetic", false,
|
||||
"drop synthetic stub nodes for unresolved/external/annotation endpoints (default: keep them so call topology stays intact)")
|
||||
exportCmd.Flags().StringVar(&exportMermaidScope, "scope", "architecture",
|
||||
"(mermaid) diagram scope: architecture | communities | processes | all")
|
||||
exportCmd.Flags().IntVar(&exportMermaidMinComm, "min-community", 3,
|
||||
"(mermaid) minimum community size to include")
|
||||
exportCmd.Flags().IntVar(&exportMermaidMaxComm, "max-communities", 20,
|
||||
"(mermaid) maximum communities to include")
|
||||
exportCmd.Flags().BoolVar(&exportOnCommit, "on-commit", false,
|
||||
"informational marker: this run was triggered by a post-commit hook")
|
||||
rootCmd.AddCommand(exportCmd)
|
||||
}
|
||||
|
||||
func runExport(cmd *cobra.Command, args []string) error {
|
||||
repoPath := "."
|
||||
if len(args) == 1 {
|
||||
repoPath = args[0]
|
||||
}
|
||||
format := strings.ToLower(exportFormat)
|
||||
|
||||
toolArgs := map[string]any{
|
||||
"format": format,
|
||||
"repo": exportRepo,
|
||||
"kinds": strings.Join(exportKinds, ","),
|
||||
"languages": strings.Join(exportLanguages, ","),
|
||||
"no_synthetic": exportDropSynthetic,
|
||||
"scope": exportMermaidScope,
|
||||
"min_community": exportMermaidMinComm,
|
||||
"max_communities": exportMermaidMaxComm,
|
||||
}
|
||||
|
||||
// The daemon writes any output files, so paths must be absolute (its
|
||||
// cwd is not the user's).
|
||||
switch {
|
||||
case format == "mermaid" && exportOutDir != "":
|
||||
abs, err := filepath.Abs(exportOutDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolve out-dir: %w", err)
|
||||
}
|
||||
toolArgs["output_dir"] = abs
|
||||
if _, err := requireDaemonTool(repoPath, "export_graph", toolArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), "[gortex export] daemon wrote mermaid files under %s\n", abs)
|
||||
return nil
|
||||
|
||||
case exportOut != "":
|
||||
abs, err := filepath.Abs(exportOut)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolve output path: %w", err)
|
||||
}
|
||||
toolArgs["output_path"] = abs
|
||||
if _, err := requireDaemonTool(repoPath, "export_graph", toolArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), "[gortex export] daemon wrote the export to %s\n", abs)
|
||||
printLoadInstructions(format, exportOut)
|
||||
return nil
|
||||
|
||||
default:
|
||||
out, err := requireDaemonTool(repoPath, "export_graph", toolArgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = cmd.OutOrStdout().Write(out)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func printLoadInstructions(format, path string) {
|
||||
w := os.Stderr
|
||||
switch format {
|
||||
case "cypher":
|
||||
fmt.Fprintf(w, "\n[gortex export] To load into Memgraph (recommended for ad-hoc exploration):\n")
|
||||
fmt.Fprintf(w, " docker run -p 7687:7687 -p 3000:3000 memgraph/memgraph-platform\n")
|
||||
fmt.Fprintf(w, " # then in Memgraph Lab (http://localhost:3000) → Datasets → Import\n")
|
||||
fmt.Fprintf(w, " # OR via mgconsole: cat %s | mgconsole\n", path)
|
||||
fmt.Fprintf(w, " # First, create an id index for fast edge MATCHes:\n")
|
||||
fmt.Fprintf(w, " # CREATE INDEX ON :GortexNode(id);\n")
|
||||
fmt.Fprintf(w, "\n[gortex export] To load into Neo4j:\n")
|
||||
fmt.Fprintf(w, " cypher-shell -u neo4j -p <pw> -f %s\n", path)
|
||||
fmt.Fprintf(w, " # First, create the index:\n")
|
||||
fmt.Fprintf(w, " # CREATE INDEX FOR (n:GortexNode) ON (n.id);\n")
|
||||
fmt.Fprintf(w, "\n[gortex export] To wipe a previous export before re-loading:\n")
|
||||
fmt.Fprintf(w, " MATCH (n:GortexNode) DETACH DELETE n;\n")
|
||||
case "graphml":
|
||||
fmt.Fprintf(w, "\n[gortex export] Open %s in:\n", path)
|
||||
fmt.Fprintf(w, " Gephi: File → Open\n")
|
||||
fmt.Fprintf(w, " yEd: File → Open\n")
|
||||
fmt.Fprintf(w, " Cytoscape: File → Import → Network from File\n")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user