Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions lib/interface/cli/commands/repo/add.cmd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const Command = require('../../Command');
const { repository } = require('../../../../logic').api;
const addRoot = require('../root/add.cmd');

const command = new Command({
command: 'repository [fullname]',
aliases: ['repo'],
parent: addRoot,
description: 'Add a repository from git context to codefresh',
webDocs: {
category: 'Repository',
title: 'Add Repository',
weight: 10,
},
builder: (yargs) => {
yargs
.positional('fullname', {
describe: 'Full name of repo (template: "owner/repo")',
required: true,
})
.option('context', {
describe: 'Name of the git context to use, if not passed the default will be used',
alias: 'c',
})
.example('codefresh add repo codefresh-io/some-repo', 'Add repo "some-repo" of "codefresh-io" owner from default git context')
.example('codefresh add repo codefresh-io/some-repo -c bitbucket', 'Add repo "some-repo" of "codefresh-io" owner from git context "bitbucket"');
return yargs;
},
handler: async (argv) => {
let { context, fullname } = argv;

if (!fullname) {
console.log('Full repo name is not provided');
return;
}

const [owner, repoName] = fullname.split('/');
if (!owner) {
console.log('Owner name not provided!');
console.log('Please follow the repo name template: "<owner>/<repo>"');
return;
}
if (!repoName) {
console.log('Repo name not provided!');
console.log('Please follow the repo name template: "<owner>/<repo>"');
return;
}

try {
// throws on not found
const gitRepo = await repository.getAvailableGitRepo(owner, repoName, context);
console.log(`Found repository "${gitRepo.name}" at context "${context || gitRepo.provider}"`);
if (!context) {
context = gitRepo.provider;
}

// following the ui logic on duplication
try {
await repository.get(fullname, context);
const contextPrefix = `${context}-${context}`;
console.log(`Repo with such name already exists -- adding context prefix: ${contextPrefix}`);
fullname = `${contextPrefix}/${fullname}`; // aka github-github/codefresh-io/cf-api
} catch (e) {
// if response is "not found" - all is ok, else re-throw
if (!e.statusCode || e.statusCode !== 404) {
throw e;
}
}

// throws on duplicate, not found, other errors...
await repository.create(fullname, owner, repoName, context);
console.log(`Repository added: ${fullname}`);
} catch (e) {
console.log('Cannot add repository:');
console.log(` - ${e.message.replace('service', 'repo')}`);
}
},
});

module.exports = command;

48 changes: 48 additions & 0 deletions lib/interface/cli/commands/repo/delete.cmd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const Command = require('../../Command');
const { repository } = require('../../../../logic').api;
const deleteRoot = require('../root/delete.cmd');

const command = new Command({
command: 'repository [name_id]',
aliases: ['repo'],
parent: deleteRoot,
description: 'Remove repository by name_id',
webDocs: {
category: 'Repository',
title: 'Delete Repository',
description: 'Remove repository by name_id ("name_id" can be retrieved with "get" command, typically "repo_owner/repo_name")',
weight: 30,
},
builder: (yargs) => {
yargs
.positional('name_id', {
describe: 'Repository "name_id" (can be retrieved with "get" command, typically "repo_owner/repo_name")',
required: true,
})
.option('context', {
describe: 'Name of the git context to use, if not passed the default will be used',
alias: 'c',
})
.example('codefresh delete repo codefresh-io/some-repo', 'Delete codefresh repo with name_id "codefresh-io/some-repo"');
return yargs;
},
handler: async (argv) => {
const { name_id: name, context } = argv;

if (!name) {
console.log('Repository name_id not provided');
return;
}

try {
await repository.deleteRepo(name, context);
console.log(`Successfully deleted repo: ${name}`);
} catch (e) {
console.log('Failed to delete repo:');
console.log(` - ${e.message}`);
}
},
});

module.exports = command;

75 changes: 75 additions & 0 deletions lib/interface/cli/commands/repo/get.cmd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const Command = require('../../Command');
const _ = require('lodash');
const { repository } = require('../../../../logic').api;
const { specifyOutputForArray } = require('../../helpers/get');
const getRoot = require('../root/get.cmd');
const Spinner = require('ora');

const command = new Command({
command: 'repository [names..]',
aliases: ['repo'],
parent: getRoot,
description: 'You can either get codefresh repos (previously added) or any repo from your git context (using option "--available" and "--context")',
webDocs: {
category: 'Repository',
title: 'Get Repositories',
weight: 20,
},
builder: (yargs) => {
yargs
.positional('names', {
describe: 'Names for filtering repos',
})
.option('available', {
describe: 'Get all available git repos from provided or default git context',
alias: 'a',
})
.option('limit', {
describe: 'Maximum displayed repos number',
alias: 'l',
default: 25,
})
.option('context', {
describe: 'Name of the git context to use, if not passed the default will be used',
alias: 'c',
})
.example('codefresh get repo', 'Get all codefresh repos')
.example('codefresh get repo codefresh-io', 'Get codefresh repos containing "codefresh-io" in its name')
.example('codefresh get repo some-repo', 'Get codefresh repos containing "some-repo" in its name')
.example('codefresh get repo -a', 'Get all available repos from default git context')
.example('codefresh get repo -a -c bitbucket', 'Get all available repos from "bitbucket" git context');
return yargs;
},
handler: async (argv) => {
const { context, names, available, limit } = argv;

const loadRepos = available ? repository.getAllAvailableGitRepos : repository.getAll;
const contextText = context ? `git context "${context}"` : 'default user git context';
const filterProperty = available ? 'info.repo_shortcut' : 'info.serviceName';

const spinner = Spinner(`Loading ${available ? `git repos for ${contextText}` : 'codefresh'}`).start();
try {
let repos = await loadRepos(context);
spinner.succeed('Successfully loaded repos!');


if (!_.isEmpty(names)) {
repos = repos.filter((r) => {
return names.reduce((bool, name) => bool || _.get(r, filterProperty).includes(name), false);
});
}
specifyOutputForArray(argv.output, repos.slice(0, limit), argv.pretty);

const lengthDiff = repos.length - limit;
if (lengthDiff > 0) {
console.log(`... ${lengthDiff} more repos available - pass greater --limit option to show more`);
}
} catch (e) {
spinner.fail('Failed to load repositories:');
console.log(` - ${e.message}`);
}
},
});

module.exports = command;

18 changes: 18 additions & 0 deletions lib/interface/cli/commands/root/add.cmd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const Command = require('../../Command');

const add = new Command({
root: true,
command: 'add',
description: 'Add a resource',
usage: 'codefresh add --help',
webDocs: {
title: 'Add',
weight: 70,
},
builder: (yargs) => {
return yargs
.demandCommand(1, 'You need at least one command before moving on');
},
});

module.exports = add;
2 changes: 2 additions & 0 deletions lib/logic/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const team = require('./team');
const board = require('./board');
const section = require('./section');
const cluster = require('./cluster');
const repository = require('./repository');

module.exports = {
user,
Expand All @@ -32,4 +33,5 @@ module.exports = {
board,
section,
cluster,
repository,
};
106 changes: 106 additions & 0 deletions lib/logic/api/repository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
const { sendHttpRequest } = require('./helper');
const GitRepo = require('../entities/GitRepo');
const CodefreshRepo = require('../entities/CodefreshRepo');

/**
* codefresh repo (aka "service")
* */
const get = async (name, context) => {
const userOptions = {
url: `/api/services/${encodeURIComponent(name)}`,
method: 'get',
qs: { context },
};

return sendHttpRequest(userOptions);
};

/**
* codefresh repo (aka "service")
* */
const deleteRepo = async (name, context) => {
const userOptions = {
url: `/api/services/${encodeURIComponent(name)}`,
method: 'delete',
qs: { context },
};
return sendHttpRequest(userOptions);
};

/**
* codefresh repo (aka "service")
* */
const getAll = async (context) => {
const userOptions = {
url: '/api/repos/existing',
method: 'get',
qs: { context, thin: '' },
};

const response = await sendHttpRequest(userOptions);
return response.map(CodefreshRepo.fromResponse);
};

/**
* codefresh repo (aka "service")
* */
const create = async (name, owner, repo, context) => {
const body = {
serviceDetails: {
name,
scm: {
name: repo,
owner: {
name: owner,
},
},
},
};
const userOptions = {
url: '/api/services/',
method: 'post',
qs: { context },
body,
};

return sendHttpRequest(userOptions);
};

/**
* get available repo from git provider (github, bitbucket...)
*
* @throws if repo does not exist or user does not have the right permissions or if the context is not configured
* */
const getAvailableGitRepo = async (owner, repo, context) => {
const userOptions = {
url: `/api/repos/${owner}/${repo}`,
method: 'get',
qs: { context },
};

return sendHttpRequest(userOptions);
};

/**
* get all available repos from git provider (github, bitbucket...)
* */
const getAllAvailableGitRepos = async (context) => {
const userOptions = {
url: '/api/repos',
method: 'get',
qs: { context },
};

const response = await sendHttpRequest(userOptions);
return response.map(GitRepo.fromResponse);
};


module.exports = {
create,
getAvailableGitRepo,
get,
getAll,
getAllAvailableGitRepos,
deleteRepo,
};
22 changes: 22 additions & 0 deletions lib/logic/entities/CodefreshRepo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const Entity = require('./Entity');

class CodefreshRepo extends Entity {
constructor(data) {
super();
this.entityType = 'codefresh-repo';
this.info = data;
this.defaultColumns = ['git_context', 'owner', 'name', 'name_id'];
this.wideColumns = this.defaultColumns.concat([]);
}

static fromResponse(response) {
const data = Object.assign({}, response);
data.name_id = response.serviceName;
data.git_context = response.provider;
data.owner = response.owner.login;
data.repo_shortcut = `${data.owner}/${data.name}`;
return new CodefreshRepo(data);
}
}

module.exports = CodefreshRepo;
21 changes: 21 additions & 0 deletions lib/logic/entities/GitRepo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const Entity = require('./Entity');

class GitRepo extends Entity {
constructor(data) {
super();
this.entityType = 'git-repo';
this.info = data;
this.defaultColumns = ['git_context', 'owner', 'name', 'repo_shortcut'];
this.wideColumns = this.defaultColumns.concat(['private', 'ssh_url']);
}

static fromResponse(response) {
const data = Object.assign({}, response);
data.git_context = response.provider;
data.owner = response.owner.login;
data.repo_shortcut = `${data.owner}/${data.name}`;
return new GitRepo(data);
}
}

module.exports = GitRepo;
Loading