Function bodies 75 total
resolveFlag function · go · L9-L14 (6 LOC)cmd/flags.go
func resolveFlag(flagVal, envKey string) string {
if flagVal != "" {
return flagVal
}
return os.Getenv(envKey)
}errMissing function · go · L16-L18 (3 LOC)cmd/flags.go
func errMissing(name string) error {
return fmt.Errorf("required: %s", name)
}init function · go · L36-L103 (68 LOC)cmd/root.go
func init() {
rootCmd.PersistentFlags().StringVar(&flagOrg, "org", "", "Organization slug (env: DRAPE_ORG)")
rootCmd.PersistentFlags().StringVar(&flagRepo, "repo", "", "Repository name (env: DRAPE_REPO)")
rootCmd.PersistentFlags().StringVar(&flagToken, "token", "", "API token (env: DRAPE_TOKEN)")
rootCmd.PersistentFlags().StringVar(&flagAPIURL, "api-url", "", "API base URL (env: DRAPE_API_URL, default: https://app.drape.io)")
rootCmd.PersistentFlags().BoolVar(&flagVerbose, "verbose", false, "Verbose logging")
rootCmd.PersistentFlags().BoolVar(&flagDryRun, "dry-run", false, "Parse and validate locally, don't upload")
}
// Execute runs the root command and returns an exit code.
func Execute() int {
if err := rootCmd.Execute(); err != nil {
// Check if the error wraps an exit code
if coded, ok := err.(*ExitError); ok {
output.Error("%v", coded.Err)
return coded.Code
}
output.Error("%v", err)
if hint := enhanceCobraError(err); hint != "" {
output.Error("%s", hintExecute function · go · L46-L60 (15 LOC)cmd/root.go
func Execute() int {
if err := rootCmd.Execute(); err != nil {
// Check if the error wraps an exit code
if coded, ok := err.(*ExitError); ok {
output.Error("%v", coded.Err)
return coded.Code
}
output.Error("%v", err)
if hint := enhanceCobraError(err); hint != "" {
output.Error("%s", hint)
}
return exitcode.UsageError
}
return exitcode.Success
}enhanceCobraError function · go · L66-L81 (16 LOC)cmd/root.go
func enhanceCobraError(err error) string {
msg := err.Error()
if argsErrorRe.MatchString(msg) {
return "hint: this often happens when a flag is passed twice (e.g. --branch used twice),\n" +
" causing the second occurrence to consume the next flag's value as its argument.\n" +
" Check your command for duplicate flags."
}
if strings.Contains(msg, "unknown flag") || strings.Contains(msg, "unknown shorthand flag") {
// Extract the flag name for a better message
return "hint: run the command with --help to see available flags."
}
return ""
}Error method · go · L89-L91 (3 LOC)cmd/root.go
func (e *ExitError) Error() string {
return e.Err.Error()
}resolveRepoID function · go · L113-L126 (14 LOC)cmd/root.go
func resolveRepoID(client *api.Client, orgSlug string) (int, error) {
repoName := resolveFlag(flagRepo, "DRAPE_REPO")
if repoName == "" {
return 0, &ExitError{Code: exitcode.UsageError, Err: errMissing("--repo or DRAPE_REPO")}
}
output.Verbose("Looking up repository %q in org %q...", repoName, orgSlug)
repo, err := client.LookupRepo(orgSlug, repoName)
if err != nil {
return 0, &ExitError{Code: exitcode.UploadError, Err: err}
}
output.Verbose("Resolved repo %q to ID %d", repoName, repo.ID)
return repo.ID, nil
}Repobility — same analyzer, your code, free for public repos · /scan/
resolveOrg function · go · L128-L134 (7 LOC)cmd/root.go
func resolveOrg() (string, error) {
org := resolveFlag(flagOrg, "DRAPE_ORG")
if org == "" {
return "", &ExitError{Code: exitcode.UsageError, Err: errMissing("--org or DRAPE_ORG")}
}
return org, nil
}init function · go · L39-L53 (15 LOC)cmd/upload_coverage.go
func init() {
uploadCoverageCmd.Flags().StringVar(&flagCovFormat, "format", "", "Coverage format: cobertura, lcov, go (required)")
uploadCoverageCmd.Flags().StringVar(&flagCovPathPrefix, "path-prefix", "", "Path prefix mapping for repo structure")
uploadCoverageCmd.Flags().StringVar(&flagCovBranch, "branch", "", "Git branch (auto-detected from CI)")
uploadCoverageCmd.Flags().StringVar(&flagCovSHA, "sha", "", "Git commit SHA (auto-detected from CI)")
uploadCoverageCmd.Flags().BoolVar(&flagCovWait, "wait", true, "Wait for server-side processing")
uploadCoverageCmd.Flags().IntVar(&flagCovTimeout, "timeout", 120, "Max wait time in seconds")
uploadCoverageCmd.Flags().StringVar(&flagCovTargetBranch, "target-branch", "", "Target branch for PR diff (auto-detected from CI)")
uploadCoverageCmd.Flags().StringVar(&flagCovRunDate, "run-date", "", "ISO 8601 date for historical uploads (e.g. 2026-03-15)")
uploadCoverageCmd.Flags().StringSliceVar(&flagCovGroups, "group", nil, "Group label(s) runUploadCoverage function · go · L55-L170 (116 LOC)cmd/upload_coverage.go
func runUploadCoverage(cmd *cobra.Command, args []string) error {
filePath := filepath.Clean(args[0])
// Read file
data, err := os.ReadFile(filePath) //nolint:gosec // G304: path is from CLI args, cleaned above
if err != nil {
return &ExitError{Code: exitcode.ParseError, Err: fmt.Errorf("reading file %s: %w", filePath, err)}
}
output.Info("Read %s (%d bytes)", filepath.Base(filePath), len(data))
// Detect CI
ci := cidetect.Detect(os.Getenv)
if ci == nil {
ci = cidetect.DetectFromGit()
}
branch := resolveGitContext(flagCovBranch, ci, func(info *cidetect.CIInfo) string { return info.Branch })
sha := resolveGitContext(flagCovSHA, ci, func(info *cidetect.CIInfo) string { return info.CommitSHA })
if branch == "" {
return &ExitError{Code: exitcode.UsageError, Err: errMissing("--branch (could not auto-detect)")}
}
if sha == "" {
return &ExitError{Code: exitcode.UsageError, Err: errMissing("--sha (could not auto-detect)")}
}
if flagDryRun {
output.Info("[dry-runprintCoverageDiff function · go · L172-L228 (57 LOC)cmd/upload_coverage.go
func printCoverageDiff(diff *api.CoverageDiffInfo, prNumber int) error {
output.Info("")
if prNumber > 0 {
output.Info("Coverage Diff (PR #%d)", prNumber)
} else {
output.Info("Coverage Diff")
}
if diff.BaseCoverageRate != nil {
output.Info(" Base: %s%%", *diff.BaseCoverageRate)
} else {
output.Info(" Base: (no baseline)")
}
if diff.CoverageDelta != nil {
output.Info(" Head: %s%% (%s%%)", diff.HeadCoverageRate, formatDelta(*diff.CoverageDelta))
} else {
output.Info(" Head: %s%%", diff.HeadCoverageRate)
}
if diff.NewCodeCoverageRate != nil {
output.Info(" New code: %s%% (%d/%d lines)", *diff.NewCodeCoverageRate, diff.NewLinesCovered, diff.NewLinesTotal)
} else if diff.NewLinesTotal > 0 {
output.Info(" New code: %d/%d lines", diff.NewLinesCovered, diff.NewLinesTotal)
}
output.Info(" Regressed: %d lines", diff.RegressedLinesCount)
if len(diff.RegressedFiles) > 0 {
output.Info("")
output.Info(" Regressed files:")
forformatDelta function · go · L230-L238 (9 LOC)cmd/upload_coverage.go
func formatDelta(delta string) string {
if len(delta) == 0 {
return delta
}
if delta[0] != '-' {
return "+" + delta
}
return delta
}formatLineRanges function · go · L240-L253 (14 LOC)cmd/upload_coverage.go
func formatLineRanges(ranges [][]int) string {
parts := make([]string, 0, len(ranges))
for _, r := range ranges {
if len(r) != 2 {
continue
}
if r[0] == r[1] {
parts = append(parts, strconv.Itoa(r[0]))
} else {
parts = append(parts, fmt.Sprintf("%d-%d", r[0], r[1]))
}
}
return strings.Join(parts, ", ")
}init function · go · L10-L12 (3 LOC)cmd/upload.go
func init() {
rootCmd.AddCommand(uploadCmd)
}init function · go · L34-L42 (9 LOC)cmd/upload_lint.go
func init() {
uploadLintCmd.Flags().StringVar(&flagLintBranch, "branch", "", "Git branch (auto-detected from CI)")
uploadLintCmd.Flags().StringVar(&flagLintSHA, "sha", "", "Git commit SHA (auto-detected from CI)")
uploadLintCmd.Flags().StringVar(&flagLintFormat, "format", "sarif", "Lint report format (default: sarif)")
uploadLintCmd.Flags().BoolVar(&flagLintWait, "wait", true, "Wait for server-side processing")
uploadLintCmd.Flags().IntVar(&flagLintTimeout, "timeout", 120, "Max wait time in seconds")
uploadCmd.AddCommand(uploadLintCmd)
}Open data scored by Repobility · https://repobility.com
runUploadLint function · go · L44-L153 (110 LOC)cmd/upload_lint.go
func runUploadLint(cmd *cobra.Command, args []string) error {
filePath := filepath.Clean(args[0])
data, err := os.ReadFile(filePath) //nolint:gosec // G304: path is from CLI args, cleaned above
if err != nil {
return &ExitError{Code: exitcode.ParseError, Err: fmt.Errorf("reading file %s: %w", filePath, err)}
}
output.Info("Read %s (%d bytes)", filepath.Base(filePath), len(data))
ci := cidetect.Detect(os.Getenv)
if ci == nil {
ci = cidetect.DetectFromGit()
}
branch := resolveGitContext(flagLintBranch, ci, func(info *cidetect.CIInfo) string { return info.Branch })
sha := resolveGitContext(flagLintSHA, ci, func(info *cidetect.CIInfo) string { return info.CommitSHA })
if branch == "" {
return &ExitError{Code: exitcode.UsageError, Err: errMissing("--branch (could not auto-detect)")}
}
if sha == "" {
return &ExitError{Code: exitcode.UsageError, Err: errMissing("--sha (could not auto-detect)")}
}
if flagDryRun {
output.Info("[dry-run] Would upload %s (format: %s,printLintDiff function · go · L155-L199 (45 LOC)cmd/upload_lint.go
func printLintDiff(diff *api.LintDiffInfo, prNumber int) error {
output.Info("")
if prNumber > 0 {
output.Info("Lint Diff (PR #%d)", prNumber)
} else {
output.Info("Lint Diff")
}
output.Info(" Base violations: %d", diff.BaseViolationCount)
output.Info(" Head violations: %d", diff.HeadViolationCount)
output.Info(" New: %d", diff.NewViolationCount)
output.Info(" Resolved: %d", diff.ResolvedViolationCount)
if diff.SuppressedViolationCount > 0 {
output.Info(" Suppressed: %d", diff.SuppressedViolationCount)
}
if len(diff.NewViolations) > 0 {
output.Info("")
output.Info(" New violations:")
for _, v := range diff.NewViolations {
output.Info(" %s:%d [%s] %s: %s", v.FilePath, v.Line, v.Severity, v.RuleID, v.Message)
}
}
if diff.Passed {
output.Info(" Result: PASSED")
if diff.SuppressedViolationCount > 0 && diff.NewViolationCount == 0 {
output.Info("")
output.Info("All %d new violation(s) are suppressed — passing CI"severityMeetsThreshold function · go · L44-L49 (6 LOC)cmd/upload_scan.go
func severityMeetsThreshold(severity, threshold string) bool {
if threshold == "any" {
return true
}
return severityRank[severity] >= severityRank[threshold]
}init function · go · L59-L72 (14 LOC)cmd/upload_scan.go
func init() {
uploadScanCmd.Flags().StringVar(&flagScanBranch, "branch", "", "Git branch (auto-detected from CI)")
uploadScanCmd.Flags().StringVar(&flagScanSHA, "sha", "", "Git commit SHA (auto-detected from CI)")
uploadScanCmd.Flags().StringVar(&flagScanFormat, "format", "sarif", "Scan report format: sarif, cyclonedx (default: sarif)")
uploadScanCmd.Flags().StringVar(&flagScanName, "scan-name", "", "Scan name (e.g. docker image name, tool name)")
uploadScanCmd.Flags().StringVar(&flagScanTag, "scan-tag", "", "Scan tag (e.g. image tag, version)")
uploadScanCmd.Flags().StringVar(&flagScanType, "scan-type", "", "Scan type: image, dependency (default: auto-detect from format)")
uploadScanCmd.Flags().BoolVar(&flagScanWait, "wait", true, "Wait for server-side processing")
uploadScanCmd.Flags().IntVar(&flagScanTimeout, "timeout", 120, "Max wait time in seconds")
uploadScanCmd.Flags().BoolVar(&flagScanFailOnVulns, "fail-on-vulnerabilities", false, "Exit non-zero if unsuppressed vulnerrunUploadScan function · go · L74-L312 (239 LOC)cmd/upload_scan.go
func runUploadScan(cmd *cobra.Command, args []string) error {
// Validate --fail-on-severity value
validSev := false
for _, s := range validSeverities {
if flagScanFailOnSeverity == s {
validSev = true
break
}
}
if !validSev {
return &ExitError{Code: exitcode.UsageError, Err: fmt.Errorf("invalid --fail-on-severity value %q, must be one of: critical, high, medium, low, any", flagScanFailOnSeverity)}
}
files, err := expandGlobs(args)
if err != nil {
return &ExitError{Code: exitcode.UsageError, Err: err}
}
if len(files) == 0 {
return &ExitError{Code: exitcode.ParseError, Err: fmt.Errorf("no files matched the given pattern(s)")}
}
output.Info("Found %d file(s) to upload", len(files))
ci := cidetect.Detect(os.Getenv)
if ci == nil {
ci = cidetect.DetectFromGit()
}
branch := resolveGitContext(flagScanBranch, ci, func(info *cidetect.CIInfo) string { return info.Branch })
sha := resolveGitContext(flagScanSHA, ci, func(info *cidetect.CIInfo) string { returnprintScanDiff function · go · L314-L374 (61 LOC)cmd/upload_scan.go
func printScanDiff(diff *api.ScanDiffInfo, prNumber int) error {
output.Info("")
if prNumber > 0 {
output.Info("Scan Diff (PR #%d)", prNumber)
} else {
output.Info("Scan Diff")
}
totalNew := diff.NewCriticalCount + diff.NewHighCount + diff.NewMediumCount + diff.NewLowCount
output.Info(" New CVEs: %d (critical: %d, high: %d, medium: %d, low: %d)",
totalNew, diff.NewCriticalCount, diff.NewHighCount, diff.NewMediumCount, diff.NewLowCount)
if diff.SuppressedCVECount > 0 {
output.Info(" Suppressed: %d", diff.SuppressedCVECount)
}
if len(diff.ResolvedCVEs) > 0 {
output.Info(" Resolved: %d", len(diff.ResolvedCVEs))
}
output.Info(" Unchanged: %d", diff.UnchangedCVECount)
if len(diff.NewCVEs) > 0 {
output.Info("")
output.Info(" New CVEs:")
for _, cve := range diff.NewCVEs {
suppressed := ""
if cve.Suppression != nil {
suppressed = fmt.Sprintf(" [suppressed: %s]", cve.Suppression.Type)
}
output.Info(" %s [%s] %s@%s (%s)%s",
cve.Cinit function · go · L40-L52 (13 LOC)cmd/upload_tests.go
func init() {
uploadTestsCmd.Flags().StringVar(&flagBranch, "branch", "", "Git branch (auto-detected from CI)")
uploadTestsCmd.Flags().StringVar(&flagSHA, "sha", "", "Git commit SHA (auto-detected from CI)")
uploadTestsCmd.Flags().StringVar(&flagFormat, "format", "", "Force format (junit, ctrf). Default: auto-detect")
uploadTestsCmd.Flags().StringVar(&flagJobName, "job-name", "", "CI job name (auto-detected from CI)")
uploadTestsCmd.Flags().IntVar(&flagPRNumber, "pr-number", 0, "PR number (auto-detected from CI)")
uploadTestsCmd.Flags().BoolVar(&flagWait, "wait", true, "Wait for server-side processing before exiting")
uploadTestsCmd.Flags().IntVar(&flagTimeout, "timeout", 120, "Max wait time in seconds for processing")
uploadTestsCmd.Flags().StringVar(&flagRunDate, "run-date", "", "ISO 8601 date for historical uploads (e.g. 2026-03-15)")
uploadTestsCmd.Flags().StringSliceVar(&flagGroups, "group", nil, "Group label(s) for this upload (can be specified multiple times)")
uploadrunUploadTests function · go · L54-L265 (212 LOC)cmd/upload_tests.go
func runUploadTests(cmd *cobra.Command, args []string) error {
// Expand glob patterns
files, err := expandGlobs(args)
if err != nil {
return &ExitError{Code: exitcode.UsageError, Err: err}
}
if len(files) == 0 {
return &ExitError{Code: exitcode.ParseError, Err: fmt.Errorf("no files matched the given pattern(s)")}
}
output.Info("Found %d file(s) to upload", len(files))
// Detect CI environment
ci := cidetect.Detect(os.Getenv)
if ci == nil {
ci = cidetect.DetectFromGit()
}
branch := resolveGitContext(flagBranch, ci, func(info *cidetect.CIInfo) string { return info.Branch })
sha := resolveGitContext(flagSHA, ci, func(info *cidetect.CIInfo) string { return info.CommitSHA })
if branch == "" {
return &ExitError{Code: exitcode.UsageError, Err: errMissing("--branch (could not auto-detect)")}
}
if sha == "" {
return &ExitError{Code: exitcode.UsageError, Err: errMissing("--sha (could not auto-detect)")}
}
if ci != nil {
output.Verbose("Detected CI: %s", ci.ProAbout: code-quality intelligence by Repobility · https://repobility.com
resolveGitContext function · go · L268-L276 (9 LOC)cmd/upload_tests.go
func resolveGitContext(flagVal string, ci *cidetect.CIInfo, getter func(*cidetect.CIInfo) string) string {
if flagVal != "" {
return flagVal
}
if ci != nil {
return getter(ci)
}
return ""
}dryRunValidate function · go · L278-L314 (37 LOC)cmd/upload_tests.go
func dryRunValidate(files []string) error {
output.Info("[dry-run] Validating files locally, no upload will be performed")
var allCases []junit.TestCase
var parseErrors int
for _, f := range files {
data, err := os.ReadFile(filepath.Clean(f)) //nolint:gosec // G304: path is from CLI args + glob expansion
if err != nil {
output.Error("Failed to read %s: %v", f, err)
parseErrors++
continue
}
cases, err := junit.Parse(data)
if err != nil {
output.Error("Failed to parse %s: %v", f, err)
parseErrors++
continue
}
summary := junit.Summarize(cases)
output.Info(" %s: %d tests (%d passed, %d failed, %d skipped, %d errors)",
filepath.Base(f), summary.Total, summary.Passed, summary.Failed, summary.Skipped, summary.Errored)
allCases = append(allCases, cases...)
}
summary := junit.Summarize(allCases)
output.Info("")
output.Info("[dry-run] Total: %d tests (%d passed, %d failed, %d skipped, %d errors)",
summary.Total, summary.Passed, summary.Faileinit function · go · L10-L12 (3 LOC)cmd/validate.go
func init() {
rootCmd.AddCommand(validateCmd)
}init function · go · L24-L26 (3 LOC)cmd/validate_tests.go
func init() {
validateCmd.AddCommand(validateTestsCmd)
}runValidateTests function · go · L28-L83 (56 LOC)cmd/validate_tests.go
func runValidateTests(cmd *cobra.Command, args []string) error {
files, err := expandGlobs(args)
if err != nil {
return &ExitError{Code: exitcode.UsageError, Err: err}
}
if len(files) == 0 {
return &ExitError{Code: exitcode.ParseError, Err: fmt.Errorf("no files matched the given pattern(s)")}
}
output.Info("Found %d file(s) to validate", len(files))
var allCases []junit.TestCase
var parseErrors int
for _, f := range files {
data, err := os.ReadFile(filepath.Clean(f)) //nolint:gosec // G304: path is from CLI args + glob expansion
if err != nil {
output.Error("Failed to read %s: %v", f, err)
parseErrors++
continue
}
cases, err := junit.Parse(data)
if err != nil {
output.Error("Failed to parse %s: %v", f, err)
parseErrors++
continue
}
summary := junit.Summarize(cases)
output.Verbose(" %s: %d tests (%d passed, %d failed, %d skipped, %d errors)",
filepath.Base(f), summary.Total, summary.Passed, summary.Failed, summary.Skipped, summaryexpandGlobs function · go · L86-L109 (24 LOC)cmd/validate_tests.go
func expandGlobs(patterns []string) ([]string, error) {
seen := make(map[string]bool)
var files []string
for _, pattern := range patterns {
matches, err := doublestar.FilepathGlob(pattern)
if err != nil {
return nil, fmt.Errorf("invalid glob pattern %q: %w", pattern, err)
}
for _, m := range matches {
abs, err := filepath.Abs(m)
if err != nil {
abs = m
}
if seen[abs] {
continue
}
seen[abs] = true
files = append(files, m)
}
}
return files, nil
}SetVersionInfo function · go · L16-L20 (5 LOC)cmd/version.go
func SetVersionInfo(version, commit, date string) {
cliVersion = version
cliCommit = commit
cliDate = date
}init function · go · L30-L32 (3 LOC)cmd/version.go
func init() {
rootCmd.AddCommand(versionCmd)
}Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
NewClient function · go · L24-L40 (17 LOC)internal/api/client.go
func NewClient(baseURL, token string) (*Client, error) {
u, err := url.Parse(baseURL)
if err != nil {
return nil, fmt.Errorf("invalid base URL %q: %w", baseURL, err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return nil, fmt.Errorf("invalid base URL scheme %q: must be http or https", u.Scheme)
}
return &Client{
BaseURL: baseURL,
Token: token,
HTTPClient: &http.Client{
Timeout: 30 * time.Second,
},
UserAgent: "drape-cli/dev",
}, nil
}LookupRepo method · go · L49-L78 (30 LOC)internal/api/client.go
func (c *Client) LookupRepo(orgSlug, repoName string) (*RepoInfo, error) {
url := fmt.Sprintf("%s/api/v1/orgs/%s/repos/?name=%s", c.BaseURL, orgSlug, repoName)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
c.setHeaders(req)
resp, err := c.doWithRetries(req)
if err != nil {
return nil, fmt.Errorf("looking up repo: %w", err)
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == http.StatusNotFound {
return nil, fmt.Errorf("repository %q not found in org %q", repoName, orgSlug)
}
if resp.StatusCode != http.StatusOK {
return nil, parseErrorResponse(resp)
}
var repos []RepoInfo
if err := json.NewDecoder(resp.Body).Decode(&repos); err != nil {
return nil, fmt.Errorf("decoding response: %w", err)
}
if len(repos) == 0 {
return nil, fmt.Errorf("repository %q not found in org %q", repoName, orgSlug)
}
return &repos[0], nil
}setHeaders method · go · L80-L83 (4 LOC)internal/api/client.go
func (c *Client) setHeaders(req *http.Request) {
req.Header.Set("Authorization", "Bearer "+c.Token)
req.Header.Set("User-Agent", c.UserAgent)
}doWithRetries method · go · L85-L113 (29 LOC)internal/api/client.go
func (c *Client) doWithRetries(req *http.Request) (*http.Response, error) {
const maxRetries = 3
var lastErr error
for attempt := range maxRetries {
if attempt > 0 {
// Exponential backoff: 1s, 2s for retries 1 and 2
delay := time.Second << (attempt - 1)
output.Verbose("Retrying request after %v (attempt %d/%d)", delay, attempt+1, maxRetries)
time.Sleep(delay)
}
resp, err := c.HTTPClient.Do(req) //nolint:gosec // G704: BaseURL is validated in NewClient
if err != nil {
lastErr = err
continue
}
// Only retry on 5xx errors
if resp.StatusCode >= 500 {
body, _ := io.ReadAll(resp.Body)
_ = resp.Body.Close()
lastErr = fmt.Errorf("server error %d: %s", resp.StatusCode, string(body))
continue
}
return resp, nil
}
return nil, fmt.Errorf("request failed after %d attempts: %w", maxRetries, lastErr)
}parseErrorResponse function · go · L122-L138 (17 LOC)internal/api/client.go
func parseErrorResponse(resp *http.Response) error {
body, _ := io.ReadAll(resp.Body)
var errResp ErrorResponse
if json.Unmarshal(body, &errResp) == nil {
msg := errResp.Error
if msg == "" {
msg = errResp.Message
}
if msg == "" {
msg = errResp.Detail
}
if msg != "" {
return fmt.Errorf("API error %d: %s", resp.StatusCode, msg)
}
}
return fmt.Errorf("API error %d: %s", resp.StatusCode, string(body))
}InitiateCoverageUpload method · go · L61-L97 (37 LOC)internal/api/coverage.go
func (c *Client) InitiateCoverageUpload(orgSlug string, repoID int, req CoverageUploadRequest) (*CoverageInitiateResponse, error) {
metadata := map[string]any{
"format": req.Format,
}
if req.PathPrefix != "" {
metadata["path_prefix"] = req.PathPrefix
}
if req.PRNumber != 0 {
metadata["pr_number"] = req.PRNumber
}
if req.PRTitle != "" {
metadata["pr_title"] = req.PRTitle
}
if req.PRURL != "" {
metadata["pr_url"] = req.PRURL
}
if req.PRAuthor != "" {
metadata["pr_author"] = req.PRAuthor
}
if req.TargetBranch != "" {
metadata["target_branch"] = req.TargetBranch
}
if req.RunDate != "" {
metadata["run_date"] = req.RunDate
}
if req.Group != "" {
metadata["group"] = req.Group
}
return c.InitiateUpload(orgSlug, repoID, UploadInitiateRequest{
UploadType: "coverage",
Branch: req.Branch,
SHA: req.SHA,
Filename: req.Filename,
Metadata: metadata,
})
}CompleteCoverageUpload method · go · L100-L102 (3 LOC)internal/api/coverage.go
func (c *Client) CompleteCoverageUpload(orgSlug string, repoID, uploadID int) error {
return c.CompleteUpload(orgSlug, repoID, uploadID)
}PollCoverageStatus method · go · L105-L120 (16 LOC)internal/api/coverage.go
func (c *Client) PollCoverageStatus(orgSlug string, repoID, uploadID int, timeout time.Duration) (*CoverageStatusResponse, error) {
raw, err := c.PollUploadStatus(orgSlug, repoID, uploadID, timeout, "Coverage")
if err != nil {
// Map to CoverageStatusResponse even on failure
if raw != nil {
return &CoverageStatusResponse{
UploadID: raw.UploadID,
Status: raw.Status,
ErrorMessage: raw.ErrorMessage,
}, err
}
return nil, err
}
return mapCoverageStatus(raw), nil
}Repobility — same analyzer, your code, free for public repos · /scan/
mapCoverageStatus function · go · L122-L155 (34 LOC)internal/api/coverage.go
func mapCoverageStatus(raw *UploadStatusResponse) *CoverageStatusResponse {
result := &CoverageStatusResponse{
UploadID: raw.UploadID,
Status: raw.Status,
ErrorMessage: raw.ErrorMessage,
}
if raw.Result != nil {
if v, ok := raw.Result["snapshot_id"]; ok {
if f, ok := v.(float64); ok {
id := int(f)
result.CoverageSnapshotID = &id
}
}
if v, ok := raw.Result["coverage_rate"]; ok {
if s, ok := v.(string); ok {
result.CoverageRate = &s
}
}
if v, ok := raw.Result["file_count"]; ok {
if f, ok := v.(float64); ok {
count := int(f)
result.FileCount = &count
}
}
if v, ok := raw.Result["coverage_diff"]; ok {
if diffMap, ok := v.(map[string]any); ok {
result.CoverageDiff = mapCoverageDiff(diffMap)
}
}
}
return result
}mapCoverageDiff function · go · L157-L218 (62 LOC)internal/api/coverage.go
func mapCoverageDiff(m map[string]any) *CoverageDiffInfo {
diff := &CoverageDiffInfo{}
if v, ok := m["passed"].(bool); ok {
diff.Passed = v
}
if v, ok := m["base_coverage_rate"].(string); ok {
diff.BaseCoverageRate = &v
}
if v, ok := m["head_coverage_rate"].(string); ok {
diff.HeadCoverageRate = v
}
if v, ok := m["coverage_delta"].(string); ok {
diff.CoverageDelta = &v
}
if v, ok := m["new_lines_total"].(float64); ok {
diff.NewLinesTotal = int(v)
}
if v, ok := m["new_lines_covered"].(float64); ok {
diff.NewLinesCovered = int(v)
}
if v, ok := m["new_code_coverage_rate"].(string); ok {
diff.NewCodeCoverageRate = &v
}
if v, ok := m["regressed_lines_count"].(float64); ok {
diff.RegressedLinesCount = int(v)
}
if files, ok := m["regressed_files"].([]any); ok {
for _, f := range files {
if fm, ok := f.(map[string]any); ok {
rf := RegressedFileInfo{}
if v, ok := fm["file_path"].(string); ok {
rf.FilePath = v
}
if v, ok := fm["regressPollLintStatus method · go · L39-L53 (15 LOC)internal/api/lint.go
func (c *Client) PollLintStatus(orgSlug string, repoID, uploadID int, timeout time.Duration) (*LintStatusResponse, error) {
raw, err := c.PollUploadStatus(orgSlug, repoID, uploadID, timeout, "Lint")
if err != nil {
if raw != nil {
return &LintStatusResponse{
UploadID: raw.UploadID,
Status: raw.Status,
ErrorMessage: raw.ErrorMessage,
}, err
}
return nil, err
}
return mapLintStatus(raw), nil
}mapLintStatus function · go · L55-L87 (33 LOC)internal/api/lint.go
func mapLintStatus(raw *UploadStatusResponse) *LintStatusResponse {
result := &LintStatusResponse{
UploadID: raw.UploadID,
Status: raw.Status,
ErrorMessage: raw.ErrorMessage,
}
if raw.Result == nil {
return result
}
if v, ok := raw.Result["snapshot_id"].(float64); ok {
id := int(v)
result.SnapshotID = &id
}
if v, ok := raw.Result["total_violations"].(float64); ok {
count := int(v)
result.TotalViolations = &count
}
if v, ok := raw.Result["error_count"].(float64); ok {
count := int(v)
result.ErrorCount = &count
}
if v, ok := raw.Result["warning_count"].(float64); ok {
count := int(v)
result.WarningCount = &count
}
if diffMap, ok := raw.Result["lint_diff"].(map[string]any); ok {
result.LintDiff = mapLintDiff(diffMap)
}
return result
}mapLintDiff function · go · L89-L142 (54 LOC)internal/api/lint.go
func mapLintDiff(m map[string]any) *LintDiffInfo {
diff := &LintDiffInfo{}
if v, ok := m["passed"].(bool); ok {
diff.Passed = v
}
if v, ok := m["base_violation_count"].(float64); ok {
diff.BaseViolationCount = int(v)
}
if v, ok := m["head_violation_count"].(float64); ok {
diff.HeadViolationCount = int(v)
}
if v, ok := m["new_violation_count"].(float64); ok {
diff.NewViolationCount = int(v)
}
if v, ok := m["resolved_violation_count"].(float64); ok {
diff.ResolvedViolationCount = int(v)
}
if v, ok := m["suppressed_violation_count"].(float64); ok {
diff.SuppressedViolationCount = int(v)
}
if violations, ok := m["new_violations"].([]any); ok {
for _, v := range violations {
if vm, ok := v.(map[string]any); ok {
lv := LintViolation{}
if s, ok := vm["rule_id"].(string); ok {
lv.RuleID = s
}
if s, ok := vm["file_path"].(string); ok {
lv.FilePath = s
}
if f, ok := vm["line"].(float64); ok {
lv.Line = int(f)
}
if s, PollScanStatus method · go · L59-L73 (15 LOC)internal/api/scan.go
func (c *Client) PollScanStatus(orgSlug string, repoID, uploadID int, timeout time.Duration) (*ScanStatusResponse, error) {
raw, err := c.PollUploadStatus(orgSlug, repoID, uploadID, timeout, "Scan")
if err != nil {
if raw != nil {
return &ScanStatusResponse{
UploadID: raw.UploadID,
Status: raw.Status,
ErrorMessage: raw.ErrorMessage,
}, err
}
return nil, err
}
return mapScanStatus(raw), nil
}mapScanStatus function · go · L75-L112 (38 LOC)internal/api/scan.go
func mapScanStatus(raw *UploadStatusResponse) *ScanStatusResponse {
result := &ScanStatusResponse{
UploadID: raw.UploadID,
Status: raw.Status,
ErrorMessage: raw.ErrorMessage,
}
if raw.Result == nil {
return result
}
if v, ok := raw.Result["scan_id"].(float64); ok {
id := int(v)
result.ScanID = &id
}
if v, ok := raw.Result["scan_name"].(string); ok {
result.ScanName = &v
}
if v, ok := raw.Result["total_vulnerabilities"].(float64); ok {
count := int(v)
result.TotalVulnerabilities = &count
}
if v, ok := raw.Result["highest_severity"].(string); ok {
result.HighestSeverity = &v
}
if v, ok := raw.Result["unsuppressed_vulnerabilities"].(float64); ok {
count := int(v)
result.UnsuppressedVulnerabilities = &count
}
if v, ok := raw.Result["unsuppressed_highest_severity"].(string); ok {
result.UnsuppressedHighestSeverity = &v
}
if diffMap, ok := raw.Result["scan_diff"].(map[string]any); ok {
result.ScanDiff = mapScanDiff(diffMap)
}
returnmapScanDiff function · go · L114-L182 (69 LOC)internal/api/scan.go
func mapScanDiff(m map[string]any) *ScanDiffInfo {
diff := &ScanDiffInfo{}
if v, ok := m["passed"].(bool); ok {
diff.Passed = v
}
if v, ok := m["new_critical_count"].(float64); ok {
diff.NewCriticalCount = int(v)
}
if v, ok := m["new_high_count"].(float64); ok {
diff.NewHighCount = int(v)
}
if v, ok := m["new_medium_count"].(float64); ok {
diff.NewMediumCount = int(v)
}
if v, ok := m["new_low_count"].(float64); ok {
diff.NewLowCount = int(v)
}
if v, ok := m["suppressed_cves_count"].(float64); ok {
diff.SuppressedCVECount = int(v)
}
if v, ok := m["unchanged_cves_count"].(float64); ok {
diff.UnchangedCVECount = int(v)
}
if cves, ok := m["new_cves"].([]any); ok {
for _, c := range cves {
if cm, ok := c.(map[string]any); ok {
diff.NewCVEs = append(diff.NewCVEs, mapScanCVE(cm))
}
}
}
if cves, ok := m["resolved_cves"].([]any); ok {
for _, c := range cves {
if cm, ok := c.(map[string]any); ok {
diff.ResolvedCVEs = append(diff.ResolvedCVOpen data scored by Repobility · https://repobility.com
mapScanCVE function · go · L184-L212 (29 LOC)internal/api/scan.go
func mapScanCVE(m map[string]any) ScanCVE {
cve := ScanCVE{}
if s, ok := m["cve_id"].(string); ok {
cve.CVEID = s
}
if s, ok := m["severity"].(string); ok {
cve.Severity = s
}
if s, ok := m["package_name"].(string); ok {
cve.PackageName = s
}
if s, ok := m["package_version"].(string); ok {
cve.PackageVersion = s
}
if s, ok := m["fix_state"].(string); ok {
cve.FixState = s
}
if sup, ok := m["suppression"].(map[string]any); ok {
s := &Suppression{}
if v, ok := sup["suppression_type"].(string); ok {
s.Type = v
}
if v, ok := sup["justification"].(string); ok {
s.Justification = v
}
cve.Suppression = s
}
return cve
}InitiateTestUpload method · go · L40-L80 (41 LOC)internal/api/tests.go
func (c *Client) InitiateTestUpload(orgSlug string, repoID int, metadata TestUploadMetadata) (*TestInitiateResponse, error) {
meta := map[string]any{}
if metadata.Format != "" {
meta["format"] = metadata.Format
}
if metadata.ProviderType != "" {
meta["provider_type"] = metadata.ProviderType
}
if metadata.ProviderRunID != "" {
meta["provider_run_id"] = metadata.ProviderRunID
}
if metadata.JobName != "" {
meta["job_name"] = metadata.JobName
}
if metadata.PRNumber != 0 {
meta["pr_number"] = metadata.PRNumber
}
if metadata.PRTitle != "" {
meta["pr_title"] = metadata.PRTitle
}
if metadata.PRURL != "" {
meta["pr_url"] = metadata.PRURL
}
if metadata.PRAuthor != "" {
meta["pr_author"] = metadata.PRAuthor
}
if metadata.RunDate != "" {
meta["run_date"] = metadata.RunDate
}
if metadata.Group != "" {
meta["group"] = metadata.Group
}
return c.InitiateUpload(orgSlug, repoID, UploadInitiateRequest{
UploadType: "test_results",
Branch: metadata.Branch,CompleteTestUpload method · go · L83-L85 (3 LOC)internal/api/tests.go
func (c *Client) CompleteTestUpload(orgSlug string, repoID, uploadID int) error {
return c.CompleteUpload(orgSlug, repoID, uploadID)
}page 1 / 2next ›