mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	feat(ui): show link to download directory (#4736)
This adds links to download a directory as archive. This can be useful if you e.g. just want to download a assets directory instead of the full source tree. The logic already exists in the backend, so only the frontend had been changed.  Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4736 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: JakobDev <jakobdev@gmx.de> Co-committed-by: JakobDev <jakobdev@gmx.de>
This commit is contained in:
		
					parent
					
						
							
								ec35eb2506
							
						
					
				
			
			
				commit
				
					
						3c68399eb0
					
				
			
		
					 2 changed files with 62 additions and 0 deletions
				
			
		|  | @ -144,6 +144,17 @@ | |||
| 					<a class="ui button" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}"> | ||||
| 						{{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}} | ||||
| 					</a> | ||||
| 					{{if not $.DisableDownloadSourceArchives}} | ||||
| 						<div class="clone-panel ui action tiny input"> | ||||
| 							<button class="ui small jump dropdown icon button" data-tooltip-content="{{ctx.Locale.Tr "repo.more_operations"}}"> | ||||
| 								{{svg "octicon-kebab-horizontal"}} | ||||
| 								<div class="menu"> | ||||
| 									<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments (printf "%s:%s" $.RefName .TreePath)}}.zip" rel="nofollow">{{svg "octicon-file-zip" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.download_zip"}}</a> | ||||
| 									<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments (printf "%s:%s" $.RefName .TreePath)}}.tar.gz" rel="nofollow">{{svg "octicon-file-zip" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.download_tar"}}</a> | ||||
| 								</div> | ||||
| 							</button> | ||||
| 						</div> | ||||
| 					{{end}} | ||||
| 				{{end}} | ||||
| 			</div> | ||||
| 		</div> | ||||
|  |  | |||
|  | @ -4,10 +4,17 @@ | |||
| package integration | ||||
| 
 | ||||
| import ( | ||||
| 	"archive/tar" | ||||
| 	"compress/gzip" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/test" | ||||
| 	"code.gitea.io/gitea/routers" | ||||
|  | @ -32,3 +39,47 @@ func TestRepoDownloadArchive(t *testing.T) { | |||
| 	assert.Empty(t, resp.Header().Get("Content-Encoding")) | ||||
| 	assert.Len(t, bs, 320) | ||||
| } | ||||
| 
 | ||||
| func TestRepoDownloadArchiveSubdir(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		defer test.MockVariableValue(&setting.EnableGzip, true)() | ||||
| 		defer test.MockVariableValue(&web.GzipMinSize, 10)() | ||||
| 		defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() | ||||
| 
 | ||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | ||||
| 
 | ||||
| 		// Create a subdirectory | ||||
| 		err := createOrReplaceFileInBranch(user, repo, "subdir/test.txt", "master", "Test") | ||||
| 		require.NoError(t, err) | ||||
| 
 | ||||
| 		t.Run("Frontend", func(t *testing.T) { | ||||
| 			resp := MakeRequest(t, NewRequestf(t, "GET", "/%s/src/branch/master/subdir", repo.FullName()), http.StatusOK) | ||||
| 
 | ||||
| 			assert.Contains(t, resp.Body.String(), fmt.Sprintf("/%s/archive/master:subdir.zip", repo.FullName())) | ||||
| 			assert.Contains(t, resp.Body.String(), fmt.Sprintf("/%s/archive/master:subdir.tar.gz", repo.FullName())) | ||||
| 		}) | ||||
| 
 | ||||
| 		t.Run("Backend", func(t *testing.T) { | ||||
| 			resp := MakeRequest(t, NewRequestf(t, "GET", "/%s/archive/master:subdir.tar.gz", repo.FullName()), http.StatusOK) | ||||
| 
 | ||||
| 			uncompressedStream, err := gzip.NewReader(resp.Body) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 			tarReader := tar.NewReader(uncompressedStream) | ||||
| 
 | ||||
| 			header, err := tarReader.Next() | ||||
| 			require.NoError(t, err) | ||||
| 			assert.Equal(t, tar.TypeDir, int32(header.Typeflag)) | ||||
| 			assert.Equal(t, fmt.Sprintf("%s/", repo.Name), header.Name) | ||||
| 
 | ||||
| 			header, err = tarReader.Next() | ||||
| 			require.NoError(t, err) | ||||
| 			assert.Equal(t, tar.TypeReg, int32(header.Typeflag)) | ||||
| 			assert.Equal(t, fmt.Sprintf("%s/test.txt", repo.Name), header.Name) | ||||
| 
 | ||||
| 			_, err = tarReader.Next() | ||||
| 			assert.Equal(t, io.EOF, err) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue