<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <link>http://code.secondbit.org/ducky/devices/</link>
    <language>en-us</language>

    <title>ducky/devices Changelog</title>
    <description>ducky/devices Changelog</description>
    <item>
    <title>[default] Add updating devices to apiv1.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/ed1b5ba69551</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/ed1b5ba69551</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>ed1b5ba69551</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td>default</td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td>tip</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Add updating devices to apiv1.<br/>
<br/>
We needed a way to be able to update devices after they were created. This is<br/>
supported in the devices package, we just needed to expose it using apiv1<br/>
endpoints.<br/>
<br/>
In doing so, it became apparent that allowing users to change the Owner of their<br/>
Devices wasn't properly thought through, and pending a reason to use it, I'm<br/>
just removing it. The biggest issue came when trying to return usable error<br/>
messages; we couldn't distinguish between &quot;you don't own the device you're<br/>
trying to update&quot; and &quot;you're not allowed to change the owner of the device&quot;. I<br/>
also couldn't figure out _who should be able to_ change the owner of the device,<br/>
which is generally an indication that I'm building a feature before I have a use<br/>
case for it.<br/>
<br/>
To support this change, the apiv1.DeviceChange type needed its Owner property<br/>
removed.<br/>
<br/>
I also needed to add deviceFromAPI and devicesFromAPI helpers to return<br/>
devices.Device types from apiv1.Device types.<br/>
<br/>
There's now a new validateDeviceUpdate helper that checks to ensure that a<br/>
device update request is valid and the user has the appropriate permissions.<br/>
<br/>
The createRequest type now accepts a slice of Devices, not a slice of<br/>
DeviceChanges, because we want to pass the Owner in.<br/>
<br/>
A new updateRequest type is created, which accepts a DeviceChange to apply.<br/>
<br/>
A new handleUpdateDevice handler is created, which is assigned to the endpoint<br/>
for PATCH requests against a device ID. It checks that the user is logged in,<br/>
the Device they're trying to update exists, and that it's a valid update. If all<br/>
of that is true, the device is updated and the updated device is returned.<br/>
<br/>
Finally, we had to add two new scopes to support new functionality:<br/>
ScopeUpdateOtherUserDevices allows a user to update other user's devices, and<br/>
ScopeUpdateLastSeen allows a user to update the LastSeen property of a device.<br/>
<br/>
Pending some better error messages, this should be a full implementation of<br/>
updating a device, which leaves only the deletion endpoint to deal with.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>apiv1/devices.go<br />apiv1/endpoints.go<br />apiv1/handlers.go<br />apiv1/scopes.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Sat, 02 Jan 2016 16:36:23 -0800</pubDate>
</item>
<item>
    <title>Update trout to fix routing bug.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/51ad0db105c8</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/51ad0db105c8</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>51ad0db105c8</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Update trout to fix routing bug.<br/>
<br/>
Update to tip on trout to fix the routing bug that was causing us such issues.<br/>
See the commit message of trout at 3df515f0cec5 for more details.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>Godeps/Godeps.json<br />vendor/code.secondbit.org/trout.hg/route.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Sat, 02 Jan 2016 16:08:43 -0800</pubDate>
</item>
<item>
    <title>Add endpoint for retrieving devices.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/b2fdf827758e</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/b2fdf827758e</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>b2fdf827758e</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Add endpoint for retrieving devices.<br/>
<br/>
Add an endpoint for retrieving devices, either as a list or by ID.<br/>
<br/>
Stub endpoints for updating and deleting devices., along with TODOs marking them<br/>
as things to still be completed. (Right now, accessing those endpoints is an<br/>
insta-panic.)<br/>
<br/>
Simplify our handleCreateDevices by returning StatusUnauthorized if AuthUser<br/>
fails, so we can reserve StatusForbidden for when auth succeeds but access is<br/>
still denied. Also, delay the instantiation and allocation of a Response<br/>
variable until we're actually going to use it.<br/>
<br/>
Create a handleGetDevices handler that authenticates the user, and if no ID is<br/>
set, returns a list of all their Devices. If one or more IDs are set, only those<br/>
Devices are returned. If ScopeViewPushToken is one of the scopes associated with<br/>
the request, the push tokens for each Device will be included in the response.<br/>
Otherwise, they will be omitted.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>apiv1/endpoints.go<br />apiv1/handlers.go<br />apiv1/scopes.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Tue, 22 Dec 2015 06:57:07 -0500</pubDate>
</item>
<item>
    <title>Fix JSON pointers in errors when creating devices.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/ad63b888f899</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/ad63b888f899</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>ad63b888f899</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Fix JSON pointers in errors when creating devices.<br/>
<br/>
Our JSON pointers used to point at the root of the document, but the properties<br/>
were actually in objects in an array keyed off of &quot;devices&quot;, so we had to update<br/>
the field property of our errors to match.<br/>
<br/>
While we were in there, we fixed the &quot;insufficient&quot; error for a Device's name to<br/>
be &quot;missing&quot; when the name is an empty string. So far, the only way for a<br/>
Device's name for it to be insufficient is _for it to be the empty string_, but<br/>
if in the future we raise the minimum length of the Device name, there will be a<br/>
distinction and I'd like the code to recognise it.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>apiv1/handlers.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Sat, 19 Dec 2015 00:30:16 -0800</pubDate>
</item>
<item>
    <title>Validate device creation.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/a700ede02f91</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/a700ede02f91</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>a700ede02f91</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Validate device creation.<br/>
<br/>
Update our uuid package to the latest, which is now based on the GitHub<br/>
fork instead of the Google Code. Also, update our api package to its latest<br/>
version, which now needs the pqarrays package as a dependency.<br/>
<br/>
We fleshed out the validateDeviceCreation. We now pass in the scopes we have<br/>
(for broad access control) and the user ID (for fine-grained access control).<br/>
This helper returns the first error it encounters, though it should probably<br/>
return a slice so we can return multiple errors all at once.<br/>
<br/>
Before we even decode the request to create a Device, let's check if the user is<br/>
even logged in. If we can't ascertain that or they're not, there's no point in<br/>
even consuming the memory necessary to read the request, because we know we're<br/>
not going to use it anyways.<br/>
<br/>
Finally actually validate the devices we're creating, and return an appropriate<br/>
error for each error we can get.<br/>
<br/>
Also, the api.CheckScopes helper function now takes the scopes passed in as a<br/>
string slice, and we have an api.GetScopes helper function to retrieve the<br/>
scopes associated with the request. Let's not keep parsing that.<br/>
<br/>
We need two new scopes to control access for device creation; ScopeImport lets<br/>
users import devices in and is pretty much admin access.<br/>
ScopeCreateOtherUserDevices allows a user to create Devices that are owned by<br/>
another user.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>Godeps/Godeps.json<br />apiv1/devices.go<br />apiv1/handlers.go<br />apiv1/scopes.go<br />devices.go<br />vendor/code.google.com/p/go-uuid/uuid/LICENSE<br />vendor/code.google.com/p/go-uuid/uuid/dce.go<br />vendor/code.google.com/p/go-uuid/uuid/doc.go<br />vendor/code.google.com/p/go-uuid/uuid/hash.go<br />vendor/code.google.com/p/go-uuid/uuid/json.go<br /><br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Sat, 19 Dec 2015 00:18:25 -0800</pubDate>
</item>
<item>
    <title>Begin implementation on apiv1.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/c24a6c5fcd8c</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/c24a6c5fcd8c</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>c24a6c5fcd8c</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Begin implementation on apiv1.<br/>
<br/>
Begin implementing the apiv1 package, which will define the first iteration of<br/>
our API endpoints and logic. Each API package should be self-contained and able<br/>
to run without depending on each other. Think of them as interfaces into<br/>
manipulating the business logic defined in the devices package. The point is to<br/>
have total control over backwards compatibility, as long as our business logic<br/>
doesn't change. If that happens, we're in a bad place, but not as bad as it<br/>
could be.<br/>
<br/>
This required us to pull in all our API tools; the api package, its<br/>
dependencies, the scopeTypes package (so we can define scopes for our API), the<br/>
trout router, etc. We also updated uuid to the latest, which now includes a<br/>
license. Hooray?<br/>
<br/>
The new apiv1 package consists of a few things:<br/>
<br/>
* The devices.go file defines the types the API will use to communicate, along<br/>
  with some helpers to convert from API types to devices types. There's also a<br/>
  stub for validating the device creation requests, which I haven't implemented<br/>
  yet because I'm a pretty bad person.<br/>
* endpoints.go just contains a helper function that builds our routes and<br/>
  assigns handlers to them, giving us an http.Handler in the returns that we can<br/>
  listen with.<br/>
* handlers.go defines our HTTP handlers, which will read requests and write<br/>
  responses, after doing the appropriate validation and executing the<br/>
  appropriating business logic. Right now, we only have a handler for creating<br/>
  devices, and it doesn't actually do any validation. Also, we have some<br/>
  user-correctable errors being returned as 500s right now, which is Bad.<br/>
  Fortunately, they're all marked with BUG, so I can at least come back to them.<br/>
* response.go defines the Response type that will be used for returning<br/>
  information after a request is executed. It may eventually get some helpers,<br/>
  but for now it's pretty basic.<br/>
* scopes.go defines the Scopes that we're going to be using in the package to<br/>
  control access. It should probably (eventually) include a helper to register<br/>
  the Scopes, or we should have a collector service that pulls in all the<br/>
  packages, finds all their Scopes, and registers them. I haven't decided how I<br/>
  want to manage Scope registration just yet.<br/>
<br/>
We exported the getStorer function (now GetStorer) so other packages can use it.<br/>
I'm not sure how I feel about this just yet. We also had to create a WithStorer<br/>
helper method that embeds the Storer into a context.Context, so we can bootstrap<br/>
in devicesd.<br/>
<br/>
We erroneously had Created in the DeviceChange struct, but there's no reason the<br/>
Created property of a Device should ever change, so it was removed from the<br/>
logic, from the struct, and from the tests.<br/>
<br/>
Our CreateMany helper was erroneously creating the un-modified Devices that were<br/>
passed in, instead of the Devices that had sensible defaults filled.<br/>
<br/>
We created a _very minimal_ (e.g., needs some work before it's ready for<br/>
production) devicesd package that will spin up a simple server, just so we could<br/>
take a peek at our apiv1 endpoints as they'd actually be used. (It worked. Yay?)<br/>
We should continue to expand on this with configuration, more information being<br/>
logged, etc.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>.hgignore<br />Godeps/Godeps.json<br />apiv1/devices.go<br />apiv1/endpoints.go<br />apiv1/handlers.go<br />apiv1/response.go<br />apiv1/scopes.go<br />context.go<br />devices.go<br />devicesd/server.go<br /><br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Mon, 14 Dec 2015 00:12:33 -0800</pubDate>
</item>
<item>
    <title>Set up DeleteDevices in Memstore.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/1ae5bae472c1</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/1ae5bae472c1</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>1ae5bae472c1</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Set up DeleteDevices in Memstore.<br/>
<br/>
Implement the DeleteDevices method for our Memstore, removing the Devices<br/>
specified by the passed IDs.<br/>
<br/>
Also, create a simple test that verifies that when Devices are deleted, only the<br/>
Devices you intend to delete are actually deleted. Further tests should be<br/>
written to verify that this extends to ListDevicesByOwner (e.g., deleted devices<br/>
will not be returned when listing them), CreateDevices (e.g., will not result in<br/>
an ErrDeviceAlreadyExists error), and UpdateDevice (e.g., will return an<br/>
ErrDeviceNotFound error after the Device is deleted).<br/>
<br/>
But for now, we're confident that it works in the simplest possible case.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>memstore.go<br />storer_test.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Sun, 29 Nov 2015 21:31:47 -0800</pubDate>
</item>
<item>
    <title>Add tests for ToSlice and ToMap.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/e3ced527d4ab</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/e3ced527d4ab</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>e3ced527d4ab</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Add tests for ToSlice and ToMap.<br/>
<br/>
Add simple unit tests that verify that ToSlice and ToMap both work as we expect.<br/>
These are probably overly-simplistic, but so are the functions we're testing.<br/>
Not sure about this... feel a bit conflicted. But let's try it.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>devices_test.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Sun, 29 Nov 2015 19:46:20 -0800</pubDate>
</item>
<item>
    <title>Add doc comments to all our exported types.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/03c49b4d3d9f</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/03c49b4d3d9f</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>03c49b4d3d9f</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Add doc comments to all our exported types.<br/>
<br/>
It makes golint happy, and it's a good thing to do. It's kind of shameful that<br/>
we went so long without them. Oops.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>devices.go<br />memstore.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Sat, 28 Nov 2015 18:26:03 -0800</pubDate>
</item>
<item>
    <title>Return ErrDeviceNotFound when updating devices.</title>
    <guid isPermaLink="true">http://code.secondbit.org/ducky/devices/rev/683050b4546b</guid>
             <link>http://code.secondbit.org/ducky/devices/rev/683050b4546b</link>
    <description>
              <![CDATA[
	<table>
	<tr>
		<th style="text-align:left;">changeset</th>
		<td>683050b4546b</td>
              </tr>
              <tr>
                              <th style="text-align:left;">branch</th>
                              <td></td>
              </tr>
              <tr>
                              <th style="text-align:left;">bookmark</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;">tag</th>
		<td></td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">user</th>
		<td>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">description</th>
		<td>Return ErrDeviceNotFound when updating devices.<br/>
<br/>
If we can't find the Device we're supposed to update, return an<br/>
ErrDeviceNotFound error.<br/>
<br/>
Write a unit test that tests for this behaviour.</td>
	</tr>
	<tr>
		<th style="text-align:left;vertical-align:top;">files</th>
		<td>memstore.go<br />storer_test.go<br /></td>
	</tr>
	</table>
	]]></description>
    <author>&#80;&#97;&#100;&#100;&#121;&#32;&#60;&#112;&#97;&#100;&#100;&#121;&#64;&#105;&#109;&#112;&#114;&#97;&#99;&#116;&#105;&#99;&#97;&#108;&#46;&#99;&#111;&#62;</author>
    <pubDate>Fri, 27 Nov 2015 11:32:15 -0800</pubDate>
</item>

  </channel>
</rss>