-
Notifications
You must be signed in to change notification settings - Fork 1
fix/incomplete-add-url #185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR restructures the git drs add-url command to directly fetch data from S3 into the local Git LFS store and introduces a new lfss3 helper package for S3 + Git LFS introspection, along with associated tests and updated coverage artifacts.
Changes:
- Replace the old
add-urlimplementation with a newCmd/runAddURLthat inspects an S3 object, streams it into the local LFS store, and writes a Git LFS pointer file in the worktree. - Add
cmd/addurl/lfss3with S3 URL parsing, LFS storage resolution, S3HeadObjectlogic, an HTTP-based fetch helper with progress reporting, and unit tests for these helpers. - Wire
addurl.Cmdintocmd/root.goand refresh coverage outputs to reflect new code and tests; remove the legacycmd/addurl/main_test.go.
Reviewed changes
Copilot reviewed 7 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| coverage/integration/coverage.out | Updated integration coverage numbers to include the new addurl/lfss3 code paths. |
| coverage/combined.out | Updated combined coverage metadata, reflecting new and removed lines in addurl, indexd client, config, logging, and other packages. |
| cmd/root.go | Switch root command to register addurl.Cmd (new command variable) instead of the removed AddURLCmd. |
| cmd/addurl/main.go | Replaces the previous Gen3/indexd-driven add-url flow with a new implementation that inspects S3 via lfss3, downloads the object into the LFS store, computes SHA256, and writes a Git LFS pointer in the worktree. |
| cmd/addurl/main_test.go | Deletes the old generatePointerFile unit test, which is no longer applicable after removing that helper. |
| cmd/addurl/lfss3/is_lfs_tracked_test.go | New tests verifying IsLFSTracked correctly interprets .gitattributes and distinguishes LFS-tracked vs non-tracked paths. |
| cmd/addurl/lfss3/inspect_test.go | New tests covering S3 URL parsing, SHA256 normalization/extraction, Git common-dir/LFS root resolution (including lfs.storage variants), and helpers for running git commands in temp repos. |
| cmd/addurl/lfss3/inspect.go | New lfss3 package logic for resolving LFS storage, parsing S3 URLs, making authenticated HeadObject calls, extracting metadata (including SHA256), and determining whether a path is LFS-tracked. |
| cmd/addurl/lfss3/agent_fetch_reader.go | New helper that converts S3/HTTP URLs to downloadable form, issues an HTTP GET, and wraps the response in a progress-reporting io.ReadCloser for use by runAddURL. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func runAddURL(cmd *cobra.Command, args []string) (err error) { | ||
| ctx := cmd.Context() | ||
| if ctx == nil { | ||
| ctx = context.Background() | ||
| } | ||
|
|
||
| s3URL := args[0] | ||
|
|
||
| // Call client.AddURL to handle Gen3 interactions | ||
| meta, err := drsClient.AddURL(s3URL, sha256, awsAccessKey, awsSecretKey, awsRegion, awsEndpoint) | ||
| if err != nil { | ||
| return err | ||
| // Determine path: use provided optional arg, otherwise derive from URL path | ||
| var pathArg string | ||
| if len(args) == 2 { | ||
| pathArg = args[1] | ||
| } else { | ||
| u, perr := url.Parse(s3URL) | ||
| if perr != nil { | ||
| return perr | ||
| } | ||
| pathArg = strings.TrimPrefix(u.Path, "/") | ||
| } | ||
|
|
||
| sha256Param, ferr := cmd.Flags().GetString("sha256") | ||
| if ferr != nil { | ||
| return fmt.Errorf("read flag sha256: %w", ferr) | ||
| } | ||
|
|
||
| awsKey, ferr := cmd.Flags().GetString(s3_utils.AWS_KEY_FLAG_NAME) | ||
| if ferr != nil { | ||
| return fmt.Errorf("read flag %s: %w", s3_utils.AWS_KEY_FLAG_NAME, ferr) | ||
| } | ||
| awsSecret, ferr := cmd.Flags().GetString(s3_utils.AWS_SECRET_FLAG_NAME) | ||
| if ferr != nil { | ||
| return fmt.Errorf("read flag %s: %w", s3_utils.AWS_SECRET_FLAG_NAME, ferr) | ||
| } | ||
| awsRegion, ferr := cmd.Flags().GetString(s3_utils.AWS_REGION_FLAG_NAME) | ||
| if ferr != nil { | ||
| return fmt.Errorf("read flag %s: %w", s3_utils.AWS_REGION_FLAG_NAME, ferr) | ||
| } | ||
| awsEndpoint, ferr := cmd.Flags().GetString(s3_utils.AWS_ENDPOINT_URL_FLAG_NAME) | ||
| if ferr != nil { | ||
| return fmt.Errorf("read flag %s: %w", s3_utils.AWS_ENDPOINT_URL_FLAG_NAME, ferr) | ||
| } | ||
|
|
||
| if awsKey == "" || awsSecret == "" { | ||
| return errors.New("AWS credentials must be provided via flags or environment variables") | ||
| } | ||
| if awsRegion == "" { | ||
| return errors.New("AWS region must be provided via flag or environment variable") | ||
| } | ||
|
|
||
| s3Input := lfss3.InspectInput{ | ||
| S3URL: s3URL, | ||
| AWSAccessKey: awsKey, | ||
| AWSSecretKey: awsSecret, | ||
| AWSRegion: awsRegion, | ||
| AWSEndpoint: awsEndpoint, | ||
| SHA256: sha256Param, | ||
| WorktreeName: pathArg, | ||
| } | ||
| info, err := lfss3.InspectS3ForLFS(ctx, s3Input) | ||
| if err != nil { | ||
| return err | ||
| } |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new runAddURL implementation only talks to S3 and the local Git LFS store and never constructs a DRS client or calls DRSClient.AddURL, so git drs add-url no longer registers the S3 URL with the configured Gen3/Anvil remote. If that behavior is still required, consider layering the new "copy into local LFS" step on top of the existing indexd/DRS registration flow rather than replacing it outright.
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 7 out of 12 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
cmd/addurl/main.go
Outdated
| isLFSTracked, err := lfss3.IsLFSTracked(pathArg) | ||
| if err != nil { | ||
| return fmt.Errorf("check LFS tracking for %s: %w", pathArg, err) | ||
| } | ||
|
|
||
| if _, err := fmt.Fprintf(cmd.OutOrStdout(), ` | ||
| Resolved Git LFS info | ||
| --------------------- | ||
| Git common dir : %s | ||
| LFS storage : %s | ||
|
|
||
| S3 object | ||
| --------- | ||
| Bucket : %s | ||
| Key : %s | ||
| Worktree name : %s | ||
| Size (bytes) : %d | ||
| SHA256 (meta) : %s | ||
| ETag : %s | ||
| Last modified : %s | ||
|
|
||
| Worktree | ||
| ------------- | ||
| path : %s | ||
| tracked by LFS : %v |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isLFSTracked is only used for printing and no longer enforces that the target path is tracked by Git LFS, whereas the previous AddURL implementation (client/indexd/add_url.go:304-316) explicitly failed when the path was not LFS-tracked. This allows git drs add-url to succeed while writing a pointer file for a path that Git LFS will never manage, which can leave consumers with a plain text pointer instead of real data and undermines the goal of avoiding incomplete LFS contracts. Consider treating a non‑LFS‑tracked path as an error (with a clear message about running git lfs track and committing .gitattributes), to preserve the earlier safety guarantees.
cmd/addurl/main.go
Outdated
| // 5) write pointer file in working tree | ||
| pointer := fmt.Sprintf( | ||
| "version https://git-lfs.github.com/spec/v1\noid sha256:%s\nsize %d\n", | ||
| oid, info.SizeBytes, | ||
| ) | ||
| // write pointer file to working tree pathArg | ||
| if pathArg == "" { | ||
| return fmt.Errorf("empty worktree path") | ||
| } | ||
| safePath := filepath.Clean(pathArg) | ||
| dir := filepath.Dir(safePath) | ||
| if dir != "." && dir != "/" { | ||
| if err := os.MkdirAll(dir, 0755); err != nil { | ||
| return fmt.Errorf("mkdir %s: %w", dir, err) | ||
| } | ||
| } | ||
| if err = os.WriteFile(safePath, []byte(pointer), 0644); err != nil { | ||
| return fmt.Errorf("write %s: %w", safePath, err) | ||
| } |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new implementation writes the Git LFS pointer file to safePath but never stages it with git add, whereas the previous generatePointerFile helper also ran git add on the created pointer. This means git drs add-url no longer ensures that the pointer is added to the index, so callers expecting the command to fully "add" the file must remember to run git add themselves, which is a behavioral regression and easy to miss in scripts. Consider either restoring the git add step (or equivalent) here or clearly changing the command’s contract and documentation to reflect that it only writes the file without staging it.
Co-authored-by: Copilot <[email protected]>
See #141