git-time-metric / gtm

Simple, seamless, lightweight time tracking for Git
MIT License
973 stars 52 forks source link

Jira Smart Commits support #95

Open desaroger opened 5 years ago

desaroger commented 5 years ago

Hi! First of all, sorry if there was already another issue where this is solved. I only found the issue #72, but I think it does not solve my problem.

I need to create Smart Commits instead of Commit Notes. I solved this, as @mschenk42 suggested in #72, creating a commit-msg hook where I modify the commit message adding a new line with the format Jira expects. You can see my commit-msg and post-commit hooks.

So in short I do gtm status --total-only to get the total time and that is what I add to the commit message. And everything seems fine until I found a problem with that:

When you run gtm status --total-only you get the the time spent on all the files. But when a commit is done, only the events related with files in that commit are cleaned. This means that if I am working on a file, but I do not commit it, the time spent in that file will be added to the time of that commit, but will not be erased from the gtm folder, so in the next commit that time will (plust the new time I spent in the file) will be added also to the commit time. And to the next, and next, until I commit that file.

My solution to that problem is to clean gtm after a commit (you can see this in the post-commit hook). But this is not ideal, as I am including time in commits not relevant for them.

The solution I think would be ideal for me is a way of getting the total time spent, but only for the files that would be included in the next commit. Something like gtm status --only-staged or something like that.

Thank you very much! I love this project, I think it's very useful, thanks for creating it!

Attachments: commit-msg.txt post-commit.txt

mschenk42 commented 5 years ago

I like the idea of gtm status --only-staged. I'll tag as an enhancement. Thanks for the feedback.

devkabiir commented 5 years ago

Hi @mschenk42, I've been wanting to learn Go for some time now and I want this feature in gtm. So If it's okay with you I'd like to work on this feature. I've never written Go code before so there will be mistakes but I'm happy to take any feedback on the PR if you're up for it?

devkabiir commented 5 years ago

Hi @desaroger, here is a workaround until --only-staged is implemented.

In your commit-msg hook, before you do anything with the commit message

GTM_DIR="./.gtm"
GTM_UNSTAGED_DIR="./.gtm-unstaged"

CLEAN_PATH=(sed -e 's#/#_#g' -e 's#\\#_#g')

STAGED_FILES=$(git diff --name-only --cached | ${CLEAN_PATH[@]})

$(mkdir "$GTM_UNSTAGED_DIR")

for event in $(ls "$GTM_DIR" | grep .event); do

    FILE_NAME=$(cat $GTM_DIR/$event | ${CLEAN_PATH[@]})

    # Skipping terminal.app so it's time usage can also be included
    if [[ $STAGED_FILES != *$FILE_NAME* ]] && [ $FILE_NAME != *terminal.app* ]; then
        mv "$GTM_DIR/$event" --target-directory="$GTM_UNSTAGED_DIR"
    fi

done

TIME=$(gtm status --total-only --long-duration)

# Do something with the $TIME

This will temporarily move all the unstaged-file events out of the .gtm directory and you will only get the time for current commit.

Next in your post-commit hook, after you do gtm clean

# After gtm commit and clean

GTM_DIR="./.gtm"
GTM_UNSTAGED_DIR="./.gtm-unstaged"
if [ -d "$GTM_UNSTAGED_DIR" ]; then

    for event in $(ls "$GTM_UNSTAGED_DIR" | grep .event); do
        mv "$GTM_UNSTAGED_DIR/$event" --target-directory="$GTM_DIR"
    done

    rmdir "$GTM_UNSTAGED_DIR"
fi

this will restore the unstaged-file events back so you don't loose any time.

This workaround does not incorporate any terminal recorded time. Because if you've worked on the terminal during that commit it's probably worth including that time too.

Edit: Updated the workaround for windows/unix paths

Edit: This workaround will clean time events for files which have been partially committed git add -p. This works best when changed files are staged as a whole. This is due to the fact that gtm tracks file-level changes and not line-level.

desaroger commented 5 years ago

Wow @devkabiir!!! It's awesome! And you did it very very fast, I didn't expect to have a workaround as soon as today.

Thanks you very much to take the time to implement this. I am going to try it today.

Aside from this workaround (which is awesome), I would like to see this implemented in GTM natively! It needs to be easier than this shell-scripts you did. If I have time maybe I would try to implement it myself, if you didn't already started to implement yourself.

Thanks again for your effort!

devkabiir commented 5 years ago

@desaroger You're welcome. I will start working on the gtm implementation around this Sunday. But please feel free to start on your own. I have never programmed in Go so I will be slow to start on the implementation. We could always join our efforts.

desaroger commented 5 years ago

Mmm interesting! I have never programmed in Go too. I have another issue that I would like to implement it myself, I think it would be a better idea if you try to implement this one, and I try to implement the other one. But yeah it sounds amazing to me to join efforts and help each other if we need help.

This weekend I would try to take a chance on Go and to try to start the implementation. I would keep you in touch, please do the same if you have time.

Thanks!

devkabiir commented 5 years ago

please do the same if you have time.

Sure thing.

Look at https://github.com/git-time-metric/gtm/issues/79#issuecomment-503881802. This might help in your case as well. Most apps know or have a way to send http POST and/or GET requests. This might be a useful approach in tracking apps.

desaroger commented 5 years ago

It sounds interesting! I think it would be nice to have the terminal approach gtm record app, and also your idea of an http server as an alternative way to communicate with gtm and track events.

I will take that into account, thanks!

desaroger commented 5 years ago

Hi @devkabiir! I already did my another issue (it's in a PR), and I thought to try to do this one, if you didn't begin to implement it yourself. The thing is, I want to propose a new feature of an actual support of Jira Smart Commits, i.e. the full implementation so you don't need to modify your hooks etc, but for that I need this issue to be solved

devkabiir commented 5 years ago

@desaroger I did start working on it, kind of figured what needs to be changed.

  1. Create a new flag staged-only in status command

  2. Pass that flag to (status.go line 109) metric.Process (metric/manager.go line 32) event.Process

  3. In (event/manager.go) there create a new git.Status object using git.NewStatus from scm/git.go

  4. In (event/manager.go line 30) after the check for *.event files add another condition to check If stagedOnly flag was supplied

  5. If it was, skip files from files array using

    • read the files[i] content in var currentFileContent and loop over git.Status.Files and find a file that is currentFileContent == git.status.Files[j].path && git.status.Files[j].InStaging() true [j is the index for inner loop of git.Status.Files]
    • if there is no file in git.Status.Files that matches that condition skip files[i]
  6. After that we should have status for only stated files.

I couldn't understand how to install dependencies. there s not npm install equivalent and when I checked the wiki for golang on GitHub there were 10s of package managers 😅. So I stopped working there.

As a result of this, I couldn't actually test it. Feel free to try it yourself

desaroger commented 5 years ago

Hi!! For some reason I didn't get any notification of your response!! I thought you were busy. Today I thought it was so many time ago, so I checked and saw your response. Sorry!!

Okk, I will try to implement it. Thanks!!

PS: I was struggling too with the way Golang install and import dependencies haha