{"id":13394959,"url":"https://github.com/samg/timetrap","last_synced_at":"2025-05-12T13:26:09.784Z","repository":{"id":544589,"uuid":"174603","full_name":"samg/timetrap","owner":"samg","description":"Simple command line timetracker","archived":false,"fork":false,"pushed_at":"2025-03-12T20:07:55.000Z","size":625,"stargazers_count":1491,"open_issues_count":31,"forks_count":115,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-04-23T07:04:22.677Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://rubygems.org/gems/timetrap","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2009-04-13T09:17:23.000Z","updated_at":"2025-04-11T02:28:06.000Z","dependencies_parsed_at":"2025-04-23T07:14:18.309Z","dependency_job_id":null,"html_url":"https://github.com/samg/timetrap","commit_stats":{"total_commits":434,"total_committers":41,"mean_commits":"10.585365853658537","dds":0.6797235023041475,"last_synced_commit":"92cc450e613c01996e9c1f745516c0d358af669c"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samg%2Ftimetrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samg%2Ftimetrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samg%2Ftimetrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samg%2Ftimetrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samg","download_url":"https://codeload.github.com/samg/timetrap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253746599,"owners_count":21957594,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T17:01:37.467Z","updated_at":"2025-05-12T13:26:09.711Z","avatar_url":"https://github.com/samg.png","language":"Ruby","funding_links":[],"categories":["Ruby","Productivity","Time Tracking","Time Tracking CLI Tools","\u003ca name=\"time-tracker\"\u003e\u003c/a\u003eTime trackers","\\*nix/\\*nux"],"sub_categories":["Time Tracking","Understand How Your App is Doing with Real-Time Contextual Insights From Your Users","Productivity"],"readme":"Timetrap [![Build Status](https://secure.travis-ci.org/samg/timetrap.png)](http://travis-ci.org/samg/timetrap)\n========\n\nTimetrap is a simple command line time tracker written in ruby. It provides an\neasy to use command line interface for tracking what you spend your time on.\n\nGetting Started\n---------------\n\nTo install:\n\n    $ gem install timetrap\n\nThis will place a ``t`` executable in your path.\n\nIf you would like to build the latest master from source:\n\n    $ git clone https://github.com/samg/timetrap\n    $ cd timetrap\n    $ gem build timetrap\n    $ gem install timetrap_X.X.X.gem\n\nIf you have errors while parsing the documentation, use `--no-document` option when installing the gem, or other option is to `gem install rdoc` before installing the `timetrap`. This is a known issue from [rdoc](https://github.com/ruby/rdoc/commit/5f9603f35d8e520c761015810c005e4a5beb97c3)\n\n### Basic Usage\n\n    $ # get help\n    $ timetrap --help\n    $ # or\n    $ t --help\n\nTimetrap maintains a list of *timesheets*.\n\n    $ # create the \"coding\" timesheet\n    $ t sheet coding\n    Switching to sheet coding\n\nAll commands can be abbreviated.\n\n    $ # same as \"t sheet coding\"\n    $ t s coding\n    Switching to sheet coding\n\nEach timesheet contains *entries*.  Each entry has a start and end time, and a\nnote associated with it.  An entry without an end time set is considered to be\nrunning.\n\nYou check in to the current sheet with the `in` command.\n\n    $ # check in with \"document timetrap\" note\n    $ t in document timetrap\n    Checked into sheet \"coding\".\n\nCommands like `display` and `now` will show you the running entry.\n\n    $ t display\n    Timesheet: coding\n        Day                Start      End        Duration   Notes\n        Sun Nov 28, 2010   12:26:10 -            0:00:03    document timetrap\n                                                 0:00:03\n        ---------------------------------------------------------\n        Total                                    0:00:03\n\n    $ t now\n    *coding: 0:01:02 (document timetrap)\n\nIf you make a mistake use the `edit` command.\n\n    $ # edit the running entry's note\n    $ t edit writing readme\n    Editing running entry\n\nYou check out with the `out` command.\n\n    $ t out\n    Checked out of entry \"document timetrap\" in sheet \"coding\"\n\nRunning `edit` when you're checked out will edit the last entry you checked out\nof.\n\n    $ t edit --append \"oh and that\"\n    Editing last entry you checked out of\n\nYou can edit entries that aren't running using `edit`'s `--id` or `-i` flag.\n`t display --ids`  (or `t display -v`) will tell you the ids.\n\n    $ # note id column in output\n    $ t d -v\n    Timesheet: coding\n    Id  Day                Start      End        Duration   Notes\n    43  Sun Nov 28, 2010   12:26:10 - 13:41:03   1:14:53    writing readme\n                                                 1:14:53\n        ---------------------------------------------------------\n        Total                                    1:14:53\n\n    $ # -i43 to edit entry 43\n    $ t e -i43 --end \"2010-11-28 13:45\"\n    Editing entry with id 43\n\n    $ t d\n    Timesheet: coding\n        Day                Start      End        Duration   Notes\n        Sun Nov 28, 2010   12:26:10 - 13:45:00   1:18:50    writing readme\n                                                 1:18:50\n        ---------------------------------------------------------\n        Total                                    1:18:50\n\n\n### Natural Language Times\n\nCommands such as `in`, `out`, `edit`, and `display` have flags that accept\ntimes as arguments.  Any time you pass Timetrap a time it will try to parse it\nas a natural language time.\n\nThis is very handy if you start working and forget to start Timetrap.  You can\ncheck in 5 minutes ago using `in`'s `--at` flag.\n\n    $ t in --at \"5 minutes ago\"\n\nCommand line flags also have short versions.\n\n    $ # equivalent to the command above\n    $ t i -a \"5 minutes ago\"\n\nYou can consult the Chronic gem (https://github.com/mojombo/chronic) for a full\nlist of parsable time formats, but all of these should work.\n\n    $ t out --at \"in 30 minutes\"\n    $ t edit --start \"last monday at 10:30am\"\n    $ t edit --end \"tomorrow at noon\"\n    $ t display --start \"10am\" --end \"2pm\"\n    $ t i -a \"2010-11-29 12:30:00\"\n\n### Output Formats\n\n#### Built-in Formatters\n\nTimetrap has built-in support for 6 output formats.\n\nThese are **text**, **csv**, **ical**, **json**, and **ids**\n\nThe default is a plain **text** format.  (You can change the default format using\n`t configure`).\n\n    $ t display\n    Timesheet: coding\n        Day                Start      End        Duration   Notes\n        Mon Apr 13, 2009   15:46:51 - 17:03:50   1:16:59    improved display functionality\n                           17:25:59 - 17:26:02   0:00:03\n                           18:38:07 - 18:38:52   0:00:45    working on list\n                           22:37:38 - 23:38:43   1:01:05    work on kill\n                                                 2:18:52\n        Tue Apr 14, 2009   00:41:16 - 01:40:19   0:59:03    gem packaging\n                           10:20:00 - 10:48:10   0:28:10    working on readme\n                                                 1:27:13\n        ---------------------------------------------------------\n        Total                                    3:46:05\n\nThe **CSV** formatters is easy to import into a spreadsheet.\n\n    $ t display --format csv\n    start,end,note,sheet\n    \"2010-08-21 11:19:05\",\"2010-08-21 12:12:04\",\"migrated site\",\"coding\"\n    \"2010-08-21 12:44:09\",\"2010-08-21 12:48:46\",\"DNS emails and install email packages\",\"coding\"\n    \"2010-08-21 12:49:57\",\"2010-08-21 13:10:12\",\"A records\",\"coding\"\n    \"2010-08-21 15:09:37\",\"2010-08-21 16:32:26\",\"setup for wiki\",\"coding\"\n    \"2010-08-25 20:42:55\",\"2010-08-25 21:41:49\",\"rewrote index\",\"coding\"\n    \"2010-08-29 15:44:39\",\"2010-08-29 16:21:53\",\"recaptcha\",\"coding\"\n    \"2010-08-29 21:15:58\",\"2010-08-29 21:30:31\",\"backups\",\"coding\"\n    \"2010-08-29 21:40:56\",\"2010-08-29 22:32:26\",\"backups\",\"coding\"\n\n**iCal** format lets you get your time into your favorite calendar program\n(remember commands can be abbreviated).\n\n    $ t d -f ical \u003e MyTimeSheet.ics\n\nThe **ids** formatter is provided to facilitate scripting within timetrap.  It only\noutputs numeric id for the entries.  This is handy if you want to move all entries\nfrom one sheet to another sheet.  You could do something like this:\n\n    $ for id in `t display sheet1 -f ids`; do t edit --id $id --move sheet2; done\n    editing entry #36\n    editing entry #37\n    editing entry #44\n    editing entry #46\n\nA *json* formatter is provided because hackers love json.\n\n    $ t d -fjson\n\n#### Custom Formatters\n\nTimetrap tries to make it easy to define custom output formats.\n\nYou're encouraged to submit these back to timetrap for inclusion in a future\nversion.\n\nTo create a custom formatter you create a ruby class and implement two methods\non it.\n\nAs an example we'll create a formatter that only outputs the notes from\nentries.\n\nTo ensure that timetrap can find your formatter put it in\n`~/.timetrap/formatters/notes.rb`.  The filename should be the same as the\nstring you will pass to `t d --format` to invoke it.  If you want to put your\nformatter in a different place you can run `t configure` and edit the\n`formatter_search_paths` option.\n\nAll timetrap formatters live under the namespace `Timetrap::Formatters` so\ndefine your class like this:\n\n```ruby\nclass Timetrap::Formatters::Notes\nend\n```\n\nWhen `t display` is invoked, timetrap initializes a new instance of the\nformatter passing it an Array of entries.  It then calls `#output` which should\nreturn a string to be printed to the screen.\n\nThis means we need to implement an `#initialize` method and an `#output`\nmethod for the class.  Something like this:\n\n```ruby\nclass Timetrap::Formatters::Notes\n  def initialize(entries)\n    @entries = entries\n  end\n\n  def output\n    @entries.map{|entry| entry[:note]}.join(\"\\n\")\n  end\nend\n```\n\nNow when I invoke it:\n\n    $ t d -f notes\n    working on issue #123\n    working on issue #234\n\n#### Timetrap Formatters Repository\n\nA community focused repository of custom formatters is available at\nhttps://github.com/samg/timetrap_formatters.\n\n#### Harvest Integration\n\nFor timetrap users who use [Harvest][harvest] to manage timesheets,\n[Devon Blandin][dblandin] created [timetrap-harvest][timetrap-harvest], a custom\nformatter which allows you to easily submit your timetrap entries to Harvest\ntimesheets.\n\nSee its [README][timetrap-harvest] for more details.\n\n#### Toggl Integration\n\nFor timetrap users who use [Toggl][toggl] to manage timesheets,\n[Miguel Palhas][naps62] created [timetrap-toggl][timetrap-toggl] (a fork of the\n[timetrap-harvest][timetrap-harvest] integration mentioned above.\n\nLike the Harvest integration, this one allows you to easily submit your timetrap entries to Toggl.\n\nSee its [README][timetrap-toggl] for more details.\n\n### AutoSheets\n\nTimetrap has a feature called auto sheets that allows you to automatically\nselect which timesheet to check into.\n\nTimetrap ships with a couple auto sheets.  The default auto sheet is called\n`dotfiles` and will read the sheetname to check into from a `.timetrap-sheet`\nfile in the current directory.\n\n[Here are all the included auto sheets](lib/timetrap/auto_sheets)\n\nYou can specify which auto sheet logic you want to use in `~/.timetrap.yml` by\nchanging the `auto_sheet` value.\n\n#### Custom AutoSheets\n\nIt's also easy to write your own auto sheet logic that matches your personal\nworkflow.  You're encouraged to submit these back to timetrap for inclusion in\na future version.\n\nTo create a custom auto sheet module you create a ruby class and implement one\nmethod on it `#sheet`.  This method should return the name of the sheet\ntimetrap should use (as a string) or `nil` if a sheet shouldn't be\nautomatically selected.\n\nAll timetrap auto sheets live under the namespace `Timetrap::AutoSheets`\n\nTo ensure that timetrap can find your auto sheet put it in\n`~/.timetrap/auto_sheets/`.  The filename should be the same as the\nstring you will set in the configuration (for example\n`~/.timetrap/auto_sheets/dotfiles.rb`.  If you want to put your auto sheet in a\ndifferent place you can run `t configure` and edit the\n`auto_sheet_search_paths` option.\n\nAs an example here's the dotfiles auto sheet\n\n```ruby\nmodule Timetrap\n  module AutoSheets\n    class Dotfiles\n      def sheet\n        dotfile = File.join(Dir.pwd, '.timetrap-sheet')\n        File.read(dotfile).chomp if File.exist?(dotfile)\n      end\n    end\n  end\nend\n```\n\nCommands\n--------\n\n**archive**\n  Archive the selected entries (by moving them to a sheet called ``_[SHEET]``)\n  These entries can be seen by running ``t display _[SHEET]``.\n\n  usage: ``t archive [--start DATE] [--end DATE] [--grep REGEX] [SHEET]``\n\n**backend**\n  Run an interactive database session on the timetrap database. Requires the\n  sqlite3 command.\n\n  usage: ``t backend``\n\n**configure**\n  Create a config file at  ``~/.timetrap.yml`` or ``ENV['TIMETRAP_CONFIG_FILE']`` if\n  one doesn't exist.  If one does exist, update it with new\n  configuration options preserving any user overrides. Prints path to config\n  file.  This file may contain ERB.\n\n  usage: ``t configure``\n\n**display**\n  Display a given timesheet. If no timesheet is specified, show the current\n  timesheet. If ``all`` is passed as SHEET display all timesheets. If ``full``\n  is passed as SHEET archived timesheets are displayed as well. Accepts an\n  optional ``--ids`` flag which will include the entries' ids in the output.\n  This is useful when editing an non running entry with ``edit``.\n\n  Display is designed to support a variety of export formats that can be\n  specified by passing the ``--format`` flag.  This currently defaults to\n  text.  iCal, csv, json, and numeric id output are also supported.\n\n  Display also allows the use of a ``--round`` or ``-r`` flag which will round\n  all times in the output. See global options below.\n\n  usage: ``t display [--ids] [--round] [--start DATE] [--end DATE] [--format FMT] [--grep REGEX] [SHEET | all | full]``\n\n**edit**\n  Insert a note associated with the an entry in the timesheet, or edit the\n  start or end times.  Defaults to the current entry, or previously running\n  entry. An ``--id`` flag can be passed with the entry's id (see display.)\n\n  usage: ``t edit [--id ID] [--start TIME] [--end TIME] [--append] [NOTES]``\n\n**in**\n  Start the timer for the current timesheet. Must be called before out.  Notes\n  may be specified for this period. This is exactly equivalent to\n  ``t in; t edit NOTES``. Accepts an optional --at flag.\n\n  usage: ``t in [--at TIME] [NOTES]``\n\n**kill**\n  Delete a timesheet or an entry.  Entries are referenced using an ``--id``\n  flag (see display).  Sheets are referenced by name.\n\n  usage: ``t kill [--id ID] [TIMESHEET]``\n\n**list**\n  List the available timesheets.\n\n  usage: ``t list``\n\n**now**\n  Print a description of all running entries.\n\n  usage: ``t now``\n\n**out**\n  Stop the timer for the current timesheet. Must be called after in. Accepts an\n  optional --at flag. Accepts an optional TIMESHEET name to check out of a\n  running, non-current sheet. Will check out of all running sheets if the\n  auto_checkout configuration option is enabled.\n\n  usage: ``t out [--at TIME] [TIMESHEET]``\n\n**resume**\n  Start the timer for the current time sheet for an entry. Defaults to the\n  active entry.\n\n  usage: ``t resume [--id ID] [--at TIME]``\n\n**sheet**\n  Switch to a timesheet creating it if necessary. The default timesheet is\n  called \"default\". When no sheet is specified list all existing sheets.\n  The special timesheet name '-' will switch to the last active sheet.\n\n  usage: ``t sheet [TIMESHEET]``\n\n**today**\n  Shortcut for display with start date as the current day\n\n  usage: ``t today [--ids] [--format FMT] [SHEET | all]``\n\n**yesterday**\n  Shortcut for display with start and end dates as the day before the current\n  day\n\n  usage: ``t yesterday [--ids] [--format FMT] [SHEET | all]``\n\n**week**\n  Shortcut for display with start date set to a day of this week. The default\n  start of the week is Monday.\n\n  usage: ``t week [--ids] [--end DATE] [--format FMT] [TIMESHEET | all]``\n\n**month**\n  Shortcut for display with start date set to the beginning of this month\n  (or a specified month) and end date set to the end of the month.\n\n  usage: ``t month [--ids] [--start MONTH] [--format FMT] [TIMESHEET | all]``\n\n\n### Global Options\n\n**rounding**\n  passing a ``--round`` or ``-r`` flag to any command will round entry start\n  and end times to the closest 15 minute increment.  This flag only affects the\n  display commands (e.g. display, list, week, etc.) and is non-destructive.\n  The actual start and end time stored by Timetrap are unaffected.\n\n  See `configure` command to change rounding increment from 15 minutes.\n\n**non-interactive**\n  passing a ``--yes`` or ``-y`` flag will cause any command that requires\n  confirmation (such as ``kill``) to assume an affirmative response to any\n  prompt. This is useful when timetrap is used in a scripted environment.\n\n### Configuration\n\nConfiguration of Timetrap's behavior can be done through an ERB interpolated\nYAML config file.\n\nSee ``t configure`` for details.  Currently supported options are:\n\n  **round_in_seconds**: The duration of time to use for rounding with the -r flag\n\n  **database_file**: The file path of the sqlite database\n\n  **append_notes_delimiter**: delimiter used when appending notes via\n                              `t edit --append`\n\n  **formatter_search_paths**: an array of directories to search for user\n                              defined fomatter classes\n\n  **default_formatter**: The format to use when display is invoked without a\n                         `--format` option\n\n  **default_command**: The default command to invoke when you call `t`\n\n  **auto_checkout**: Automatically check out of running entries when you check\n                     in or out\n\n  **require_note**: Prompt for a note if one isn't provided when checking in\n\n  **auto_sheet**: Which auto sheet module to use.\n\n  **auto_sheet_search_paths**: an array of directories to search for user\n                              defined auto_sheet classes\n\n  **note_editor**: The command to start editing notes. Defaults to false which\n               means no external editor is used. Please see the section below\n               on Notes Editing for tips on using non-terminal based editors.\n               Example: note_editor: \"vim\"\n\n  **week_start**: The day of the week to use as the start of the week for t week.\n\n### Autocomplete\n\nTimetrap has some basic support for autocomplete in bash and zsh.\nThere are completions for commands and for sheets.\n\n**HINT** If you don't know where timetrap is installed,\nhave a look in the directories listed in `echo $GEM_PATH`.\n\n#### bash\n\nIf it isn't already, add the following to your `.bashrc`/`.bash_profile`:\n\n```bash\nif [ -f /etc/bash_completion ]; then\n  . /etc/bash_completion\nfi\n```\n\nThen add this to source the completions:\n\n```bash\nsource /path/to/timetrap-1.x.y/gem/completions/bash/timetrap-autocomplete.bash\n```\n\n#### zsh\n\nIf it isn't already, add the following to your `.zshrc`:\n\n```bash\nautoload -U compinit\ncompinit\n```\n\nThen add this to source the completions:\n\n```bash\nfpath=(/path/to/timetrap-1.x.y/gem/completions/zsh $fpath)\n```\n\n#### Notes editing\n\nIf you use the note_editor setting, then it is possible to use\nan editor for writing your notes. If you use a non terminal based\neditor (like atom, sublime etc.) then you will need to make timetrap\nwait until the editor has finished. If you're using the \"core.editor\"\nflag in git, then it'll be the same flags you'll use.\n\nAs of when this command was added, for atom you would use `atom --wait`\nand for sublime `subl -w`. If you use a console based editor (vim, emacs,\nnano) then it should just work.\n\nDevelopment\n-----------\n\nGet `bundler` in case you don't have it:\n\n    gem install bundler\n\nSet a local path for the project's dependencies:\n\n    bundle config set --local path 'vendor/bundle'\n\nInstall timetrap's dependencies:\n\n    bundle install\n\nNow you can run your local timetrap installation:\n\n    bundle exec t\n\nOr run the test suite:\n\n    bundle exec rspec\n\nSpecial Thanks\n--------------\n\nThe initial version of Timetrap was heavily inspired by Trevor Caira's\nTimebook, a small python utility.\n\nOriginal Timebook available at:\nhttps://github.com/trevorc/timebook\n\nBugs and Feature Requests\n--------\nSubmit to http://github.com/samg/timetrap/issues\n\n[harvest]:          http://www.getharvest.com\n[timetrap-harvest]: https://github.com/dblandin/timetrap-harvest\n[dblandin]:         https://github.com/dblandin\n[toggl]:            https://toggl.com\n[timetrap-toggl]:   https://github.com/naps62/timetrap-toggl\n[naps62]:           https://github.com/naps62\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamg%2Ftimetrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamg%2Ftimetrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamg%2Ftimetrap/lists"}