Programmatic SDK
Overview
Section titled “Overview”The pkg/artdupl package provides a programmatic API with:
Detectorinterface withFindClones(),FindClonesStreamResult(), andClose()Optionsbuilder for full configuration- Progress callbacks for UI integration
- 20+ typed sentinel errors
- Injectable file reader for testing/custom sources
The SDK has zero imports of config/ or errors/ — it uses fully independent types aliased from domain.
Installation
Section titled “Installation”go get github.com/LarsArtmann/art-dupl/pkg/artduplBasic Usage
Section titled “Basic Usage”package main
import ( "context" "fmt" "log"
"github.com/LarsArtmann/art-dupl/pkg/artdupl")
func main() { detector, err := artdupl.New(artdupl.Options{ Threshold: 10, Paths: []string{"./src"}, }) if err != nil { log.Fatal(err) } defer detector.Close()
result, err := detector.FindClones(context.Background()) if err != nil { log.Fatal(err) }
fmt.Printf("Found %d clone groups\n", len(result.CloneGroups)) for _, group := range result.CloneGroups { fmt.Printf(" %d tokens, %d occurrences\n", group.Tokens, len(group.Clones)) }}Streaming Results
Section titled “Streaming Results”detector, _ := artdupl.New(opts)defer detector.Close()
ch, err := detector.FindClonesStreamResult(ctx)if err != nil { log.Fatal(err)}
for result := range ch { if result.Err != nil { log.Print(result.Err) continue } fmt.Printf("Clone: %d tokens\n", result.CloneGroup.Tokens)}Progress Callbacks
Section titled “Progress Callbacks”detector, _ := artdupl.New(artdupl.Options{ Threshold: 10, Paths: []string{"./src"}, OnProgress: func(stage string, completed, total int, currentFile string) { pct := float64(completed) / float64(total) * 100 fmt.Printf("\r%s: %d/%d (%.0f%%) %s", stage, completed, total, pct, currentFile) },})Custom File Reader
Section titled “Custom File Reader”detector, _ := artdupl.New(artdupl.Options{ Threshold: 10, FileReader: func(path string) ([]byte, error) { // Custom file reading logic (e.g., from a VFS, database, etc.) return myCustomRead(path) },})Validation
Section titled “Validation”if err := artdupl.ValidateOptions(opts); err != nil { // Handle validation errors}
// Check individual clone validityfor _, group := range result.CloneGroups { for _, clone := range group.Clones { if !clone.IsValid() { // Invalid clone } }}Error Handling
Section titled “Error Handling”The SDK provides typed sentinel errors:
result, err := detector.FindClones(ctx)switch {case errors.Is(err, artdupl.ErrInvalidThreshold): // Threshold out of rangecase errors.Is(err, artdupl.ErrThresholdTooLarge): // Threshold exceeds file token countcase err != nil: // Other errors}API Reference
Section titled “API Reference”Full API documentation: pkg.go.dev/github.com/LarsArtmann/art-dupl/pkg/artdupl