Odd interaction with other libraries using flag behind the scenes
Opened this issue · 3 comments
Hi,
You may be interested in this ticket. There is an odd interaction when another library (in this case, the zero-downtime restart library endless) uses flags behind the scene to sneak in its own flags. A number of oddities crop up. To demonstrate, use this code. Compile the sample code to flagtest, and the demonstrations are below:
- The using application's flags become illegal and generate an error if provided (
./flagtest -param
) - The library's flags become illegal and generate an error if provided (
./flagtest -continue
) - Which help message displayed differs depending on which flags are missed or provided (see the two examples above -- two different messages)
The behavior is the same whether the flag is defined globally, or in the scope of the main()
function.
I do not know whether this is particular to fvbock/endless + namsral/flag, or if other flag-using libraries have the same problem with namsral/flag; I haven't investigated it yet. I thought you might like to be aware of the issue.
Hi,
Confirmed that it is not an issue with endless. Minimal test code:
Recommended directory structure:
test/
main.go
testlib/
testlib.go
Then in test
:
go build -o test test.go
./test -param
(application flags are illegal)./test -libarg
(library flags also illegal)
I'm certain this arises from the use of different flag libraries, but I am unable to recommend a fix at this time.
A library should not mandate the user interface of an application unless it is an UI library.
The flag
package is a UI library, the testlib
package in your example is not.
It is best practice to pass options in libraries through a public function. Take for example the database/sql
package:
import "database/sql"
func main() {
db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
…
Hi,
The code illustrates that the flag library hijacks the interpretation of flags globally, preventing it from being used with other (possibly UI, according to your terminology) libraries that access flags.
I can accept that this is a fundamental design flaw of the flags (both core and namsral versions) libraries, which access shared global state and interpret it as a rule set. It prevents composition of UI libraries for doing things like what endless
attempts, which is attempting to re-fork the executable and pass in an argument indicating a restart rather than a virgin launch. Endless does not use namsral/flag for this; it uses the core library. The core library and namsral/flag can not both be used within the same application. It is as if using a Postgres SQL DB library implicitly prevented you from using a MySQL DB library because they both accessed some global shared state and read the configurations as being incompatible.
So: while I still see this as a fundamental design flaw, I don't disagree with closing the ticket as it isn't the namsral/flag's design flaw. It's just unfortunate that it inherits the flaw.