import a "main" package

8,034 views
Skip to first unread message

Manlio Perillo

unread,
Dec 13, 2016, 11:19:15 AM12/13/16
to golang-nuts
This is something that I asked in the past, but now it is a feature that I probably need for a project.

I have a main package with some data fixtures, stored in the package assets directory.
I want to implement a Go tool that, given a package importpath and a Data Source Name
(not necessarily an SQL database), loads the data fixtures in the database.

Each fixture file is named after the name of a Go struct, so the tool will generate, build and run a Go
source where the package is imported, the data fixture is decoded into a Go variable, and then
saved in the database.

This is easy, but the problem is that a main package can not be imported.
Of course I can move the related code to a normal package; and this may also improve the code organization.

However I think that there is no reason why a "main" package should not be importable, to the point that
I think that the fact that a "main" package is not importable is an "exception" implemented in the Go tool.

Is this true?


Thanks  Manlio

Jan Mercl

unread,
Dec 13, 2016, 11:34:24 AM12/13/16
to Manlio Perillo, golang-nuts
On Tue, Dec 13, 2016 at 5:19 PM Manlio Perillo <manlio....@gmail.com> wrote:

> However I think that there is no reason why a "main" package should not be importable, to the point that
> I think that the fact that a "main" package is not importable is an "exception" implemented in the Go tool.

The package dependency graph must be (1) an acyclic graph, ie. a tree with (2) main package at its root, for obvious reasons. Importing main violates both of the properties.
--

-j

adon...@google.com

unread,
Dec 13, 2016, 12:13:08 PM12/13/16
to golang-nuts, manlio....@gmail.com
Packages named main are importable, just like any other.  Occasionally this is useful when you want to write tests for members of that package.  Of course, the main function is not exported.


Jan Mercl

unread,
Dec 13, 2016, 12:18:22 PM12/13/16
to adon...@google.com, golang-nuts, manlio....@gmail.com
On Tue, Dec 13, 2016 at 6:13 PM adonovan via golang-nuts <golan...@googlegroups.com> wrote:

> Packages named main are importable, just like any other. Occasionally this is useful when you want to write tests for members of that package. Of course, the main function is not exported.

I recall running into this limitation years ago. Was it always possible? Or do I have a false remembrance?

--

-j

Manlio Perillo

unread,
Dec 13, 2016, 1:48:23 PM12/13/16
to golang-nuts, manlio....@gmail.com, adon...@google.com
You are right, thanks!
For some reason I was sure it was not possible; was this feature always available?

This will make the implementation of my data fixture loader much more easy.


Manlio 

Dave Cheney

unread,
Dec 13, 2016, 2:16:49 PM12/13/16
to golang-nuts, adon...@google.com, manlio....@gmail.com
There were some difficulties in writing external tests for a main package, ie package main_test, but they were resolved a long time ago.

roger peppe

unread,
Dec 14, 2016, 11:17:14 AM12/14/16
to Jan Mercl, golang-nuts, manlio....@gmail.com, Alan Donovan

It is not possible to import main packages in general, although it does seem to be possible to import a main package from external tests in the same directory.

tst.go: 9:3: import "local/cmd/test" is a program, not an importable package

I'm not why this restriction exists.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alan Donovan

unread,
Dec 14, 2016, 11:41:06 AM12/14/16
to roger peppe, Jan Mercl, golang-nuts, Manlio Perillo
On 14 December 2016 at 11:16, roger peppe <rogp...@gmail.com> wrote:

It is not possible to import main packages in general, although it does seem to be possible to import a main package 

Ah, that explains it.  Thanks for the correction.  Clearly I never tried importing a main package from anywhere but its tests.  

Manlio Perillo

unread,
Dec 15, 2016, 2:43:45 PM12/15/16
to golang-nuts, 0xj...@gmail.com, manlio....@gmail.com, adon...@google.com
However importing a main package in another main package works.
To summarize:

1) importing a main package in a external test is supported
2) importing a main package in a main package is supported
3) importing a main package in a non main package is not supported

This seems reasonable to me, however AFAIK it is not documented.

Manlio
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

beac...@morris.umn.edu

unread,
Sep 25, 2017, 12:18:29 AM9/25/17
to golang-nuts
The fact that importing a main package in a non main-package isn't supported ought to be in the Go spec.

Ian Lance Taylor

unread,
Sep 25, 2017, 12:29:16 AM9/25/17
to beac...@morris.umn.edu, golang-nuts
On Sun, Sep 24, 2017 at 5:33 PM, <beac...@morris.umn.edu> wrote:
>
> The fact that importing a main package in a non main-package isn't supported
> ought to be in the Go spec.

Yes, probably. Want to open an issue about it at https://golang.org/issue ?

Technically, from the language perspective, I think the current
implementation forbids literally `import "main"`. It permits
importing a package whose package name is "main", as long as a
different path is used to import it. The go tool may impose other
restrictions--offhand I don't recall--but those restrictions, if any,
don't necessarily belong in the language spec.

Ian

Alex Buchanan

unread,
Oct 24, 2017, 11:14:25 PM10/24/17
to golang-nuts
Is there documentation (or other) explaining why the main package must have name "main" and may not be imported? Is this an important simplification for the compiler?

I'd love it if a single "go get <url>" represented both my library root and my command line binary.

Ian Lance Taylor

unread,
Oct 25, 2017, 12:32:27 AM10/25/17
to Alex Buchanan, golang-nuts
On Tue, Oct 24, 2017 at 8:14 PM, Alex Buchanan <buchan...@gmail.com> wrote:
>
> Is there documentation (or other) explaining why the main package must have
> name "main" and may not be imported? Is this an important simplification for
> the compiler?

The language spec says that the main package must have the name main.
I guess we could use other mechanisms but that one seems reasonable to
me.

cmd/compile prohibiting `import "main"` is a moderately important
simplification because cmd/compile uses the import path to set symbol
names, and for the main package it uses "main". If cmd/compile
permitted `import "main"` then there would be two different packages
with the same import path, which can't work. So it would have to use
something else for the imported "main", but what?

Note that cmd/compile does not prohibit importing a package named
"main" if the path used to import that package is not specifically
"main". But I think the go tool does prohibit that, and I think that
is simply to be less surprising to most people.

Ian

Alex Buchanan

unread,
Oct 25, 2017, 1:03:28 AM10/25/17
to Ian Lance Taylor, Alex Buchanan, golang-nuts
Interesting, thanks. Let me try to clarify my idea with some simple code:

// file lives at github.com/buchanae/foobar/foobar.go
package foobar

func Foobar() string {
return "foobar"
}

func main() {
print(Foobar())
}

This file exports both a function to be used as a library, and a main function which would be compiled into a command line utility. In order to use the library, you'd write `import "github.com/buchanae/foobar"; foobar.Foobar()`. In order to use the command line tool, you'd run `go get github.com/buchanae/foobar` and run `foobar` on the command line. There's no `import "main"` or package named main in this example. The compiler would need to look for a main function in the starting package and perhaps name symbols using the fully qualified package name. Also, packages in the "foobar" tree would not be importing the root, so there are no import cycles.

I'm not sure it's a good idea, but it was my instinct when I started writing Go, and feels like it would have simplified the organization and documentation of some projects which have a separate "go get <url>" for the library vs the CLI command.

Hope that made sense. Probably too late to be writing about such things :)

Dan Kortschak

unread,
Oct 25, 2017, 1:22:54 AM10/25/17
to Alex Buchanan, Ian Lance Taylor, Alex Buchanan, golang-nuts
The spec does preclude that since there must be a `package main`.

https://golang.org/ref/spec#Program_execution

Ian Lance Taylor

unread,
Oct 25, 2017, 10:35:50 AM10/25/17
to Alex Buchanan, Alex Buchanan, golang-nuts
On Tue, Oct 24, 2017 at 10:02 PM, Alex Buchanan <buch...@ohsu.edu> wrote:
> Interesting, thanks. Let me try to clarify my idea with some simple code:
>
> // file lives at github.com/buchanae/foobar/foobar.go
> package foobar
>
> func Foobar() string {
> return "foobar"
> }
>
> func main() {
> print(Foobar())
> }
>
> This file exports both a function to be used as a library, and a main function which would be compiled into a command line utility. In order to use the library, you'd write `import "github.com/buchanae/foobar"; foobar.Foobar()`. In order to use the command line tool, you'd run `go get github.com/buchanae/foobar` and run `foobar` on the command line. There's no `import "main"` or package named main in this example. The compiler would need to look for a main function in the starting package and perhaps name symbols using the fully qualified package name. Also, packages in the "foobar" tree would not be importing the root, so there are no import cycles.
>
> I'm not sure it's a good idea, but it was my instinct when I started writing Go, and feels like it would have simplified the organization and documentation of some projects which have a separate "go get <url>" for the library vs the CLI command.

Personally I think it's better to separate the library and the
command. That is particularly true if the command takes any flags.

> Hope that made sense. Probably too late to be writing about such things :)

Indeed. It's an interesitng idea but this isn't something that is
going to change at this point.

Ian
Reply all
Reply to author
Forward
0 new messages