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

Premature error fix for issue #353 #357

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

Omnikron13
Copy link

As per #353, commands were failing due to unavailable data

How did you test this change?

Duplicate a hotkey command akin to that reported as failing to confirm.
Grepped the source for elements I needed to remove/modify.

Ran go test suite, manually verified command now successfully executes.

Omnikron13 and others added 3 commits April 18, 2024 00:00
Removes an assumption that specific data/keys are required by the bound
command.

Instead `Template.Option()` is used to tell the Template to error out if
and when it actually encounters a key it needs.
Unfortuneatly it seems the Template options are a little lacking, and
I don't believe can be persuaded to accept zero values or even nil
pointers as 'missing' values.

The struct in question, `PRCommandTemplateInput`, appears to have no use
elsewhere however, so was easily replaced with a map, which I hope
serves your needs for the near future at least.
}

cmd, err := template.New("keybinding_command").Parse(commandTemplate)
if err != nil {
log.Fatal("Failed parse keybinding template", err)
}

// Set the command to error out if required input (e.g. RepoPath) is missing
cmd = cmd.Option("missingkey=error")
Copy link
Owner

Choose a reason for hiding this comment

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

Can we remove the log.Fatal on line 128 and instead return a tea.Cmd?
Use a more appropriate message though :)

		return func() tea.Msg {
			return constants.ErrMsg{Err: fmt.Errorf("Failed to find local path for repo %s", repoName)}
		}

Copy link
Author

Choose a reason for hiding this comment

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

Hm, no I don't think that is the right approach...

Templates can be pretty complex. They can be recursively nested into a tree structure, be populated out in multiple stages by different calls to the Execute functions with different sources and types of data, potentially across multiple goroutines simultaneously.

The values passed in can be chained on one another (I presume to key into a map or struct which is another value passed in). They can be (zero-argument*) functions/methods that implements some kind of literal piping with | to produce the final substitution. I believe they may return a 2nd err return which will be propagated out ultimately. ( * there is a manner in which the final piece of data passed in, can have arguments, but honestly there's a lot going on in there, and a lot of ways and reasons it might spit errors at you. )

There's definitely cases where it will error on 'empty or incomplete' template, other internal/syntactic issues, unexpected data types or values, etc...

The Option that this branch sets is essentially stating;

'This is our final pass over this Template, and we will consider any dangling placeholders left unfilled as also being errors.

While trivial current uses seem in the source to suggest the other values passed in are reliable, future additions may not be. The writer of the template might typo key/member names, screw up their syntax, etc. and cause an unrelated error, or the template may have its own reasons to.

It could certainly complicate the error handing if you want to tease any nuance out, though I think you may be able to simple propagate the errors, or wrapped versions of them, up to wherever and how that gets communicated to the user.

@Omnikron13
Copy link
Author

With that said, I think there is perhaps a fair bit of quite aggressive reworking of that source file that is low-hanging fruit to improve flexibility and provide a broader framework for new features, screens etc.

I'll put a little work in on that in another branch, might make it easier to work out the ideal was to act here.

@Omnikron13
Copy link
Author

Applying the same fixes to the issues version of function things look pretty parse when you diff the two functions::

func (m *Model) runCustomIssueCommand(commandTemplate string, |	func (m *Model) runCustomPRCommand(commandTemplate string, pr
	// A generic map is often the simplest way to pass a  |		// A generic map is a pretty easy & flexible way to p
							     >		// for sructured data, existing structs, etc. Especia
	input := map[string]any {					input := map[string]any {
		"RepoName":    issueData.GetRepoNameWithOwner |			"RepoName":    prData.GetRepoNameWithOwner(),
	  "IssueNumber": issueData.Number,		     |			"PrNumber":    prData.Number,
							     >			"HeadRefName": prData.HeadRefName,
							     >			"BaseRefName": prData.BaseRefName,
	}								}

	// Append in the local RepoPath only if it can be fou		// Append in the local RepoPath only if it can be fou
	if repoPath, ok := common.GetRepoLocalPath(input["Rep		if repoPath, ok := common.GetRepoLocalPath(input["Rep
		input["RepoPath"] =  repoPath;		     |			input["RepoPath"] = repoPath
	}								}

	cmd, err := template.New("keybinding_command").Parse(		cmd, err := template.New("keybinding_command").Parse(
	if err != nil {							if err != nil {
		log.Fatal("Failed parse keybinding template",			log.Fatal("Failed parse keybinding template",
	}								}

	// Set the command to error out if required input (e.		// Set the command to error out if required input (e.
	cmd = cmd.Option("missingkey=error")				cmd = cmd.Option("missingkey=error")

	var buff bytes.Buffer						var buff bytes.Buffer
	err = cmd.Execute(&buff, input)					err = cmd.Execute(&buff, input)
	if err != nil {							if err != nil {
		log.Fatal("Failed executing keybinding comman			log.Fatal("Failed executing keybinding comman
	}								}
	return m.executeCustomCommand(buff.String())			return m.executeCustomCommand(buff.String())
}								

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

Successfully merging this pull request may close these issues.

None yet

2 participants