Skip to content

Commit

Permalink
feat: scoped issue (#666)
Browse files Browse the repository at this point in the history
* feat: scoped issue

Signed-off-by: ismael FALL <ismael.fall@epitech.eu>

* feat: unit-tests scpoed issue

Signed-off-by: ismael FALL <ismael.fall@epitech.eu>

* test(scope-issue): verify every output of scope issue are related to the target one

---------

Signed-off-by: ismael FALL <ismael.fall@epitech.eu>
  • Loading branch information
Doozers authored Sep 16, 2023
1 parent 7cb533d commit e19c7be
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 109 deletions.
8 changes: 8 additions & 0 deletions cmd/depviz/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ var (
genHideExternalDeps = genFlags.Bool("hide-external-deps", false, "hide dependencies outside of the specified targets")
genHideIsolated = genFlags.Bool("hide-isolated", false, "hide isolated tasks")
genShowClosed = genFlags.Bool("show-closed", false, "show closed tasks")
genScope = genFlags.String("scope", "", "target scope")
genScopeSize = genFlags.Int("scope-size", 1, "scope size")

fetchFlags = flag.NewFlagSet("fetch", flag.ExitOnError)
fetchGitHubToken = fetchFlags.String("github-token", "", "GitHub token")
Expand Down Expand Up @@ -371,6 +373,8 @@ func execGenGraphviz(ctx context.Context, args []string) error {
HideIsolated: *genHideIsolated,
HidePRs: *genHidePRs,
HideExternalDeps: *genHideExternalDeps,
Scope: *genScope,
ScopeSize: *genScopeSize,
}

opts := dvcore.GraphvizOpts{
Expand Down Expand Up @@ -403,6 +407,8 @@ func execGenJSON(ctx context.Context, args []string) error {
HideIsolated: *genHideIsolated,
HidePRs: *genHidePRs,
HideExternalDeps: *genHideExternalDeps,
Scope: *genScope,
ScopeSize: *genScopeSize,
Format: "json",
}

Expand All @@ -429,6 +435,8 @@ func execGenCSV(ctx context.Context, args []string) error {
HideIsolated: *genHideIsolated,
HidePRs: *genHidePRs,
HideExternalDeps: *genHideExternalDeps,
Scope: *genScope,
ScopeSize: *genScopeSize,
Format: "csv",
}

Expand Down
4 changes: 3 additions & 1 deletion go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

162 changes: 87 additions & 75 deletions pkg/dvcore/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type GenOpts struct {
HideIsolated bool
HidePRs bool
HideExternalDeps bool
Scope string
ScopeSize int
}

func Gen(h *cayley.Handle, args []string, opts GenOpts) error {
Expand All @@ -50,87 +52,97 @@ func Gen(h *cayley.Handle, args []string, opts GenOpts) error {
return fmt.Errorf("parse targets: %w", err)
}

if !opts.NoGraph { // nolint:nestif
// load tasks
filters := dvmodel.Filters{
Targets: targets,
WithClosed: opts.ShowClosed,
WithoutIsolated: opts.HideIsolated,
WithoutPRs: opts.HidePRs,
WithoutExternalDeps: opts.HideExternalDeps,
}
tasks, err := dvstore.LoadTasks(h, opts.Schema, filters, opts.Logger)
var scope multipmuri.Entity
if opts.Scope != "" {
scope, err = dvparser.ParseTarget(opts.Scope)
if err != nil {
return fmt.Errorf("load tasks: %w", err)
}
}

// graph
pertConfig := graphmanPertConfig(tasks, opts)

switch opts.Format {
case "json":
return genJSON(tasks)
case "csv":
return genCSV(tasks)
case "graphman-pert":
out, err := yaml.Marshal(pertConfig)
if err != nil {
return err
}
fmt.Println(string(out))
return nil
// TODO: fix many issues with generated dependencies
//case "dot":
// // graph from PERT config
// graph := graphman.FromPertConfig(*pertConfig)
//
// // initialize graph from config
// if !opts.NoPert {
// result := graphman.ComputePert(graph)
// shortestPath, distance := graph.FindShortestPath("Start", "Finish")
// opts.Logger.Debug("pert result", zap.Any("result", result), zap.Int64("distance", distance))
//
// for _, edge := range shortestPath {
// edge.Dst().SetColor("red")
// edge.SetColor("red")
// }
// }
//
// // graph fine tuning
// graph.GetVertex("Start").SetColor("blue")
// graph.GetVertex("Finish").SetColor("blue")
// if opts.Vertical {
// graph.Attrs["rankdir"] = "TB"
// }
// graph.Attrs["overlap"] = "false"
// graph.Attrs["pack"] = "true"
// graph.Attrs["splines"] = "true"
// graph.Attrs["sep"] = "0.1"
// // graph.Attrs["layout"] = "neato"
// // graph.Attrs["size"] = "\"11,11\""
// // graph.Attrs["start"] = "random"
// // FIXME: hightlight critical paths
// // FIXME: highlight other infos
// // FIXME: highlight target
//
// // graphviz
// s, err := viz.ToGraphviz(graph, &viz.Opts{
// CommentsInLabel: true,
// })
// if err != nil {
// return fmt.Errorf("graphviz: %w", err)
// }
//
// fmt.Println(s)
// return nil
case "quads":
return fmt.Errorf("not implemented")
default:
return fmt.Errorf("unsupported graph format: %q", opts.Format)
}
if opts.NoGraph { // nolint:nestif
return nil
}

return nil
// load tasks
filters := dvmodel.Filters{
Targets: targets,
WithClosed: opts.ShowClosed,
WithoutIsolated: opts.HideIsolated,
WithoutPRs: opts.HidePRs,
WithoutExternalDeps: opts.HideExternalDeps,
Scope: scope,
ScopeSize: opts.ScopeSize,
}
tasks, err := dvstore.LoadTasks(h, opts.Schema, filters, opts.Logger)
if err != nil {
return fmt.Errorf("load tasks: %w", err)
}

// graph
pertConfig := graphmanPertConfig(tasks, opts)

switch opts.Format {
case "json":
return genJSON(tasks)
case "csv":
return genCSV(tasks)
case "graphman-pert":
out, err := yaml.Marshal(pertConfig)
if err != nil {
return err
}
fmt.Println(string(out))
return nil
// TODO: fix many issues with generated dependencies
//case "dot":
// // graph from PERT config
// graph := graphman.FromPertConfig(*pertConfig)
//
// // initialize graph from config
// if !opts.NoPert {
// result := graphman.ComputePert(graph)
// shortestPath, distance := graph.FindShortestPath("Start", "Finish")
// opts.Logger.Debug("pert result", zap.Any("result", result), zap.Int64("distance", distance))
//
// for _, edge := range shortestPath {
// edge.Dst().SetColor("red")
// edge.SetColor("red")
// }
// }
//
// // graph fine tuning
// graph.GetVertex("Start").SetColor("blue")
// graph.GetVertex("Finish").SetColor("blue")
// if opts.Vertical {
// graph.Attrs["rankdir"] = "TB"
// }
// graph.Attrs["overlap"] = "false"
// graph.Attrs["pack"] = "true"
// graph.Attrs["splines"] = "true"
// graph.Attrs["sep"] = "0.1"
// // graph.Attrs["layout"] = "neato"
// // graph.Attrs["size"] = "\"11,11\""
// // graph.Attrs["start"] = "random"
// // FIXME: hightlight critical paths
// // FIXME: highlight other infos
// // FIXME: highlight target
//
// // graphviz
// s, err := viz.ToGraphviz(graph, &viz.Opts{
// CommentsInLabel: true,
// })
// if err != nil {
// return fmt.Errorf("graphviz: %w", err)
// }
//
// fmt.Println(s)
// return nil
case "quads":
return fmt.Errorf("not implemented")
default:
return fmt.Errorf("unsupported graph format: %q", opts.Format)
}
}

func pullBatches(targets []multipmuri.Entity, h *cayley.Handle, githubToken string, resync bool, logger *zap.Logger) []dvmodel.Batch {
Expand Down
2 changes: 2 additions & 0 deletions pkg/dvmodel/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ type Filters struct {
WithoutPRs bool
WithoutExternalDeps bool
WithFetch bool
Scope multipmuri.Entity
ScopeSize int
}
44 changes: 28 additions & 16 deletions pkg/dvstore/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,35 @@ func LoadTasks(h *cayley.Handle, schema *schema.Config, filters dvmodel.Filters,
ctx := context.TODO()

// fetch targets
paths := []*path.Path{}
if filters.TheWorld {
paths = append(paths, path.StartPath(h))
} else {
for _, target := range filters.Targets {
// FIXME: handle different target types (for now only repo)
p := path.StartPath(h, quad.IRI(target.String())).
Both().
Has(quad.IRI("rdf:type"), quad.IRI("dv:Task"))

// FIXME: reverse depends/blocks
paths = append(paths, p)
var p *path.Path
if filters.Scope == nil {
paths := []*path.Path{}
if filters.TheWorld {
paths = append(paths, path.StartPath(h))
} else {
for _, target := range filters.Targets {
// FIXME: handle different target types (for now only repo)
p := path.StartPath(h, quad.IRI(target.String())).
Both().
Has(quad.IRI("rdf:type"), quad.IRI("dv:Task"))

// FIXME: reverse depends/blocks
paths = append(paths, p)
}
}
}
p := paths[0]
for _, path := range paths[1:] {
p = p.Or(path)
p = paths[0]
for _, path := range paths[1:] {
p = p.Or(path)
}
} else {
p = path.StartPath(h, quad.IRI(filters.Scope.String())).Is(quad.IRI(filters.Scope.String()))
p = scopeIssue(p, filters.ScopeSize, []quad.IRI{
"isDependingOn",
"isBlocking",
//"IsRelatedWith",
//"IsPartOf",
//"HasPart",
})
}

// filters
Expand Down
23 changes: 12 additions & 11 deletions pkg/dvstore/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

_ "github.com/cayleygraph/quad/json"
"github.com/stretchr/testify/assert"
"moul.io/depviz/v3/pkg/dvmodel"
"moul.io/depviz/v3/pkg/dvparser"
"moul.io/depviz/v3/pkg/multipmuri"
"moul.io/depviz/v3/pkg/testutil"
Expand All @@ -18,19 +19,19 @@ func TestLoadTasks(t *testing.T) {
tests := []struct {
golden string
name string
filters LoadTasksFilters
filters dvmodel.Filters
expectedErr error
}{
{"all-depviz-test", "theworld", LoadTasksFilters{TheWorld: true}, nil},
{"all-depviz-test", "theworld-light", LoadTasksFilters{TheWorld: true, WithoutPRs: true, WithClosed: false, WithoutExternalDeps: true}, nil},
{"all-depviz-test", "theworld-with-closed", LoadTasksFilters{TheWorld: true, WithClosed: true}, nil},
{"all-depviz-test", "theworld-without-prs", LoadTasksFilters{TheWorld: true, WithoutPRs: true}, nil},
{"all-depviz-test", "theworld-without-isolated", LoadTasksFilters{TheWorld: true, WithoutIsolated: true}, nil},
{"all-depviz-test", "theworld-without-external-deps", LoadTasksFilters{TheWorld: true, WithoutExternalDeps: true}, nil},
{"all-depviz-test", "theworld-all-flags", LoadTasksFilters{TheWorld: true, WithClosed: true, WithoutPRs: true, WithoutIsolated: true, WithoutExternalDeps: true}, nil},
{"all-depviz-test", "moul-depviz-test", LoadTasksFilters{Targets: parseTargets(t, "moul/depviz-test")}, nil},
{"all-depviz-test", "moulbot-depviz-test", LoadTasksFilters{Targets: parseTargets(t, "moul-bot/depviz-test")}, nil},
{"all-depviz-test", "moul-and-moulbot-depviz-test", LoadTasksFilters{Targets: parseTargets(t, "moul/depviz-test, moul-bot/depviz-test")}, nil},
{"all-depviz-test", "theworld", dvmodel.Filters{TheWorld: true}, nil},
{"all-depviz-test", "theworld-light", dvmodel.Filters{TheWorld: true, WithoutPRs: true, WithClosed: false, WithoutExternalDeps: true}, nil},
{"all-depviz-test", "theworld-with-closed", dvmodel.Filters{TheWorld: true, WithClosed: true}, nil},
{"all-depviz-test", "theworld-without-prs", dvmodel.Filters{TheWorld: true, WithoutPRs: true}, nil},
{"all-depviz-test", "theworld-without-isolated", dvmodel.Filters{TheWorld: true, WithoutIsolated: true}, nil},
{"all-depviz-test", "theworld-without-external-deps", dvmodel.Filters{TheWorld: true, WithoutExternalDeps: true}, nil},
{"all-depviz-test", "theworld-all-flags", dvmodel.Filters{TheWorld: true, WithClosed: true, WithoutPRs: true, WithoutIsolated: true, WithoutExternalDeps: true}, nil},
{"all-depviz-test", "moul-depviz-test", dvmodel.Filters{Targets: parseTargets(t, "moul/depviz-test")}, nil},
{"all-depviz-test", "moulbot-depviz-test", dvmodel.Filters{Targets: parseTargets(t, "moul-bot/depviz-test")}, nil},
{"all-depviz-test", "moul-and-moulbot-depviz-test", dvmodel.Filters{Targets: parseTargets(t, "moul/depviz-test, moul-bot/depviz-test")}, nil},
}
alreadySeen := map[string]bool{}
for _, testptr := range tests {
Expand Down
Loading

0 comments on commit e19c7be

Please sign in to comment.