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

drop glog from the unquote and parser packages #77

Merged
merged 2 commits into from
Jan 30, 2023

Conversation

mvdan
Copy link
Contributor

@mvdan mvdan commented Nov 23, 2022

(see commit messages - please do not squash)

Fixes #70.

cc @stapelberg @kssilveira

@mvdan
Copy link
Contributor Author

mvdan commented Nov 23, 2022

This is an alternative to #75. Note that, unlike the other patch, this avoids any breaking changes where possible.

There is one minor breaking change. Any parser users which did want glog should now pass it along explicitly, just like I'm doing in cmd/txtpbfmt. It can't be kept there by default, because we want to drop the hard dependency in the first place.

@kssilveira
Copy link
Member

I think this will work, I will comment on the diff.

parser/parser.go Outdated
@@ -163,7 +173,9 @@ func Format(in []byte) ([]byte, error) {
func FormatWithConfig(in []byte, c Config) ([]byte, error) {
addMetaCommentsToConfig(in, &c)
if c.Disable {
log.Infoln("Ignored file with 'disable' comment.")
if c.Logger != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Can we avoid checking for nil in every use, and instead make every public function set logger to an internal noopLogger (that doesn't do anything) if logger is nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's no good place to have such a read-write field to set to a noopLogger. The parser type isn't enough, because we need to log from some funcs which don't hang off the parser.

I assume you didn't like the repetition, so I set up two methods on the config type to deduplicate the nil checks. I don't think the nil checks harm performance, because an interface call always has to check whether the interface is nil or not.

@@ -322,9 +334,9 @@ func parseWithMetaCommentConfig(in []byte, c Config) ([]*ast.Node, error) {
if err != nil {
return nil, err
}
if p.log {
Copy link
Member

Choose a reason for hiding this comment

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

Some logs, like this one, have V(2) by default, but others don't, so we need to somehow make the logger differentiate between "default verbosity" and "extra verbosity", such as having a boolean EnableExtraVerbosity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't even notice that there were actually three log levels, not just two. There's Errorf, Infof, and the verbose Infof. Quite confusing to be honest, but I'm also not used to glog :) Naively, I would call the third a Debugf in the interface.

I've taken you up on the extra boolean for the sake of unblocking the PR.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I was wrong, there is only one verbosity, the reason for the separate if statement is the performance:

https://pkg.go.dev/github.com/golang/glog#V

The second form is shorter but the first is cheaper if logging is off because it does not evaluate its arguments.

Please delete ExtraVerbosity and instead use something like if p.config.log() implemented as c.Logger.IsVerbose() (c *Config) implemented as return bool(l.Verbose) (l parserLog).

I've checked that this compiles using https://go.dev/play/p/e8pZ220VUGK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So we're ending up with this logging interface?

// Logger is a small glog-like interface.
type Logger interface {
	// Infof is used for informative messages, for testing or debugging.
	Infof(format string, args ...interface{})

	// Errorf is used for non-fatal errors, such as invalid meta comments.
	Errorf(format string, args ...interface{})

	// IsVerbose reports whether Infof logs are being printed out.
	IsVerbose() bool
}

Not opposed per se, though the interface stops being "small" or "glog-like" at that point :)

Copy link
Member

@kssilveira kssilveira left a comment

Choose a reason for hiding this comment

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

I wanted to approve only one commit, not the whole pull request, sorry.

@@ -322,9 +334,9 @@ func parseWithMetaCommentConfig(in []byte, c Config) ([]*ast.Node, error) {
if err != nil {
return nil, err
}
if p.log {
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I was wrong, there is only one verbosity, the reason for the separate if statement is the performance:

https://pkg.go.dev/github.com/golang/glog#V

The second form is shorter but the first is cheaper if logging is off because it does not evaluate its arguments.

Please delete ExtraVerbosity and instead use something like if p.config.log() implemented as c.Logger.IsVerbose() (c *Config) implemented as return bool(l.Verbose) (l parserLog).

I've checked that this compiles using https://go.dev/play/p/e8pZ220VUGK.

@kssilveira
Copy link
Member

kssilveira commented Jan 6, 2023 via email

@mvdan
Copy link
Contributor Author

mvdan commented Jan 7, 2023

Should be ready now. I went for InfoLevel() bool rather than IsVerbose() bool, to clarify that it returns whether the info level at Infof is enabled or not. The notion of "verbose" seemed confusing to me, as it could mean other things such as how detailed the logs should be, rather than whether they are printed or not.

mvdan added 2 commits January 23, 2023 11:12
We can log straight into testing.T.
Now that glog.Errorf calls are returned as error values,
we can replace glog.Verbose.Infof calls with an interface.

All calls go through a logger in the config.
By default the logger is nil, which disables logging,
so we have nil checks when logging.

Note that the library uses a nil check on the logger to tell whether or
not it can avoid constructing the log messages.
We don't need a method like "IsInfoLevel" or "IsEnabled",
since the interface only knows how to log at the info level.

With that in mind, keep the behavior in cmd/txtpbfmt unchanged;
it now passes log.V(2) in the config if its level is enabled.

Fixes protocolbuffers#70.
@mvdan
Copy link
Contributor Author

mvdan commented Jan 23, 2023

Since the Errorf PR was merged (thanks @kssilveira!), I've now rebased and updated this PR accordingly.

The Errorf method is gone, as it's no longer needed. And I've also removed InfoLevel - since we now only need a single logger method, we can check that the logger is non-nil to construct log messages.

@mvdan
Copy link
Contributor Author

mvdan commented Jan 23, 2023

We could also go further and have Logger be just a func signature type, but I think that could be a bit limiting in the future.

@kssilveira
Copy link
Member

I will accept this, thanks!

@mvdan
Copy link
Contributor Author

mvdan commented Jan 26, 2023

Excellent, let me know if I can help to get this merged :)

@copybara-service copybara-service bot merged commit 765cbae into protocolbuffers:master Jan 30, 2023
@mvdan
Copy link
Contributor Author

mvdan commented Jan 30, 2023

FYI @kssilveira @stapelberg, this was merged with a change from interface{} to any - which was never in my PR, as far as I can tell. That broke the build, as any requires go 1.18 or later in your go.mod. Master's build appears to be broken for now.

@kssilveira
Copy link
Member

Yes, sorry, fixing.

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.

Please remove the hard dependency on glog
2 participants