Skip to content

Duplicate flattening logic across artifact handlers in pkg/cli/logs_download.go #21168

@github-actions

Description

@github-actions

Overview

The latest commit (b049e6dcb91e6b00b8a251b6c74e52806e38e1cd) includes a high-churn update in pkg/cli/logs_download.go that now contains three near-identical flattening flows for different artifact roots.

This is significant structural duplication (well above 10 lines and appearing in 3 locations), and it increases the risk of inconsistent behavior when flattening logic is changed.

Critical Information

  • Pattern: Repeated directory-walk + move + cleanup workflow
  • Severity: Medium
  • Occurrences: 3
  • Locations:
    • pkg/cli/logs_download.go (flattenUnifiedArtifact, lines 155-246)
    • pkg/cli/logs_download.go (flattenActivationArtifact, lines 252-326)
    • pkg/cli/logs_download.go (flattenAgentOutputsArtifact, lines 330-405)
Duplicated Structure (Representative)
err := filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
    if err != nil {
        return err
    }
    if path == sourceDir {
        return nil
    }

    relPath, err := filepath.Rel(sourceDir, path)
    if err != nil {
        return fmt.Errorf("failed to get relative path for %s: %w", path, err)
    }

    destPath := filepath.Join(outputDir, relPath)
    if info.IsDir() {
        if err := os.MkdirAll(destPath, 0750); err != nil {
            return fmt.Errorf("failed to create directory %s: %w", destPath, err)
        }
    } else {
        if err := os.MkdirAll(filepath.Dir(destPath), 0750); err != nil {
            return fmt.Errorf("failed to create parent directory for %s: %w", destPath, err)
        }
        if err := os.Rename(path, destPath); err != nil {
            return fmt.Errorf("failed to move file %s to %s: %w", path, destPath, err)
        }
    }
    return nil
})

if err != nil {
    return fmt.Errorf("failed to flatten ...: %w", err)
}

if err := os.RemoveAll(sourceDir); err != nil {
    // warn only
}

Impact Analysis

  • Maintainability: Any behavioral fix (permissions, logging, symlink policy, error wrapping, path handling) must be repeated in 3 places.
  • Bug Risk: High chance of divergent fixes over time across artifact types.
  • Code Bloat: ~150+ lines of repeated traversal/move/cleanup code.

Refactoring Recommendations

  1. Extract shared flattener helper
  • Suggested function: flattenArtifactTree(sourceDir, outputDir, verbose, options) in pkg/cli/logs_download.go (or a nearby helper file).
  • Keep pre-processing differences in callers (e.g., old/new unified artifact source resolution).
  • Estimated effort: 1-2 hours.
  1. Parameterize post-flatten messages and error prefixes
  • Pass artifact label ("unified", "activation", "agent_outputs") to keep current user-facing text while reusing logic.
  1. Add focused tests for helper behavior
  • Cases: nested dirs, file move errors, cleanup failures (warn-only), permissions creation, relative path handling.

Implementation Checklist

  • Extract common flatten helper
  • Migrate all 3 artifact-specific functions to helper
  • Preserve existing logging and error semantics
  • Add/adjust tests for each artifact variant
  • Verify no behavior regression in logs and audit flows

Analysis Metadata

  • Analyzed Files: 581 changed non-test Go files in latest commit scope; focused semantic review on high-churn pkg/cli paths
  • Detection Method: Serena semantic analysis + structural pattern matching
  • Commit: b049e6dcb91e6b00b8a251b6c74e52806e38e1cd
  • Workflow Run: §23127574643
  • Analysis Date: 2026-03-16 UTC

References:

Generated by Duplicate Code Detector ·

Warning

⚠️ Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions