@@ -151,9 +151,10 @@ def test_install_pip_requirements_with_uv(
151151
152152
153153@pytest .mark .parametrize (
154- "env,extra_expected" ,
154+ "args, env,extra_expected" ,
155155 [
156156 pytest .param (
157+ {},
157158 {
158159 "REPOSITORY_TYPE" : "hg" ,
159160 "BASE_REPOSITORY" : "https://hg.mozilla.org/mozilla-central" ,
@@ -164,20 +165,38 @@ def test_install_pip_requirements_with_uv(
164165 {
165166 "base-repo" : "https://hg.mozilla.org/mozilla-unified" ,
166167 },
167- )
168+ id = "hg" ,
169+ ),
170+ pytest .param (
171+ {"myrepo_shallow_clone" : True },
172+ {
173+ "REPOSITORY_TYPE" : "git" ,
174+ "HEAD_REPOSITORY" : "https://github.com/test/repo.git" ,
175+ "HEAD_REV" : "abc123" ,
176+ },
177+ {"shallow-clone" : True },
178+ id = "git_with_shallow_clone" ,
179+ ),
168180 ],
169181)
170- def test_collect_vcs_options (monkeypatch , run_task_mod , env , extra_expected ):
182+ def test_collect_vcs_options (
183+ monkeypatch ,
184+ run_task_mod ,
185+ args ,
186+ env ,
187+ extra_expected ,
188+ ):
171189 name = "myrepo"
172190 checkout = "checkout"
173191
174192 monkeypatch .setattr (os , "environ" , {})
175193 for k , v in env .items ():
176194 monkeypatch .setenv (f"{ name .upper ()} _{ k .upper ()} " , v )
177195
178- args = Namespace ()
179- setattr (args , f"{ name } _checkout" , checkout )
180- setattr (args , f"{ name } _sparse_profile" , False )
196+ args .setdefault (f"{ name } _checkout" , checkout )
197+ args .setdefault (f"{ name } _shallow_clone" , False )
198+ args .setdefault (f"{ name } _sparse_profile" , False )
199+ args = Namespace (** args )
181200
182201 result = run_task_mod .collect_vcs_options (args , name , name )
183202
@@ -193,6 +212,7 @@ def test_collect_vcs_options(monkeypatch, run_task_mod, env, extra_expected):
193212 "head-ref" : env .get ("HEAD_REF" ),
194213 "head-rev" : env .get ("HEAD_REV" ),
195214 "repo-type" : env .get ("REPOSITORY_TYPE" ),
215+ "shallow-clone" : False ,
196216 "ssh-secret-name" : env .get ("SSH_SECRET_NAME" ),
197217 "sparse-profile" : False ,
198218 "store-path" : env .get ("HG_STORE_PATH" ),
@@ -333,7 +353,9 @@ def mock_git_repo():
333353 )
334354
335355 def _commit_file (message , filename ):
336- with open (os .path .join (repo , filename ), "w" ) as fout :
356+ filepath = os .path .join (repo , filename )
357+ os .makedirs (os .path .dirname (filepath ), exist_ok = True )
358+ with open (filepath , "w" ) as fout :
337359 fout .write ("test file content" )
338360 subprocess .check_call (["git" , "add" , filename ], cwd = repo_path )
339361 subprocess .check_call (["git" , "commit" , "-m" , message ], cwd = repo_path )
@@ -427,6 +449,104 @@ def test_git_checkout_with_commit(
427449 assert current_rev == mock_git_repo ["branch" ]
428450
429451
452+ def test_git_checkout_shallow (
453+ mock_stdin ,
454+ run_task_mod ,
455+ mock_git_repo ,
456+ tmp_path ,
457+ ):
458+ destination = tmp_path / "destination"
459+
460+ # Git ignores `--depth` when cloning from local directories, so use file://
461+ # protocol to force shallow clone.
462+ repo_url = f"file://{ mock_git_repo ['path' ]} "
463+ base_rev = mock_git_repo ["main" ]
464+ head_rev = mock_git_repo ["branch" ]
465+
466+ # Use shallow clone with head_ref != head_rev
467+ run_task_mod .git_checkout (
468+ destination_path = str (destination ),
469+ head_repo = repo_url ,
470+ base_repo = repo_url ,
471+ base_rev = base_rev ,
472+ head_ref = "mybranch" ,
473+ head_rev = head_rev ,
474+ ssh_key_file = None ,
475+ ssh_known_hosts_file = None ,
476+ shallow = True ,
477+ )
478+ shallow_file = destination / ".git" / "shallow"
479+ assert shallow_file .exists ()
480+
481+ # Verify we're on the correct commit
482+ final_rev = subprocess .check_output (
483+ ["git" , "rev-parse" , "HEAD" ],
484+ cwd = str (destination ),
485+ universal_newlines = True ,
486+ ).strip ()
487+ assert final_rev == mock_git_repo ["branch" ]
488+
489+ # Verify both base_rev and head_rev are available.
490+ for sha in [mock_git_repo ["main" ], mock_git_repo ["branch" ]]:
491+ result = subprocess .run (
492+ ["git" , "cat-file" , "-t" , sha ],
493+ cwd = str (destination ),
494+ capture_output = True ,
495+ text = True ,
496+ )
497+ assert result .returncode == 0 , f"Commit { sha } should be available"
498+ assert result .stdout .strip () == "commit"
499+
500+
501+ def test_git_fetch_shallow (
502+ mock_stdin ,
503+ run_task_mod ,
504+ mock_git_repo ,
505+ tmp_path ,
506+ ):
507+ destination = tmp_path / "destination"
508+
509+ # Git ignores `--depth` when cloning from local directories, so use file://
510+ # protocol to force shallow clone.
511+ repo_url = f"file://{ mock_git_repo ['path' ]} "
512+
513+ run_task_mod .run_command (
514+ b"vcs" ,
515+ [
516+ "git" ,
517+ "clone" ,
518+ "--depth=1" ,
519+ "--no-checkout" ,
520+ repo_url ,
521+ str (destination ),
522+ ],
523+ )
524+ shallow_file = destination / ".git" / "shallow"
525+ assert shallow_file .exists ()
526+
527+ # Verify base_rev doesn't exist yet
528+ base_rev = mock_git_repo ["branch" ]
529+ result = subprocess .run (
530+ ["git" , "cat-file" , "-t" , base_rev ],
531+ cwd = str (destination ),
532+ capture_output = True ,
533+ text = True ,
534+ )
535+ assert result .returncode != 0
536+
537+ run_task_mod .git_fetch (str (destination ), base_rev , remote = repo_url , shallow = True )
538+
539+ # Verify base_rev is now available
540+ result = subprocess .run (
541+ ["git" , "cat-file" , "-t" , base_rev ],
542+ cwd = str (destination ),
543+ capture_output = True ,
544+ text = True ,
545+ )
546+ assert result .returncode == 0
547+ assert result .stdout .strip () == "commit"
548+
549+
430550def test_display_python_version_should_output_python_versions_title (
431551 run_task_mod , capsys
432552):
0 commit comments