Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add runCommand function to Go template syntax + add support for templates in git branchPrefix setting #4438

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ruudk
Copy link

@ruudk ruudk commented Mar 31, 2025

  • Cheatsheets are up-to-date (run go generate ./...)
  • Code has been formatted (see here)
  • Tests have been added/updated (see here for the integration test guide)
  • Text is internationalised (see here)
  • If a new UserConfig entry was added, make sure it can be hot-reloaded (see here)
  • Docs have been updated if necessary
  • You've read through your own file changes for silly mistakes etc

This makes it possible to use date and time in initial values like this:

initialValue: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'

Screenshot 2025-04-02 at 19 41 40@2x

I want to use this to configure my BranchPrefix like this:

git:
  branchPrefix: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'

Screenshot 2025-04-02 at 19 43 06@2x

@ruudk
Copy link
Author

ruudk commented Apr 2, 2025

@jesseduffield I know you're probably busy, but do you have any advice on where to add the tests? Then I can finish the PR.

Thanks for this amazing program, I love it!

@stefanhaller
Copy link
Collaborator

Happy to step in for Jesse, but I don't understand what you're trying to do. 😅

I understand the example with the initialValue: in custom command prompts; that's fine with me. Just one detail: the function takes an argument of time.Time, but the .Now property seems to be the only way to get one. How can the function ever be called differently than formatDate .Now? I guess my point is whether we should instead have something like currentFormattedDate "2006" or something along those lines, so that we don't pretend to offer more flexibility than we actually do.

What I don't understand is the branchPrefix example. We don't expand templates in that context, or do we? Are you planning on adding that; if so, how? Your exported formatDate function is very specific to custom commands.

@ruudk
Copy link
Author

ruudk commented Apr 2, 2025

I understand the example with the initialValue: in custom command prompts; that's fine with me. Just one detail: the function takes an argument of time.Time, but the .Now property seems to be the only way to get one. How can the function ever be called differently than formatDate .Now? I guess my point is whether we should instead have something like currentFormattedDate "2006" or something along those lines, so that we don't pretend to offer more flexibility than we actually do.

That's a good suggestion. What about formatCurrentDate or formatCurrentDateTime?

What I don't understand is the branchPrefix example. We don't expand templates in that context, or do we? Are you planning on adding that; if so, how? Your exported formatDate function is very specific to custom commands.

You're right. My idea was to work on adding support for that next, in a similar way.

Before this PR, I had this custom command to create a branch (using git town)

      - context: "files, localBranches, commits, subCommits"
        key: "a"
        description: "Git Town Hack"
        prompts:
          - type: "input"
            title: "Branch name (ruudk/yyyy/m will be added automatically)."
            key: "BranchName"
        command: 'git town hack "ruudk/$(date +"%Y/%-m")/{{.Form.BranchName}}"'
        stream: true

As you can see, the title now has to say something like ruudk/yyyy/m while it would have been nicer to see the actual year and month.

Even better, to use it in initialValue so that you can modify it, for situations where you don't want the prefix.

With the current PR, you can use the formatted dates in the initialValue and title of a custom command.

@ruudk
Copy link
Author

ruudk commented Apr 2, 2025

Screenshot 2025-04-02 at 19 41 40@2x

Based on:

      - context: "files, localBranches, commits, subCommits"
        key: "a"
        description: "Git Town Append"
        prompts:
          - type: "input"
            title: 'Branch name to append from "{{.CheckedOutBranch.Name}}"'
            key: "BranchName"
            initialValue: 'ruudk/{{ formatCurrentDate "2006/1" }}/'
        command: 'git town append {{.Form.BranchName | quote}}'
        stream: true
        loadingText: "Appending"

@ruudk
Copy link
Author

ruudk commented Apr 2, 2025

Also made the branchPrefix work:

Screenshot 2025-04-02 at 19 43 06@2x

based on:

git:
  branchPrefix: 'ruudk/{{ formatCurrentDate "2006/1" }}/'

@ruudk ruudk changed the title Add formatDate function to Go template syntax Add formatCurrentDate function to Go template syntax + add support for templates in git branchPrefix setting Apr 2, 2025
@stefanhaller
Copy link
Collaborator

Ok, now I understand better what you are trying to do.

I do have to wonder if it would be better to expose a general runCommand (or exec or some such) function that would allow you to do initialValue: ruudk/{{ runCommand "date +'%Y/%-m'" }}/. Isn't that a lot more flexible than exposing bespoke functions for whatever thing users want to put in their branch names?

@ruudk
Copy link
Author

ruudk commented Apr 2, 2025

That would be more flexible for sure! Do you think it's hard to do? I can give it a try if you steer me in the right direction

@stefanhaller
Copy link
Collaborator

I don't think it would be hard at all; the only tricky thing is to decide how to handle errors. And maybe whether it's a problem if the command returns multi-line output; we could consider replacing line feeds with spaces (like echo does), or at least trim trailing newlines.

Anyway, something like this in your template.FuncMap should work (haven't tried it though):

	"runCommand": func(command string) string {
		output, err := self.c.Git().Custom.RunWithOutput(command)
		if err != nil {
			return err.Error() // is this the best way to handle errors?
		}
		return output

@ruudk
Copy link
Author

ruudk commented Apr 3, 2025

It's working 🎉

branchPrefix: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'
initialValue: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'

@stefanhaller
Copy link
Collaborator

Nice! Now to your question about tests and documentation. It's true that the quote function has neither tests nor documentation. I'm not sure it needs tests, but adding a bit of documentation would be nice; this could simply go somewhere in Custom_Command_Keybindings.md (it's used in a few examples there). Then you can add documentation for the runCommand function next to it.

As for tests: yes, it would be good to have some for your new function, and I think integration tests would be best. For custom commands you could use pkg/integration/tests/custom_commands/selected_path.go as an example, yours would probably be even simpler. For the branch prefix you could take pkg/integration/tests/commit/new_branch_with_prefix.go as an example; for some reason this is in tests/commit which doesn't make a lot of sense, you could move this to tests/branch as a cleanup commit first.

Also, can you please squash the commits, the commit history is not reviewable like this.

@ruudk
Copy link
Author

ruudk commented Apr 3, 2025

Thanks for the guidance @stefanhaller, I'll follow up later with the changes.

@ruudk ruudk force-pushed the format-date branch 2 times, most recently from 76b40ae to 0e32c5e Compare April 4, 2025 06:25
@ruudk
Copy link
Author

ruudk commented Apr 4, 2025

@stefanhaller I applied your feedback and added the docs and tests. Could you approve the workflow so we can see if it works correctly? Thanks!

@ruudk ruudk changed the title Add formatCurrentDate function to Go template syntax + add support for templates in git branchPrefix setting Add runCommand function to Go template syntax + add support for templates in git branchPrefix setting Apr 4, 2025
Copy link
Collaborator

@stefanhaller stefanhaller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice; I pushed a few fixups, I sometimes find this easier than explaining what I would like to see changed. (In one case I did both now though. 😄)

Feel free to squash them if you agree.

The final thing to do would be to update the PR description, it is out of date with what we are doing here now. This is important because it will end up in the commit message of the merge commit.

@stefanhaller stefanhaller added the enhancement New feature or request label Apr 4, 2025
@stefanhaller stefanhaller mentioned this pull request Apr 4, 2025
7 tasks
@ruudk
Copy link
Author

ruudk commented Apr 4, 2025

@stefanhaller Thank you! I updated the PR description and fixed up all the commits.

ruudk added 2 commits April 4, 2025 14:30
This makes it possible to use date and time in initial values like this:

```yaml
initialValue: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'
```

I want to use this to configure my BranchPrefix like this:

```yaml
git:
  branchPrefix: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'
```
@ruudk
Copy link
Author

ruudk commented Apr 4, 2025

@stefanhaller You did a rebase? Let's see if it's still green.

@stefanhaller
Copy link
Collaborator

I only fixed the subject of the first commit, and the description of one of the tests. Shouldn't have changed anything.

@stefanhaller
Copy link
Collaborator

I'll wait with merging until @jesseduffield had a chance to look at the approach we're taking here (just in case), and also to see if the folks over in #4183 have anything to say about it. They were trying to solve the same problem there, but with a different approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants