Yaydoc, our automatic documentation generation and deployment project was recently introduced with the dashboard for its registered users. Introducing a dashboard to Yaydoc enabled us to include a lot of new functionalities and processes associated with users and their registered repositories.
One of the main reasons of creating a dashboard for registered users was to enable them to access and edit configurations of the repositories they registered to Yaydoc. Hence, there was a need to display all of the registered repositories to users. These repositories include the public repositories owned by the users and organizations’ repositories the user has admin access to.
The organizations and users are retrieved separately in parallel using async.js. Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. The required functionality is achieved using async.parallel() method which runs the tasks of a collection of functions in parallel, without waiting until the previous function has completed.
async.parallel({ organizations: function (callback) { github.retrieveOrganizations(user.token, function (error, organizations)) { callback(null, organizations); } }, ownedRepositories: function (callback) { Repository.getRepositoriesByOwner(user.username, function (err, repositories)) { callback(null, repositories); } }, function (err, results) { res.render(‘dashboard’, { title: ‘Dashboard’, organizations: results.organizations, ownedRepositories: results.ownedRepositories }); } });
In order to show the organizations’ registered repositories the github.retrieveOrganizations()
function is updated, retrieving registered repositories from Yaydoc’s database. To perform the operation, we use async’s waterfall method. This method runs the tasks in series, passing the result of each function to the next function in that array. This function is needed since we are retrieving the organizations first and then for each organization, we retrieve all the repositories for each organization. To access each organization asynchronously, we use the async.forEachOf()
method.
/** * Retrieve a list of organization the user has access to * Along with the organizations, also retrieve the registered repositories * @param accessToken: Access token of the user * @param callback */ exports.retrieveOrganizations = function (accessToken, callback) { async.waterfall([ function (callback) { // Retrieve organizations .... organizations.push({ id: organization.id, name: organization.login, avatar: organization.avatar_url }); return callback(null, organizations); }, function (organizations, callback) { async.forEachOf(organizations, function (value, key, callback)) { Repository.getRepositoriesByOwner(value.name, function (error, repositories) { value.repositories = repositories; update.push(value); callback() }); }, function (err) { callback(null, update); } } ], function (error, result) { callback(error, result); }); };
Showing the list of repositories, we now plan to make these repositories configurable. Some of these configurations may include deleting the repository and enabling or disabling it from the build process.
Resources
- Async utilities for node and browser – https://caolan.github.io/async/
- Github’s organization API https://developer.github.com/v3/orgs/