diff --git a/doc/api/repositories.md b/doc/api/repositories.md index 90fda387947..7a9f766ba1d 100644 --- a/doc/api/repositories.md +++ b/doc/api/repositories.md @@ -239,6 +239,56 @@ Parameters: ] ``` +## List repository tree + +Get a list of repository files and directories in a project. + +``` +GET /projects/:id/repository/tree +``` + +Parameters: + ++ `id` (required) - The ID of a project ++ `path` (optional) - The path inside repository. Used to get contend of subdirectories ++ `ref_name` (optional) - The name of a repository branch or tag or if not given the default branch + +```json + +[{ + "name": "assets", + "type": "tree", + "mode": "040000", + "id": "6229c43a7e16fcc7e95f923f8ddadb8281d9c6c6" +}, { + "name": "contexts", + "type": "tree", + "mode": "040000", + "id": "faf1cdf33feadc7973118ca42d35f1e62977e91f" +}, { + "name": "controllers", + "type": "tree", + "mode": "040000", + "id": "95633e8d258bf3dfba3a5268fb8440d263218d74" +}, { + "name": "Rakefile", + "type": "blob", + "mode": "100644", + "id": "35b2f05cbb4566b71b34554cf184a9d0bd9d46d6" +}, { + "name": "VERSION", + "type": "blob", + "mode": "100644", + "id": "803e4a4f3727286c3093c63870c2b6524d30ec4f" +}, { + "name": "config.ru", + "type": "blob", + "mode": "100644", + "id": "dfd2d862237323aa599be31b473d70a8a817943b" +}] + +``` + ## Raw blob content diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index dc75ca7a383..5db17b7e414 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -102,6 +102,31 @@ module API present commits, with: Entities::RepoCommit end + # Get a project repository tree + # + # Parameters: + # id (required) - The ID of a project + # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used + # Example Request: + # GET /projects/:id/repository/tree + get ":id/repository/tree" do + authorize! :download_code, user_project + + ref = params[:ref_name] || user_project.try(:default_branch) || 'master' + path = params[:path] || nil + + commit = user_project.repository.commit(ref) + tree = Tree.new(user_project.repository, commit.id, ref, path) + + trees = [] + + %w(trees blobs submodules).each do |type| + trees += tree.send(type).map { |t| { name: t.name, type: type.singularize, mode: t.mode, id: t.id } } + end + + trees + end + # Get a raw file contents # # Parameters: diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index 31176316af2..13e6627840e 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -111,6 +111,29 @@ describe API::API do end end + describe "GET /projects/:id/repository/tree" do + context "authorized user" do + before { project.team << [user2, :reporter] } + + it "should return project commits" do + get api("/projects/#{project.id}/repository/tree", user) + response.status.should == 200 + + json_response.should be_an Array + json_response.first['name'].should == 'app' + json_response.first['type'].should == 'tree' + json_response.first['mode'].should == '040000' + end + end + + context "unauthorized user" do + it "should not return project commits" do + get api("/projects/#{project.id}/repository/tree") + response.status.should == 401 + end + end + end + describe "GET /projects/:id/repository/commits/:sha/blob" do it "should get the raw file contents" do get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.md", user)