Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM node:8.2.1-alpine

ENV GTT_VERSION 1.6.11
ENV GTT_VERSION 1.7.0

RUN yarn global add --prefix /usr/local "gitlab-time-tracker@$GTT_VERSION"

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gitlab-time-tracker",
"version": "1.6.11",
"version": "1.7.0",
"description": "A command line interface for GitLabs time tracking feature.",
"bugs": {
"url": "https://github.com/kriskbx/gitlab-time-tracker/issues"
Expand Down
17 changes: 17 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,23 @@ timeFormat: "[%sign][%minutes_overall]"
1095
```

##### `[%hours_overall:2]`, `[%days_overall:3]`

You can ceil any float value by adding the number of decimals to keep separated with a `:`.

**Example config:**

```yaml
timeFormat: "[%sign][%hours_overall:2]"
```

**Example outputs:**

```shell
0,51
18,25
```

## how to use gtt as a library

Add as a dependency using yarn:
Expand Down
39 changes: 39 additions & 0 deletions src/gtt-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const program = require('commander');
const colors = require('colors');
const moment = require('moment');
const Table = require('cli-table');


const Config = require('./include/file-config');
const Cli = require('./include/cli');
const Tasks = require('./include/tasks');

program
.arguments('[project]')
.option('--verbose', 'show verbose output')
.option('-t, --type <type>', 'specify resource type: issue, merge_request')
.option('-c, --closed', 'show closed issues (instead of opened only)')
.option('--my', 'show only issues assigned to me')
.parse(process.argv);

Cli.verbose = program.verbose;

let config = new Config(process.cwd()),
tasks = new Tasks(config),
type = program.type ? program.type : 'issue',
project = program.args[0];

tasks.list(project, program.closed ? 'closed' : 'opened', program.my, program.type)
.then(issues => {
let table = new Table({
style : {compact : true, 'padding-left' : 1}
});
if (issues.length == 0) {
console.log("No ${programm.type}s found.");
}
issues.forEach(issue => {
table.push([issue.iid.toString().magenta, issue.title.green + "\n" + issue.data.web_url.gray, issue.state])
})
console.log(table.toString());
})
.catch(error => Cli.error(error));
4 changes: 1 addition & 3 deletions src/gtt-log.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ Cli.verbose = program.verbose;

let config = new Config(__dirname).set('hoursPerDay', program.hours_per_day),
tasks = new Tasks(config),
timeFormat = config.set('timeFormat', program.time_format).get('timeFormat');

timeFormat = _.isObject(timeFormat) && timeFormat['log'] ? timeFormat['log'] : timeFormat;
timeFormat = config.set('timeFormat', program.time_format).get('timeFormat', 'log');

function toHumanReadable(input) {
return Time.toHumanReadable(Math.ceil(input), config.get('hoursPerDay'), timeFormat);
Expand Down
3 changes: 2 additions & 1 deletion src/gtt.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env node

const version = '1.6.11';
const version = '1.7.0';
const program = require('commander');

program
Expand All @@ -11,6 +11,7 @@ program
.command('stop', 'stop monitoring time')
.command('resume [project]', 'resume monitoring time for last stopped record')
.command('cancel', 'cancel and discard active monitoring time')
.command('list [project]', 'list all open issues')
.command('log', 'log recorded time records')
.command('sync', 'sync local time records to GitLab')
.command('edit [id]', 'edit time record by the given id')
Expand Down
5 changes: 5 additions & 0 deletions src/include/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ class tasks {
});
}

list(project, state, my, type) {
this.config.set('project', project);
return (new classes[type](this.config, {})).list(this.config.get('project'), state, my);
}

/**
*
* @param project
Expand Down
18 changes: 18 additions & 0 deletions src/models/issue.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,24 @@ class issue extends hasTimes {
return promise;
}

list(project, state, my) {
return new Promise((resolve, reject) => {
let promise;
const query = `scope=${my ? "assigned-to-me" : "all"}&state=${state}`;
if (project) {
promise = this.get(`projects/${encodeURIComponent(project)}/issues?${query}`);
} else {
promise = this.get(`issues/?${query}`);
}
promise.then(response => {
const issues = response.body.map(issue => new this.constructor(this.config, issue))
resolve(issues)
});
promise.catch(error => reject(error))
})
}


/*
* properties
*/
Expand Down
17 changes: 17 additions & 0 deletions src/models/mergeRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ class mergeRequest extends hasTimes {

return promise;
}

list(project, state, my) {
return new Promise((resolve, reject) => {
let promise;
const query = `scope=${my ? "assigned-to-me" : "all"}&state=${state}`;
if (project) {
promise = this.get(`projects/${encodeURIComponent(project)}/merge_requests?${query}`);
} else {
promise = this.get(`merge_requests/?${query}`);
}
promise.then(response => {
const issues = response.body.map(issue => new this.constructor(this.config, issue))
resolve(issues)
});
promise.catch(error => reject(error))
})
}

/*
* properties
Expand Down
16 changes: 16 additions & 0 deletions src/models/time.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const defaultTimeFormat = '[%sign][%days>d ][%hours>h ][%minutes>m ][%seconds>s]
const mappings = ['complete', 'sign', 'weeks', 'days', 'hours', 'minutes', 'seconds'];
const regex = /^(?:([-])\s*)?(?:(\d+)w\s*)?(?:(\d+)d\s*)?(?:(\d+)h\s*)?(?:(\d+)m\s*)?(?:(\d+)s\s*)?$/;
const conditionalRegex = /(\[\%([^\>\]]*)\>([^\]]*)\])/ig;
const roundedRegex = /(\[\%([^\>\]]*)\:([^\]]*)\])/ig;
const conditionalSimpleRegex = /([0-9]*)\>(.*)/ig;
const defaultRegex = /(\[\%([^\]]*)\])/ig;

Number.prototype.padLeft = function (n, str) {
Expand Down Expand Up @@ -121,6 +123,20 @@ class time {
inserts.seconds = ((input % secondsInADay) % secondsInAnHour) % secondsInAMinute;
inserts.Seconds = inserts.seconds.padLeft(2, 0);

// rounded
while ((match = roundedRegex.exec(format)) !== null) {
if (match.index === roundedRegex.lastIndex) roundedRegex.lastIndex++;
let time, conditionalMatch, decimals = match[3];

if ((conditionalMatch = conditionalSimpleRegex.exec(decimals)) !== null) {
decimals = conditionalMatch[1]
}

decimals = parseInt(decimals);
time = Math.ceil(inserts[match[2]] * Math.pow(10, decimals)) / Math.pow(10, decimals);
output = output.replace(match[0], time !== 0 && conditionalMatch ? time + conditionalMatch[2] : time);
}

// conditionals
while ((match = conditionalRegex.exec(format)) !== null) {
if (match.index === conditionalRegex.lastIndex) conditionalRegex.lastIndex++;
Expand Down