Skip to content

Commit

Permalink
fixes for dustin
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre Tardy committed Aug 11, 2013
1 parent 3d30dc1 commit 53db29e
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 20 deletions.
6 changes: 3 additions & 3 deletions master/buildbot/data/connector.py
Expand Up @@ -119,12 +119,12 @@ def control(self, action, args, path):
endpoint, kwargs = self.getEndpoint(path)
return endpoint.control(action, args, kwargs)

def asList(self):
def allEndpoints(self):
"""return the full spec of the connector as a list of dicts
"""
paths = []
for k, v in sorted(self.matcher._patterns.items()):
for k, v in sorted(self.matcher.iterPatterns()):
paths.append(dict(path="/".join(k),
type=v.rtype.entityType.name,
type_spec=v.rtype.entityType.asDict()))
type_spec=v.rtype.entityType.getSpec()))
return paths
2 changes: 1 addition & 1 deletion master/buildbot/data/root.py
Expand Up @@ -30,7 +30,7 @@ class SpecEndpoint(base.Endpoint):
pathPatterns = "/application.spec"

def get(self, resultSpec, kwargs):
return defer.succeed(self.master.data.asList())
return defer.succeed(self.master.data.allEndpoints())


class Root(base.ResourceType):
Expand Down
18 changes: 9 additions & 9 deletions master/buildbot/data/types.py
Expand Up @@ -38,7 +38,7 @@ def cmp(self, val, arg):
def validate(self, name, object):
raise NotImplementedError

def asDict(self):
def getSpec(self):
r = dict(name=self.name)
if self.doc is not None:
r["doc"] = self.doc
Expand All @@ -61,8 +61,8 @@ def validate(self, name, object):
return
for msg in self.nestedType.validate(name, object):
yield msg
def asDict(self):
r = self.nestedType.asDict()
def getSpec(self):
r = self.nestedType.getSpec()
r["can_be_null"] = True
return r

Expand Down Expand Up @@ -162,9 +162,9 @@ def validate(self, name, object):
for msg in self.of.validate("%s[%d]" % (name, idx), elt):
yield msg

def asDict(self):
def getSpec(self):
return dict(type=self.name,
of=self.of.asDict())
of=self.of.getSpec())

class SourcedProperties(Type):

Expand Down Expand Up @@ -219,11 +219,11 @@ def validate(self, name, object):
for msg in f.validate("%s[%r]" % (name, k), object[k]):
yield msg

def asDict(self):
def getSpec(self):
return dict(type=self.name,
fields=[dict(name=k,
type=v.name,
type_spec=v.asDict())
type_spec=v.getSpec())
for k, v in self.contents.items()
])

Expand Down Expand Up @@ -288,10 +288,10 @@ def validate(self, name, object):
for msg in f.validate("%s[%r]" % (name, k), object[k]):
yield msg

def asDict(self):
def getSpec(self):
return dict(type=self.name,
fields=[dict(name=k,
type=v.name,
type_spec=v.asDict())
type_spec=v.getSpec())
for k, v in self.fields.items()
])
2 changes: 1 addition & 1 deletion master/buildbot/scripts/dataspec.py
Expand Up @@ -33,6 +33,6 @@ def dataspec(config):
with open(config['out'], "w") as f:
if config['global'] is not None:
f.write("window." + config['global'] + '=')
f.write(json.dumps(data.asList(), indent=2))
f.write(json.dumps(data.allEndpoints(), indent=2))
print "written", config['out']
defer.returnValue(0)
2 changes: 1 addition & 1 deletion master/buildbot/scripts/runner.py
Expand Up @@ -687,7 +687,7 @@ class DataSpecOption(base.BasedirMixin, base.SubcommandOptions):
subcommandFunction = "buildbot.scripts.dataspec.dataspec"
optParameters = [
['out', 'o', "dataspec.json", "output to specified path"],
['global', 'g', None, "output a js script, that sets a global, for inclusion in tessuite"],
['global', 'g', None, "output a js script, that sets a global, for inclusion in testsuite"],
]
def getSynopsis(self):
return "Usage: buildbot dataspec [options]"
Expand Down
5 changes: 4 additions & 1 deletion master/buildbot/util/pathmatch.py
Expand Up @@ -68,8 +68,11 @@ def __getitem__(self, path):
else:
raise KeyError, 'No match for %r' % (path,)

def iterPatterns(self):
return self._patterns.iteritems()

def _compile(self):
self._by_length = {}
for k, v in self._patterns.iteritems():
for k, v in self.iterPatterns():
l = len(k)
self._by_length.setdefault(l, {})[k] = v
85 changes: 84 additions & 1 deletion master/docs/developer/www.rst
Expand Up @@ -193,6 +193,89 @@ A simple example:
--> {"jsonrpc": "2.0", "method": "force", "params": {"revision": "abcd", "branch": "dev"}, "id": 843}
<-- {"jsonrpc": "2.0", "result": {"buildsetid": 44}, "id": 843}
Discovering
~~~~~~~~~~~

Data API comes with a discovery endpoint which exposes all endpoints of the API in a json format so that one can write
middleware to automatically create higher level API, or generate fake data for development.
The api is available at:

.. code-block:: none
GET http://build.my.org/api/v2/application.spec
This metadata is guaranteed to be correct, as this is generated from the spec used in data's unit tests.
see :ref:`Adding-Fields-to-Resource-Types` for more details on the type system used.

The data validation type system is serialized into json in a very simple way. The API returns a list of endpoints specs:

.. code-block:: javascript
{
path: "<endpoint_path>"
type: "<endpoint_entity_type>"
type_spec: "<endpoint_entity_type_spec>"
}
Typespec encoding can have several forms:

* Entity or Dict

.. code-block:: javascript
{
..
type_spec: {
type: "<type name>"
fields: [
{
name: "<field name>"
type: "<field type name>"
type_spec: "<field type spec>"
}, // [...]
]
}
}
* List

.. code-block:: javascript
{
..
type_spec: {
type: "list"
of: {
type: "<field type name>"
type_spec: "<field type spec>"
}
}
* links
.. code-block:: javascript
{
..
type_spec: {
type: "link"
link_specs: [
"<ep1 path>",
"<ep2 path>", // [...]
]
}
* Other base types
.. code-block:: javascript
{
..
type_spec: {
type: "(string|integer|boolean|binary|identifier|jsonobject|source-properties)"
}
Message API
-----------
Expand Down Expand Up @@ -276,7 +359,7 @@ Restangular offers nice semantics around nested REST endpoints. Please see resta
BuildbotService adds serveral methods to restangular objects in order to integrate it with EventSource.
The idea is to simplifify automatic update of the $scope based on events happening on a given data endpoint
.. code-block: python
.. code-block:: coffeescript
# Following code will get initial data from 'api/v2/build/1/step/2'
# and register to events from 'sse/build/1/step/2'
Expand Down
2 changes: 1 addition & 1 deletion www/setup.py
Expand Up @@ -82,7 +82,7 @@
"grunt-html2js": "~0.1.6",
"grunt-requiregen": "~0.1.0",
"grunt-karma": "~0.6.0",
"bower": "~0.9.2"
"bower": "~1.1.0"
},
"engines": {
"node": "0.8.x",
Expand Down
4 changes: 2 additions & 2 deletions www/src/scripts/services/alertService.coffee
Expand Up @@ -16,16 +16,16 @@ angular.module('app').factory 'alert', ['$rootScope', ($rootScope) ->
return alert
]
angular.module('app').config ['$httpProvider', ($httpProvider) ->
$httpProvider.responseInterceptors.push ["alert", (alert) ->
$httpProvider.responseInterceptors.push ["alert", "$q", (alert, $q) ->
return (promise) ->
promise.then (res)->
res
, (res) ->
if res.config.url.indexOf("views") == 0 and res.status == 404
alert.error "view does not exist: " + res.config.url
else
console.log res
alert.error res.data
$q.reject res
]

]

0 comments on commit 53db29e

Please sign in to comment.