Code Monkey home page Code Monkey logo

hey_3's Introduction

NAME

Hey - a simple command line time tracker, written in Raku and backed by SQLite.

DESCRIPTION

Hey is a command line tool that tracks your time spent on various projects that may have happened along the way.

USAGE

Quickie Version

Usage:
  hey start [<start_args> ...] -- Start a new timer
  hey stop [<stop_args> ...] -- stop an existing timer
  hey log <number> <duration> -- see a log of recent timers
  hey log-interrupts <number> <duration> -- see a log of recent interruptions
  hey running -- lets you know if there are any timers running & what they are for
  hey <name> [<start_args> ...] -- Record an interruption
  hey kill timer <id> -- Remove an unwanted timer.
  hey nevermind -- Cancel & delete the most recent running timer
  hey kill <name> -- Remove an unwanted person / thing from interruptions

    [<start_args> ...]    optional time adjustment, project(s), & optional tags
    [<stop_args> ...]     optional id, and optional time adjustments (e.g. 4 minutes ago)
    <number>              number of duration units
    <duration>            duration string. E.g. minutes, hours, days, etc.
    <name>                name of person / thing that interrupted you
    <id>                  the id of the timer to delete.

And now for some useful details to fill in the gaps...

Timers

Starting and stopping timers is pretty straightforward. At a bare minimum you just tell it to start and give it a project name: hey start @my_project and stop it when you're done with hey stop

Associating Projects & Tags

  • Project names are prefixed with @.
  • Tag names are prefixed with +. Neither can contain spaces.
  • Every timer event must be associated with at least one project.
  • Tags are optional.
  • Order of tags and projects doesn't matter. They can be mixed too.
# simple usage
hey start @project +tag1 +tag2
hey stop

Backdating Timers

The start and stop of a timer can be backdated using relative or absolute times.

Time modifiers must come immediately after start/stop.

Absolute Times

Absolute times are specified with 12 hour or 24 hour time formats. You can also just specify the hour with no minutes. The expected format is "at" followed by the time.

hey start at 4 @project +tag
hey start at 4:30 @project +tag
hey start at 16:30 @project

The system will always assume you mean the most recent corresponding time. So, if for example it's 6PM and you say at 4 it's going to assume you mean 2 hours ago. If, however it's 3PM and you say at 4 it's going to assume you meant 4 AM. This will carry-over to the previous day if you leave a timer running overnight. And yes, it should handle year boundaries correctly and not accidentally mark something as being done in the future.

Occasionally you'll need to specify stop a timer you left running the prior day, or maybe add a record for some time you forgot to track on a past day. In that case you can also specify the date. Dates come before times and are in MM/DD format. When you do this you will need to specify the full time in 24hr format. There's no good way for Hey to know if 4:00 means 4 PM or 4 AM.

hey start at 12/16 11:50 @project

Relative Times

Relative times come immediately after start/stop and follow the syntax of <number> <time unit> ago

You must include "ago" as it provides a clue to the code as to what you're intending.

# backdating 
hey start 4 minutes ago @project +tag1
hey start 3 days ago @project

Supported Duration Words

You can use any of the following duration words.

  • second
  • seconds
  • minute
  • minutes
  • hour
  • hours
  • day
  • days
  • week
  • weeks
  • month
  • months
  • year
  • years

Multiple Timers

Hey supports multiple simultaneous timers. There's nothing fancy to it. The only special note is that stop will stop the most recent one unless you provide an id.

Stopping A Specific Timer

To stop a specific timer you just give it the integer id shown in the log.

hey stop 12

Killing A Specific Timer

Sometimes, things don't go as planned. For example, I started a timer to go walk the dogs, left my computer, and unexpectedly ended up eating lunch. That timer was no good.

To kill an unwanted timer say hey kill timer <id>

hey kill timer 4

A timer's id is shown when you create a new timer, or when you view the log.

Alternately....

Stop the most recently created running timer without knowing its ID.

hey nevermind

Why? Because I keep starting a timer and then finding myself being retasked. For example:

me: "I'm going to start cooking..." hey start @cooking wifey: "Maybe you should walk the dogs first so that they don't annoy you with constantly wanting to go in and out." me: πŸ€” hey nevermind hey start @dogs +walking

Viewing the Log

hey log <number> <duration>

example log output

This uses the same duration words as in backdating.

hey log 4 days
hey log 24 hours

Note: when it comes to durations of a day or larger it uses cultural meaning not literal meaning.

So, for example:

  • hey log 1 day is going to get you today's log.
  • hey log 1 week is going to get you this week's log. Monday is treated as the start of the week, so if it's Monday you'll only see one day worth of records.
  • hey log 1 month is going to get you this month's log.
  • hey log 1 year is going to get you this year's log.

Day's an larger all count from midnight. All times should be local.

If you want a specific and literal amount of time use seconds, minutes, or hours.

So, for example, hey log 1 day doesn't get you the past 24 hours worth of logs. It gets you everything from midnight yesterday. If you really want 24 hours, just say hey log 24 hours.

Summarized Time

Summarizing timers follows the same pattern as generating a log of them. Asking for a summary of timers will produce a table displaying the amount of time spent on each project during that duration.

hey summarize timers <amount of time> <duration>

So, for example, hey summarize timers 2 days might output something like this.

example summary output

Interruptions

Recording an interruption is the same as recording a timer, except that you start with the name of the person / thing that interrupted you, and project is completely optional.

hey bob
hey bob at 9:15
hey bob at 10:30 +gossip
hey bob at 11:15 @project_x +questions
hey bob 20 minutes ago 
hey bob 10 minutes ago @project_x +questions

Viewing the Log

This works the same as viewing your timer logs, but you say "log-interrupts" instead of "log"

hey log-interrupts <number> <duration>

example log output

Other

Tagging After the fact

You can add tags to a timer or interruption after it's been created, by running hey tag <id> <list of tags> If you ran a marathon and wanted to tag it with your thoughts afterwards you might say hey tag 33 +hard +fulfilling

Listing Projects

hey projects will output a list of all the projects you've entered. This is useful when you've forgotten what you called something, and for integrations like shell autocomplete.

INSTALLATION

Hey is written in Raku, and uses the zef package manager for installation.

If you've already got Raku and zef installed then just run:

zef install Hey

If you don't have Raku installed then...

Raku install quick-guide

My recommendation is to use Homebrew to install Rakudo Regardless of if you use Homebrew, or download from the main site, you'll want the Rakudo-Star package. This brings along a handful of other useful things, like our package manager: zef.

brew install rakudo-star

Now, go back and run the zef install Hey command from above.

Coming soon

Tagging After The fact

Sometimes you'll record an interruption, or some work, but forget to add a tag.

Reports

  • Graph Interruptions over time, to find parts of the day where you're most likely to be able to focus, or need to hide.
  • Graph Interruptions by people to find out who you need to talk to.
  • Graph Interruptions by tag or projects to find out where you would best benefit from adding documentation.

Configuration

It'd be nice to be able to configure things, such as when the start of the day is. Many of us work past midnight, and consider it part of the prior day's work. So, it'd be nice to have the logging use our preferred "start of day" time. Here's the GitHub issue for that feature.

I'm betting you might have ideas for configurations too. Like, maybe colors for specific data types in the report?

CONTRIBUTING

Pull Requests are very welcomed.

I'm using this daily now so there will be modifications and improvements over time. I'm especially interested in adding useful reporting and data extraction functionality.

Let's chat on Mastodon if you've got some ideas. Alternately, just file a new ticket on github.

Note: this app's version numbers follow strict Semantic Versioning.

Tests

The test suite uses bash_unit because testing an app where 90% of the behaviors are based upon side-effects of data that may, or may not, have been persisted in the DB is way easier to write System tests for than Unit tests. If you feel like writing some Raku unit tests with all the stubbing that that will require, I'll happily merge the PR.

Regardless of unit tests, if you do add / change functionality please include additional bash_unit tests with your PR.

The bash_unit tests can be run by changing into the bash_unit_tests directory and running bash_unit hey_test.sh

Note that these will work on a local test database, so you don't have to worry about hurting your real time & interruption tracking data.

AUTHOR

masukomi (A.K.A. Kay Rhodes)

COPYRIGHT AND LICENSE

Copyright 2022 Kay Rhodes & distributed under the GNU Affero General Public License version 3.0 or later.

hey_3's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

hey_3's Issues

[bug] killing unknown things shows stack trace

tried to kill by id (couldn't remember if i'd added support for that - see #37 ) got this as a result.

there should be no stack trace after the error message.

1202 wasn't found. Maybe they know what you're planning!
  in sub unwrap at /Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/site/sources/E2EB282798A7D4CB4E849B977867B774BBD41E92 (Definitely) line 235
  in sub MAIN at /Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/site/resources/E470A641173EDC7592C583B0792D50B5BC0EC783 line 358
  in block <unit> at /Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/site/resources/E470A641173EDC7592C583B0792D50B5BC0EC783 line 59
  in sub MAIN at /Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/site/bin/hey line 3
  in block <unit> at /Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/site/bin/hey line 1

add ability to export log as json

hey log-json <duration>

Basically the same thing as hey log <duration> but it would output a JSON array with containing a denormalized object / Hash for each event that looked like this.

events that had not ended /would/ be included, but would have null in the ended_at field.

{
  "type": "event",
  "id": 12345,
  "created_at": "<ISO-8601 string>",
  "updated_at": "<ISO-8601 string>",
  "started_at": "<ISO-8601 string>",
  "ended_at": "<ISO-8601 string>",
  "total_seconds": 12345,
  "projects": [ "foo", "bar"],
  "tags": ["baz", "beedle"]
}

summarization of project or tag

hey summarize @foo 1 day

will output a table showing how how much time was spent on the @foo project, regardless of tags, for the given duration.

When the duration is "day" or larger and the number is > 1 it should have a line for each block of that duration and a line for the total spent across the reporting time.

So, if we said hey summarize @foo 4 weeks

We'd see something like this

week starting time spent
11/28/22 3hrs 42mins
12/05/22 14hrs 3 mins
12/12/22 5hrs 16 mins
12/26/22 0mins
Totals 24hrs 1 min

If we said hey summarize @foo 40320 seconds (4 weeks) we'd see something like this (because seconds < days )

Total for 40320 seconds
24hrs 1 min

We should be able to do the same for tags +bar or combinations thereof (@foo +bar). The latter being only reporting on the foo project where entries also had the bar tag.

It'd be great if we could do specify multiple projects and multiple tags to get really really specific but that query might be a pain in the butt.

totals by project table

create a "days totals" (or months, or whatever) table that displays after the log and contains the total time spent within the given duration on each project in a duration.

So, if you have logged 3 timers of 1hr each for @foo project today, there would be, in a subsequent table a line that indicated that @foo had 3hrs spent on it

Something like this

project time spent
@foo 3h
@bar 45m
total 3h45m

improve time functions & unit test

We really need Raku unit tests for the time related functions in Utilities

change 1

We don't have an equivalent of timecop in Raku AFAIK so, we'll have to modify anything that's comparing the current date to a past date to take an optionalDateTime parameter (named now ?) if it isn't already.

change 2

This is somewhat thinking-out-loud not "what must happen". The most important thing being that the resulting code is testable, and easy to wrap your head around.

extract-time-adjustment-args needs to be modified to return a hash, and the multiple places that interact with its output need to be modified accordingly

the hash contents should address the following questions

  • is the user setting a specific date?
  • is this a relative time adjustment or absolute?

as this method is just about "get the args out of the input" it shouldn't be doing any calculations based on those.

I think then we might want to introduce an intermediary method(s) that expands on that hash. and answers the following questions

  • what is the correct hour
  • what is the correct minute
  • what is the correct month
  • what is the correct day
  • what is the correct year

Many of these already exist and could just be leveraged to shove their output into the hash.

after all that we can just take the contents of the hash, shove them into a new DateTime object.

change 3

unit test the πŸ’© out of whatever comes out of that.

Command name consistancy

hey kill timer <id> and hey summarize timers use multi-word commands, but hey log-interrupts uses a hyphen. It seems like hey should pick one style and stick to it.

(This is very minor, but it's easier to change now).

I don't have strong feelings on which style to adopt, but I mildly prefer the hyphenated version (which IME is more common).

configurable end/start of day

It'd be nice to be able to configure things, such as when the start of the day is. Many of us work past midnight, and consider it part of the prior day's work. So, it'd be nice to have the logging use our preferred "start of day" time.

There should be a config file in $XDG_CONFIG_HOME/hey/config.toml (or similar) that allows users to specify that time. I think that file should probably be TOML, but am open to suggestions. Just not YAML because way too many developers hate YAML. :/

[feature] tab completion of projects and tags

add tab completion of projects and tags

start @project_<tab> should

  1. autocomplete the project name if there's only one match
  2. print out the list of all matching projects if more than one matches
  • in both cases hitting should make the suggestion text disappear
  • in both cases typing more should make the suggestion text disappear

the same behavior should apply to tags. eg. hey start @project +wal<tab>

Example tab-completion code via Linenoise. I'm currently unsure how to handle the printing of suggestions that then go away.

#!/usr/bin/env raku

use Linenoise;

my @commands = <help quit list get set>;

sub find-last-word(Str $line) {
	return $line.subst(/.*? \s? $<lw>=(\S+) $/, {"$<lw>"}  );
}

linenoiseSetCompletionCallback(-> $line, $c {
    my ( $last-word ) = find-last-word($line);

    for @commands.grep(/^ "$last-word" /).sort -> $cmd {
        linenoiseAddCompletion($c, $cmd);
    }
});

my $line = linenoise '> ';
# while (my $line = linenoise '> ').defined {
    say "got a line: $line";
# }

add to list of supported durations

I want to be able to type min and mins instead of minute or minutes and hr or hrs instead of hour or hours

This would be adding those to the list in utilities and adding them to the place where it checks if you're using a duration that's shorter than "days".

[feature] add hey kill project <name>

originated in this comment by @codesections

Killing projects is dangerous for anyone using this for billing purposes.

As such i think that there should be a -f / --force option for this. If the flag isn't passed then the project is actually just archived. This is a personal time tracker so the amount of data we're talking about is negligible and not going to cause anyone problems

this, of course, means we need a way to see a list of "archived" projects...

I'm thinking maybe a hey archives command which would, initially, just list archived projects, but if we decide to archive people instead of deleting it could have a section for them too.

and then a way to unarchive a project:

hey unkill project <name> ? πŸ€” I'm unsure about unkill vs unarchive

I don't want to do a hey kill project <x> AND hey archive project <x> because it's too easy to move fast and accidentally do the dangerous one. really deleting should require the extra thought / effort of adding --force

[feature] project should have default tags

I should be able to associate a project with some default tags.

that way when i say hey start @foo i don't have to say hey start @foo +tags +foo +always +has and / or don't have to remember to add them in afterwards.

Not sure how to handle this at the db level. πŸ€”

better handling of ongoing timers

Ongoing timers should have their current duration displayed instead of just "ongoing"

when you say hey today or hey log 1 day
I'm thinking it should be something like > 40m41s

when you hey summarize 1 day it should add in whatever time has passed so far on ongoing timers.

[feature] hey stop should ask which timer when multiple are running

currently saying hey stop will stop the most recently started timer. This is problematic if you have automations starting timers and unclear when you didn't realize you had multiple running.

request:

  1. when run without a timer id, hey stop should check if there are multiple timers running
  2. it should display the currently running timers if there are more than one.
  3. it should allow you to enter the one you want to stop, and then apply your original command. So, hey stop at 3:00 would ask you for an ID and then be invoked as if you ran hey stop <id> at 3:00

[bug] piping hey's log output results in broken pipe

beta 8 code, but i suspect it has existed all along.

The line in question is say $table which is an instance of Prettier::Table. I initially thought this was a bug in Prettier::Table but now I'm not so sure, because the demo.raku file over there does say $table and can be piped without issue.

Failed to write 2048 bytes to filehandle: Broken pipe
  in sub display-timers-as-table at /Users/masukomi/workspace/Hey/lib/Hey/Timer.rakumod (Hey::Timer) line 90
  in sub generate-log at bin/hey line 408
  in sub MAIN at bin/hey line 211
  in block <unit> at bin/hey line 49

latest commit is

commit 738ea03b621ceb7ca04ecedf8fed3996ed7faa2f (HEAD -> beta_8, origin/beta_8)
Author: masukomi <[email protected]>
Date:   Sat Dec 31 18:01:05 2022 -0500

    summarized timers now say duration in table title

ability to rename project

proposed interface

hey rename project <old name> <new name>

Behind the scenes this would just need to do a

UPDATE projects SET name = 'new-name' 
WHERE name = 'old-name`;

Project names should be unique, and can't be "archived", so this change should be safe without other constraints.

Generating Data For Invoices

This is a high level ticket to work out ideas for generating data for invoicing as I'm about to need it.

I can see 2 main desires here:

  1. gimme the raw data!
    I'm thinking CSV is probably the best format for this use case
  2. generate a printable/PDFable invoice!
    For those who aren't using an invoicing system. I'm thinking something simple like a markdown document. User puts a markdown template in XDG_HOME_CONFIG and a file is generated based off of that.

Setting aside how we export it, I think we need to contemplate what we report.

I think we need to be able to specify a time range, and one with no end date is just "since X"

Output options:

  • days worked in range
    • list of days, chronologically sorted
    • total (for invoice version)
  • hours worked in range
    • list of hours by week because I suspect most freelancers don't want clients seeing number of hours worked on any given day. That could be problematic. hours by month seems too coarsely grained.

Open questions / thoughts

I think there's an implication here about billing, and that one shouldn't be able to bill for the same time unit twice. This implies that we should add an "invoiced" flag. But, what does it mean if you try and edit a thing that's been invoiced. "Are you sure? This has been invoiced" I'm thinking there are times when you'll generate an invoice, go 'oh crap', edit something, and then regenerate it, so they should be editable. Maybe there's a --force flag when editing the time on an invoiced entry. Without it it goes "Oy! this has been invoiced. Try again with --force if you really want to be editing this." Or something like that.

πŸ€” I wonder if there are any services with APIs that we could push to, and if it'd be worth the effort to support them.

[feature] hey nevermind should work on interruptions too

hey nevermind shouldn't be restricted to timers.

it should get rid of the last event regardless of if it was a timer or an interruption.

HOWEVER,
in both cases it should remove one-off metadata.

Example

if i type hey runnnig instead of hey running (typo) it's going to create an interruption event from a new person named runnnig. I want to hey nevermind and eliminate that event, but ALSO see that runnnig (the person) only existed in the context of that one event and get rid of it.

Similarly if the timer is associated with a project that has no other associated events the project should be deleted. Ditto for tags.

Goal:

I want a fast and easy way to address bad data resulting from typos if i notice them immediately after creation.

addressing them later is a trickier task.

Task:

  1. the nevermind functionality should be expanded to encompass interruptions
  2. the nevermind functionality should delete records that are associated with the "bad" event IF they aren't tied to any other event.

ability to 'restart' work on a project

It's not uncommon to stop some work and restart it later in the day (or the next day)

given the name of a project we should be able to easily "restart" work on it by creating a new timer with the same tags. The idea being you're "restarting" work on that project.

proposed interface

hey restart @project

It should error gracefully, if the name doesn't correspond to any known project.
it should use the same tags associated with the last event for this project.

variant

hey restart will just restart whatever the last event was.

[feature] enable editing of existing timers & interruptions

we have the id of the timer / interrupt from the logs. We just need a command that lets us say we're editing the start or end.

Note that Timers and Interruptions are both records in the events table so the ids don't overlap. We can, in theory, use the same command for both. That way we wont need "hey edit timer 4 start at 4:44" and "hey edit interrupt 5 start at 5:55" we can just have one "hey edit event start at 6:46" as well as a "end" version.

The "end" version should error if the id corresponds to an interruption.

Events have a type of interruption or timer.

So, the request is for a new "edit" command in hey which lets us do the following, and updates the db as you'd expect.

hey edit 4 start at 5:30
hey edit 4 start 4 minutes ago
hey edit 4 end at 6:30
hey edit 4 end 12 minutes ago

Most of the code for this already exists and can be reused.

Note: technically we already have half of this. We can say hey stop 4 at ..... on a timer that's already been stopped and it'll change the stop time.

[feature] graph hours captured by day

A simple vertical bar graph. Each bar represents 1 of whatever time unit was requested.

if you ask for 7 days you get 7 bars. 2 weeks 2 bars, etc.

each bar represents the total hours captured. I think the max should probably be ~18hrs ? I'm hoping folks aren't working more than 18hrs in a day (shudder at the thought of doctors with 24hr shifts). The problem with 24 is that it leaves a ton of empty space at the top for the vast vast majority of humans.

This will require a cli graphing library. We'll probably have to port something like this library i wrote in crystal unless something like this already exists in Raku.

enhanced stop syntax

right now you can say hey stop at HH:MM but i just noticed i've left a timer running for two days πŸ€¦πŸ»β€β™€οΈ so the normal backdating isn't going to work.

I'm proposing the expansion of the at <time> time modification to be at [optional date] <time>

# hey stop at mm/dd HH:MM
hey stop at 12/16 14:22

In this case we would have to presume 24hr time input because we don't have relative context to guess at which 6:40 they meant.

[feature] teach it to recognize backdating anywhere in the arguments list

hey start 4 minutes ago @project +tag is all well and good, but it'd also be nice to be able to say hey start @project +tag 4 minutes ago or hey start @project 4 minutes ago +tag Ditto for the at 4:00 style of backdating.

With a little bit of creative Regexp we can detect the time strings, and then extract them from the arguments list regardless of where they are.

[feature] support single-timer-mode

I find i generally don't want multiple timers to be able to run at the same time, but I can see value in the feature, so I don't want to get rid of it.

Instead i think i want to add a new metadata field to toggle "single timer mode"

in single timer mode the following behavior would be exhibited

starting 1 timer would stop a running timer at the same moment (or maybe prior second), and print out the ids of both. Something like:

stopped: @foo (123) after 22 minutes
started: @bar at 11:22

can't stop specific timer

it supports multiple simultaneous timers, but you can only support the last one.

hey log shows the ID now.
enable stop to take an id as the first parameter.

[feature] slightly less concise durations in log

I'm using the Time::Duration library to generate the duration text in the logs.

it was outputting something like "2 hours and 23 minutes". In Beta 5 it's outputting "2h23m" That's a bit... too concise for my taste.

I'd like "2hr 23min".

I think the best solution is to make a PR against Time::Duration and then use that, but barring/until that we can just shove it into Utilities.rakumod

[feature] projects should have a concept of archiving

you should be able to "archive" a project such that it no longer shows up in the list of hey projects

why

because if we're going to build autocomplete tools and GUIs they shouldn't be asking you to choose from projects you no longer care about.

Edge case

if you start a new timer with a project name that's been previously archived it should unarchive that project. Maybe the client came back. Doesn't matter why you've started using it, just that if you are, it's no longer conceptually in the "archive".

Side note

we'll eventually have to do this with tags too...

[bug] problems stopping specific timer

if you have two timers going and say hey stop <id of earlier timer> 1 minute ago it will stop the most recently started one instead of the one specified.

The problem is that stop + id expects explicit 4 section time string (date + 24hr time), but it's not getting that and it's mistakenly not erroring out.

bug found on beta_9 branch, but probably exists in main.

add concise "stopped" column to tables

Currently there's a "Started" column which contains something like this 12/30 08:23 AM and a "Total" column which contains something like this 1h19m

I keep finding that i need to start a timer after the fact, but figuring out when involves mental math to calculate what time the prior timer stopped.

This ticket proposes a "Stopped" column that contains something like 09:30 AM. We know the day from "Started" and it's rarely going to be multi-day or crossing day boundary. When it does i think the context of the "Total" will be plenty.

Note: this does overlap in concept with the need for the ability to start a timer at the end of the prior timer ( Issue #14 ) but i think this is valuable for other reasons too.

allow beginning a timer at the end of the prior timer

I would like to be able to tell hey to start a new timer that starts immediately after the last timer ended.

So,

  1. find the most recently ended timer
  2. start a new timer 1 minute after that. Note that if the last one ended at 59 minutes the new one should start at 0 minutes. Ignore seconds

UX something like

hey start after [last|id] @foo +bar

no time adjustment would be supported in this interface.

bash_unit tests for backdating

backdating is tricky without a good way to "freeze time"

The DB uses epoch time stamps to record time (because SQLite doesn't have a native concept of Dates or Times... at least not as far as a data type).

We need tests that confirm that starting & stopping of a task, and the creation of interruptions using the relative and absolute formats

Examples:

hey start at 4:30 @proj +task
hey stop at 5:30
hey bob at 13:50
hey bob at 1:51
hey start 4 minutes ago
hey stop 3 minutes ago

The problem is that without the ability to freeze time it becomes difficult to test the time you're expecting in the db. You have to start testing for ranges. For example, create the thing, get the current epoch time, and then test that the started_at column contains a number within 2 seconds of the current epoch time you recorded.

This is because you could create a thing, and in the millisecond between creation and reading you've crossed into the next second, and now the numbers aren't the same.

So, we a new assert function. I've filed a feature request ticket against bash_unit.

Once we have / create that then we can do the simple math of taking the current epoch time, subtracting N minutes worth of seconds, and comparing that to the backdated time shoved in the db.

Dependency on Template6

Hi,

on one hand, it's very flattering to see dependencies on Template6 that mostly I have been maintaining for a while... on the other hand, this repo doesn't seem to use it for anything. Perhaps it could be removed from dependencies, or I'm missing something.

Cheers.

[bug] summary doesn't account for timer overlaps

The summarize functionality (e.g. hey summarize timers 1 day ) doesn't correctly handle overlaps. the math is wrong and results in overlapping timers causing an increase in unaccounted time.

❯ hey log 1 day
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                          All Timers                                         β”‚
β”œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  ID β”‚ Started            β”‚ Ended        β”‚  Total β”‚ Projects    β”‚ Tags                       β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 384 β”‚ Mon 01/30 08:31 AM β”‚ Mon 09:32 AM β”‚  1h49s β”‚ daily_todos β”‚ unwanted                   β”‚
β”‚ 385 β”‚ Mon 01/30 09:33 AM β”‚ Mon 10:51 AM β”‚  1h19m β”‚ eating      β”‚ breakfast, required, smile β”‚
β”‚ 386 β”‚ Mon 01/30 10:01 AM β”‚ Mon 10:51 AM β”‚ 50m53s β”‚ daily_todos β”‚ meh, unwanted              β”‚
β”‚ 387 β”‚ Mon 01/30 10:52 AM β”‚ Mon 11:20 AM β”‚ 28m33s β”‚ daily_todos β”‚ unwanted                   β”‚
β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

resulted in this summary

❯ hey summarize timers 1 day
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       1 day Summary…      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Project      β”‚ Total Time β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ daily_todos  β”‚      2h20m β”‚
β”‚ eating       β”‚      1h19m β”‚
β”‚ ━━━━━━━━━━━  β”‚    ━━━━━━━ β”‚
β”‚ All…         β”‚      3h39m β”‚
β”‚ Unaccounted… β”‚     49m50s β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

but when I modified the end of timer 385 (eating) such that it no longer overlapped and went too long it decreased the unaccounted time,

❯ hey summarize timers 1 day
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       1 day Summary…      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Project      β”‚ Total Time β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ daily_todos  β”‚      2h20m β”‚
β”‚ eating       β”‚        27m β”‚
β”‚ ━━━━━━━━━━━  β”‚    ━━━━━━━ β”‚
β”‚ All…         β”‚      2h47m β”‚
β”‚ Unaccounted… β”‚      1m45s β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mostly this is just a case of the algorithm being too simple and assuming none of the timers overlap and thus their total seconds can be summed without issue.

slow startup time

Hey is fairly slow to start up. Even on a fairly decent desktop, it routinely takes nearly a second to launch, even for simple commands such as displaying the USAGE message. (Testing with hyperfine shows a startup time of 832ms (Β±16ms)).

Some of this is, unfortunately, a Raku problem – even "Hello world!" Raku programs take ~100ms to start. But it's definitely possible to start up a lot faster than Hey is right now; for example, zef displays it usage message in ~250ms. And, for interactive CLI use, the difference between ΒΌ second and ΒΎ second feels huge (at least in my highly subjective experience).

I'm not 100% sure of the best fix, but I suspect that moving logic (and module loading) out of bin/hey would be a good place to start.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.