embedded task and status in build struct

This commit is contained in:
Brad Rydzewski 2015-04-16 14:45:05 -07:00
parent 110af2a196
commit 5f35f46c24
11 changed files with 104 additions and 269 deletions

View file

@ -79,15 +79,8 @@ func main() {
repo.GET("/builds", server.GetBuilds)
repo.GET("/builds/:number", server.GetBuild)
//TODO repo.POST("/builds/:number", server.RestartBuild)
//TODO repo.DELETE("/builds/:number", server.CancelBuild)
repo.GET("/builds/:number/tasks", server.GetTasks)
repo.GET("/builds/:number/tasks/:task", server.GetTask)
repo.GET("/builds/:number/tasks/:task/log", server.GetTaskLogs)
// repo.GET("/status/:number/status/:context", server.GetStatus)
repo.GET("/status/:number", server.GetStatusList)
repo.POST("/status/:number", server.PostStatus)
repo.GET("/logs/:number/:task", server.GetBuildLogs)
repo.POST("/status/:number", server.PostBuildStatus)
}
}

View file

@ -1,9 +1,12 @@
package server
import (
"io"
"strconv"
"github.com/drone/drone/common"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
// GetBuild accepts a request to retrieve a build
@ -28,7 +31,7 @@ func GetBuild(c *gin.Context) {
}
}
// GetBuild accepts a request to retrieve a list
// GetBuilds accepts a request to retrieve a list
// of builds from the datastore for the given repository.
//
// GET /api/builds/:owner/:name
@ -43,3 +46,52 @@ func GetBuilds(c *gin.Context) {
c.JSON(200, builds)
}
}
// GetBuildLogs accepts a request to retrieve logs from the
// datastore for the given repository, build and task
// number.
//
// GET /api/repos/:owner/:name/logs/:number/:task
//
func GetBuildLogs(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
full, _ := strconv.ParseBool(c.Params.ByName("full"))
build, _ := strconv.Atoi(c.Params.ByName("number"))
task, _ := strconv.Atoi(c.Params.ByName("task"))
r, err := store.LogReader(repo.FullName, build, task)
if err != nil {
c.Fail(404, err)
} else if full {
io.Copy(c.Writer, r)
} else {
io.Copy(c.Writer, io.LimitReader(r, 2000000))
}
}
// PostBuildStatus accepts a request to create a new build
// status. The created user status is returned in JSON
// format if successful.
//
// POST /api/repos/:owner/:name/status/:number
//
func PostBuildStatus(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
num, err := strconv.Atoi(c.Params.ByName("number"))
if err != nil {
c.Fail(400, err)
return
}
in := &common.Status{}
if !c.BindWith(in, binding.JSON) {
c.AbortWithStatus(400)
return
}
if err := store.SetStatus(repo.Name, num, in); err != nil {
c.Fail(400, err)
} else {
c.JSON(201, in)
}
}

View file

@ -234,6 +234,42 @@ func PostRepo(c *gin.Context) {
c.JSON(200, r)
}
// Unubscribe accapets a request to unsubscribe the
// currently authenticated user to the repository.
//
// DEL /api/subscribers/:owner/:name
//
func Unsubscribe(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
user := ToUser(c)
err := store.DelSubscriber(user.Login, repo.FullName)
if err != nil {
c.Fail(400, err)
} else {
c.Writer.WriteHeader(200)
}
}
// Subscribe accapets a request to subscribe the
// currently authenticated user to the repository.
//
// POST /api/subscriber/:owner/:name
//
func Subscribe(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
user := ToUser(c)
err := store.SetSubscriber(user.Login, repo.FullName)
if err != nil {
c.Fail(400, err)
} else {
c.JSON(200, &common.Subscriber{Subscribed: true})
}
}
// perms is a helper function that returns user permissions
// for a particular repository.
func perms(remote remote.Remote, u *common.User, r *common.Repo) *common.Perm {

View file

@ -27,7 +27,6 @@
<script src="/static/scripts/services/repos.js"></script>
<script src="/static/scripts/services/builds.js"></script>
<script src="/static/scripts/services/tasks.js"></script>
<script src="/static/scripts/services/users.js"></script>
<script src="/static/scripts/services/logs.js"></script>
<script src="/static/scripts/services/tokens.js"></script>
@ -37,4 +36,4 @@
<script src="/static/scripts/filters/time.js"></script>
</body>
</html>
</html>

View file

@ -3,18 +3,18 @@
/**
* BuildsCtrl responsible for rendering the repo's
* recent build history.
*/
*/
function BuildsCtrl($scope, $routeParams, builds, repos, users) {
var owner = $routeParams.owner;
var name = $routeParams.name;
var fullName = owner+'/'+name;
// Gets the currently authenticated user
// Gets the currently authenticated user
users.getCached().then(function(payload){
$scope.user = payload.data;
});
// Gets a repository
repos.get(fullName).then(function(payload){
$scope.repo = payload.data;
@ -44,8 +44,8 @@
/**
* BuildCtrl responsible for rendering a build.
*/
function BuildCtrl($scope, $routeParams, logs, tasks, builds, repos, users) {
*/
function BuildCtrl($scope, $routeParams, logs, builds, repos, users) {
var step = parseInt($routeParams.step) || 1;
var number = $routeParams.number;
@ -53,11 +53,11 @@
var name = $routeParams.name;
var fullName = owner+'/'+name;
// Gets the currently authenticated user
// Gets the currently authenticated user
users.getCached().then(function(payload){
$scope.user = payload.data;
});
// Gets a repository
repos.get(fullName).then(function(payload){
$scope.repo = payload.data;
@ -68,23 +68,12 @@
// Gets the build
builds.get(fullName, number).then(function(payload){
$scope.build = payload.data;
$scope.task = payload.data.tasks[step];
}).catch(function(err){
$scope.error = err;
});
// Gets a list of build steps
tasks.list(fullName, number).then(function(payload){
$scope.tasks = payload.data || [];
$scope.tasks.forEach(function(task) {
if (task.number === step) {
$scope.task = task;
}
});
}).catch(function(err){
$scope.error = err;
});
if (step) {
if (step) { // TODO only if build is step.state == 'running'
// Gets a list of build steps
logs.get(fullName, number, step).then(function(payload){
$scope.logs = payload.data;
@ -98,4 +87,4 @@
.module('drone')
.controller('BuildCtrl', BuildCtrl)
.controller('BuildsCtrl', BuildsCtrl);
})();
})();

View file

@ -16,7 +16,7 @@
* @param {number} Number of the task.
*/
this.get = function(repoName, number, step) {
return $http.get('/api/repos/'+repoName+'/builds/'+number+'/tasks/'+step+'/log');
return $http.get('/api/repos/'+repoName+'/logs/'+number+'/'+step);
};
}

View file

@ -1,47 +0,0 @@
'use strict';
(function () {
/**
* The TaskService provides access to build
* task data using REST API calls.
*/
function TaskService($http, $window) {
/**
* Gets a list of builds.
*
* @param {string} Name of the repository.
* @param {number} Number of the build.
*/
this.list = function(repoName, number) {
return $http.get('/api/repos/'+repoName+'/builds/'+number+'/tasks');
};
/**
* Gets a task.
*
* @param {string} Name of the repository.
* @param {number} Number of the build.
* @param {number} Number of the task.
*/
this.get = function(repoName, number, step) {
return $http.get('/api/repos/'+repoName+'/builds/'+number+'/tasks/'+step);
};
/**
* Gets a task.
*
* @param {string} Name of the repository.
* @param {number} Number of the build.
* @param {number} Number of the task.
*/
this.get = function(repoName, number, step) {
return $http.get('/api/repos/'+repoName+'/builds/'+number+'/tasks/'+step);
};
}
angular
.module('drone')
.service('tasks', TaskService);
})();

View file

@ -67,7 +67,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="task in tasks">
<tr ng-repeat="task in build.tasks">
<td><a ng-href="{{ repo.full_name }}/{{ build.number }}/{{ task.number }}">{{ task.number }}</a></td>
<td>{{ task.state }}</td>
<td>{{ task.started_at | fromNow }}</td>

View file

@ -1,75 +0,0 @@
package server
import (
"strconv"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/drone/drone/common"
)
// GetStatus accepts a request to retrieve a build status
// from the datastore for the given repository and
// build number.
//
// GET /api/status/:owner/:name/:number/:context
//
func GetStatus(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
num, _ := strconv.Atoi(c.Params.ByName("number"))
ctx := c.Params.ByName("context")
status, err := store.Status(repo.FullName, num, ctx)
if err != nil {
c.Fail(404, err)
} else {
c.JSON(200, status)
}
}
// PostStatus accepts a request to create a new build
// status. The created user status is returned in JSON
// format if successful.
//
// POST /api/status/:owner/:name/:number
//
func PostStatus(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
num, err := strconv.Atoi(c.Params.ByName("number"))
if err != nil {
c.Fail(400, err)
return
}
in := &common.Status{}
if !c.BindWith(in, binding.JSON) {
c.AbortWithStatus(400)
return
}
if err := store.SetStatus(repo.Name, num, in); err != nil {
c.Fail(400, err)
} else {
c.JSON(201, in)
}
}
// GetStatusList accepts a request to retrieve a list of
// all build status from the datastore for the given repository
// and build number.
//
// GET /api/status/:owner/:name/:number/:context
//
func GetStatusList(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
num, _ := strconv.Atoi(c.Params.ByName("number"))
list, err := store.StatusList(repo.FullName, num)
if err != nil {
c.Fail(404, err)
} else {
c.JSON(200, list)
}
}

View file

@ -1,42 +0,0 @@
package server
import (
"github.com/drone/drone/common"
"github.com/gin-gonic/gin"
)
// Unubscribe accapets a request to unsubscribe the
// currently authenticated user to the repository.
//
// DEL /api/subscribers/:owner/:name
//
func Unsubscribe(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
user := ToUser(c)
err := store.DelSubscriber(user.Login, repo.FullName)
if err != nil {
c.Fail(400, err)
} else {
c.Writer.WriteHeader(200)
}
}
// Subscribe accapets a request to subscribe the
// currently authenticated user to the repository.
//
// POST /api/subscriber/:owner/:name
//
func Subscribe(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
user := ToUser(c)
err := store.SetSubscriber(user.Login, repo.FullName)
if err != nil {
c.Fail(400, err)
} else {
c.JSON(200, &common.Subscriber{Subscribed: true})
}
}

View file

@ -1,70 +0,0 @@
package server
import (
"io"
"strconv"
"github.com/gin-gonic/gin"
)
// GetTask accepts a request to retrieve a build task
// from the datastore for the given repository and
// build number.
//
// GET /api/tasks/:owner/:name/:number/:task
//
func GetTask(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
b, _ := strconv.Atoi(c.Params.ByName("number"))
t, _ := strconv.Atoi(c.Params.ByName("task"))
task, err := store.Task(repo.FullName, b, t)
if err != nil {
c.Fail(404, err)
} else {
c.JSON(200, task)
}
}
// GetTasks accepts a request to retrieve a list of
// build tasks from the datastore for the given repository
// and build number.
//
// GET /api/tasks/:owner/:name/:number
//
func GetTasks(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
num, _ := strconv.Atoi(c.Params.ByName("number"))
tasks, err := store.TaskList(repo.FullName, num)
if err != nil {
c.Fail(404, err)
} else {
c.JSON(200, tasks)
}
}
// GetTaskLogs accepts a request to retrieve logs from the
// datastore for the given repository, build and task
// number.
//
// GET /api/logs/:owner/:name/:number/:task
//
func GetTaskLogs(c *gin.Context) {
store := ToDatastore(c)
repo := ToRepo(c)
full, _ := strconv.ParseBool(c.Params.ByName("full"))
build, _ := strconv.Atoi(c.Params.ByName("number"))
task, _ := strconv.Atoi(c.Params.ByName("task"))
r, err := store.LogReader(repo.FullName, build, task)
if err != nil {
c.Fail(404, err)
} else if full {
io.Copy(c.Writer, r)
} else {
io.Copy(c.Writer, io.LimitReader(r, 2000000))
}
}