diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 588223c30d..bcef993011 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -812,9 +812,10 @@ func GetContentsExt(ctx *context.APIContext) { // required: true // - name: filepath // in: path - // description: path of the dir, file, symlink or submodule in the repo + // description: path of the dir, file, symlink or submodule in the repo. Swagger requires path parameter to be "required", + // you can leave it empty or pass a single dot (".") to get the root directory. // type: string - // required: false + // required: true // - name: ref // in: query // description: the name of the commit/branch/tag, default to the repository’s default branch. @@ -833,6 +834,11 @@ func GetContentsExt(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" + treePath := ctx.PathParam("*") + if treePath == "." || treePath == "/" { + treePath = "" + ctx.SetPathParam("*", treePath) + } opts := files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*")} for includeOpt := range strings.SplitSeq(ctx.FormString("includes"), ",") { if includeOpt == "" { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 62fbda5611..879f59df2e 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -7547,9 +7547,10 @@ }, { "type": "string", - "description": "path of the dir, file, symlink or submodule in the repo", + "description": "path of the dir, file, symlink or submodule in the repo. Swagger requires path parameter to be \"required\", you can leave it empty or pass a single dot (\".\") to get the root directory.", "name": "filepath", - "in": "path" + "in": "path", + "required": true }, { "type": "string", diff --git a/tests/integration/api_repo_get_contents_test.go b/tests/integration/api_repo_get_contents_test.go index d95a049b48..0bd378e9cd 100644 --- a/tests/integration/api_repo_get_contents_test.go +++ b/tests/integration/api_repo_get_contents_test.go @@ -206,11 +206,25 @@ func testAPIGetContentsExt(t *testing.T) { session := loginUser(t, "user2") token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) t.Run("DirContents", func(t *testing.T) { - req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/contents-ext/docs?ref=sub-home-md-img-check") + req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/contents-ext?ref=sub-home-md-img-check") resp := MakeRequest(t, req, http.StatusOK) var contentsResponse api.ContentsExtResponse DecodeJSON(t, resp, &contentsResponse) assert.Nil(t, contentsResponse.FileContents) + assert.NotNil(t, contentsResponse.DirContents) + + req = NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/contents-ext/.?ref=sub-home-md-img-check") + resp = MakeRequest(t, req, http.StatusOK) + contentsResponse = api.ContentsExtResponse{} + DecodeJSON(t, resp, &contentsResponse) + assert.Nil(t, contentsResponse.FileContents) + assert.NotNil(t, contentsResponse.DirContents) + + req = NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/contents-ext/docs?ref=sub-home-md-img-check") + resp = MakeRequest(t, req, http.StatusOK) + contentsResponse = api.ContentsExtResponse{} + DecodeJSON(t, resp, &contentsResponse) + assert.Nil(t, contentsResponse.FileContents) assert.Equal(t, "README.md", contentsResponse.DirContents[0].Name) assert.Nil(t, contentsResponse.DirContents[0].Encoding) assert.Nil(t, contentsResponse.DirContents[0].Content)