Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var EvalCmd = &cobra.Command{ Use: "eval", Short: "Evaluate a Datalog query against policy and data", Long: `Evaluate a Datalog query against policy and data. Output modes (--output): json Print the query results as a JSON array on stdout. All progress messages go to stderr, so the output can be piped to jq. table Print the results as an aligned table (default). Exit codes: 0 success, 1 policy-deny, 2 usage error, 3 runtime error.`, RunE: func(cmd *cobra.Command, args []string) error { if outputMode != outputJSON && outputMode != outputTable { return exitcode.UsageErrorf("invalid --output value %q: must be %q or %q", outputMode, outputJSON, outputTable) } if dataPath == "" && knowledgePath == "" { return exitcode.UsageErrorf("must provide either --data (JSON) or --facts/--knowledge (Graph)") } progress := func(format string, a ...any) { if quiet { return } fmt.Fprintf(cmd.ErrOrStderr(), format+"\n", a...) } policyBytes, err := os.ReadFile(policyPath) if err != nil { return fmt.Errorf("failed to read policy file: %w", err) } var dataBytes []byte if dataPath != "" { dataBytes, err = os.ReadFile(dataPath) if err != nil { return fmt.Errorf("failed to read data file: %w", err) } } e, err := engine.New() if err != nil { return fmt.Errorf("failed to initialize engine: %w", err) } if knowledgePath != "" { triples, err := knowledge.ParseGraphFile(knowledgePath) if err != nil { return fmt.Errorf("failed to parse knowledge base: %w", err) } preds := knowledge.GetPredicates(triples) if len(preds) > 0 { var decls []string for _, p := range preds { decls = append(decls, fmt.Sprintf("Decl %s(S, O).", p)) } schemaBlock := strings.Join(decls, "\n") if err := e.LoadPolicy(cmd.Context(), schemaBlock); err != nil { return fmt.Errorf("failed to inject schema declarations: %w", err) } progress("Injected %d schema declarations.", len(preds)) } facts := knowledge.TriplesToFacts(triples) if err := e.LoadFacts(cmd.Context(), facts); err != nil { return fmt.Errorf("failed to load knowledge facts: %w", err) } progress("Loaded %d knowledge facts.", len(facts)) } if err := e.LoadPolicy(cmd.Context(), string(policyBytes)); err != nil { return fmt.Errorf("failed to load policy: %w", err) } if dataPath != "" { var data any if err := json.Unmarshal(dataBytes, &data); err != nil { return fmt.Errorf("failed to parse data JSON: %w", err) } dataFacts, err := engine.Flatten("input", data) if err != nil { return fmt.Errorf("failed to flatten data: %w", err) } if err := e.LoadFacts(cmd.Context(), dataFacts); err != nil { return fmt.Errorf("failed to load data facts: %w", err) } progress("Loaded %d data facts.", len(dataFacts)) } ctx := context.Background() if explain { explanation, err := e.Explain(ctx, nil, queryString) if err != nil { return fmt.Errorf("explanation failed: %w", err) } stdout := cmd.OutOrStdout() if outputMode == outputJSON { outputBytes, err := json.MarshalIndent(explanation, "", " ") if err != nil { return fmt.Errorf("failed to format output: %w", err) } fmt.Fprintln(stdout, string(outputBytes)) } else { fmt.Fprint(stdout, explanation.String()) } return nil } results, err := e.Query(ctx, nil, queryString) if err != nil { return fmt.Errorf("query execution failed: %w", err) } stdout := cmd.OutOrStdout() switch outputMode { case outputJSON: outputBytes, err := json.MarshalIndent(results, "", " ") if err != nil { return fmt.Errorf("failed to format output: %w", err) } fmt.Fprintln(stdout, string(outputBytes)) default: if len(results) == 0 { progress("No results found.") return nil } printTable(stdout, results) } return nil }, }
Functions ¶
func AddCommands ¶
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.