Code-base Refactoring Tool for Go , Move files from packages to sub packages

734 views
Skip to first unread message

jis...@hifx.co.in

unread,
Dec 13, 2016, 8:58:00 AM12/13/16
to golang-nuts


Currently my code-base have just 1 level of packages , due to the increase in number of components it would make much sense if I use sub packages.Is there any code refactoring tools I could use to achieve this.

Package_1/
      -- File 1
      -- File 2
      -- File 3
      -- File 4
Package_2/
      -- File 5
      -- File 6
      -- File 7

Target structure

Package_1
      /subpackage1
               -- File 1
               -- File 2
      /subpackage2
               -- File 3
               -- File 4
Package_2/
       /subpackage3
               -- File 5
               -- File 6
       /subpackage4
               -- File 4  

I tried gomvpkg https://godoc.org/golang.org/x/tools/cmd/gomvpkg but doesnot support moving files from same package to different package.



IMPORTANT: This is an e-mail from HiFX IT Media Services Pvt. Ltd. Its content are confidential to the intended recipient. If you are not the intended recipient, be advised that you have received this e-mail in error and that any use, dissemination, forwarding, printing or copying of this e-mail is strictly prohibited. It may not be disclosed to or used by anyone other than its intended recipient, nor may it be copied in any way. If received in error, please email a reply to the sender, then delete it from your system.

Although this e-mail has been scanned for viruses, HiFX cannot ultimately accept any responsibility for viruses and it is your responsibility to scan attachments (if any).

Before you print this email or attachments, please consider the negative environmental impacts associated with printing.

adon...@google.com

unread,
Dec 13, 2016, 10:44:01 AM12/13/16
to golang-nuts, jis...@hifx.co.in
On Tuesday, 13 December 2016 08:58:00 UTC-5, jis...@hifx.co.in wrote:


Currently my code-base have just 1 level of packages , due to the increase in number of components it would make much sense if I use sub packages.Is there any code refactoring tools I could use to achieve this?  I tried gomvpkg https://godoc.org/golang.org/x/tools/cmd/gomvpkg but doesnot support moving files from same package to different package.


We do not currently have a production-quality tool that can split a package into two or more parts, although Michael Matloob and I produced an experimental prototype of a tool (https://go-review.googlesource.com/3269) to analyze and refactor large packages such as "runtime" with complex internal dependencies.  It may be more complex than you need, but it might save you time.


Dave Cheney

unread,
Dec 13, 2016, 8:06:49 PM12/13/16
to golang-nuts, jis...@hifx.co.in
I advice caution, Go is not Java and does not permit circular dependencies. The more packages you have, the greater the chance you have of creating a circular dependency. 

adon...@google.com

unread,
Dec 14, 2016, 11:23:17 AM12/14/16
to golang-nuts, jis...@hifx.co.in
On Tuesday, 13 December 2016 20:06:49 UTC-5, Dave Cheney wrote:
I advice caution, Go is not Java and does not permit circular dependencies. The more packages you have, the greater the chance you have of creating a circular dependency. 

That's a rather dark viewpoint. Absent further information, there's nothing wrong with breaking up a large package into smaller ones, nor with using tools to help do so.  Even packages with circular dependencies can be separated by using function or interface parameters to express the interdependence.  Of course it can be overused, but so can any technique.

Dave Cheney

unread,
Dec 14, 2016, 3:09:35 PM12/14/16
to golang-nuts, jis...@hifx.co.in, adon...@google.com
It's pretty consistent with the message I've been pushing for a while; each package should have a well defined purpose, and that purpose should be enumerated by the pacakge's name. I find that when I apply that logic to my own projects, I tend to have less packages, not more.

Dave Cheney

unread,
Dec 14, 2016, 3:13:59 PM12/14/16
to golang-nuts, jis...@hifx.co.in, adon...@google.com
As an aside, I find that many programmers have a strong desire to aptly taxonomies to their work, they want to find _differences_ between two things so they can be separated and classified. I think to write successful Go, you should look for similarities and combine things with a similar purpose into a package. For example, net/http contains both http client and server facilities, because they both relate to the use of http. The prevailing style in other languages would have these placed in separate packages, one for client, one for server, and a third for things which are common to both. I think this is unnecessary.

Alan Donovan

unread,
Dec 14, 2016, 3:51:02 PM12/14/16
to Dave Cheney, golang-nuts, jis...@hifx.co.in
On 14 December 2016 at 15:13, Dave Cheney <da...@cheney.net> wrote:
For example, net/http contains both http client and server facilities, because they both relate to the use of http. The prevailing style in other languages would have these placed in separate packages, one for client, one for server, and a third for things which are common to both. I think this is unnecessary.

There's a case to be made here for the combined power of internal packages and aliases (as proposed for Go 1.8).  From the user's perspective, a single net/http package makes sense, but for the maintainers, breaking it up may lighten their burden. 

Within Google, the Go implementation of our in-house RPC system is a complex beast that would benefit from a little modularity, but we can't break the package up without changing its API.  With aliases, it would be possible to define separate internal packages for common declarations, for clients, and for servers, and then define a "facade" package that exposes just the API.

I realize you are no fan of the aliases proposal, but I think it provides real opportunities to solve problems of "programming in the large" that aren't just about temporary refactoring.

Dave Cheney

unread,
Dec 14, 2016, 4:11:28 PM12/14/16
to Alan Donovan, golang-nuts, jis...@hifx.co.in


On Thu, 15 Dec 2016, 07:50 Alan Donovan <adon...@google.com> wrote:
On 14 December 2016 at 15:13, Dave Cheney <da...@cheney.net> wrote:
For example, net/http contains both http client and server facilities, because they both relate to the use of http. The prevailing style in other languages would have these placed in separate packages, one for client, one for server, and a third for things which are common to both. I think this is unnecessary.

There's a case to be made here for the combined power of internal packages and aliases (as proposed for Go 1.8).  From the user's perspective, a single net/http package makes sense, but for the maintainers, breaking it up may lighten their burden. 

Within Google, the Go implementation of our in-house RPC system is a complex beast that would benefit from a little modularity, but we can't break the package up without changing its API.  With aliases, it would be possible to define separate internal packages for common declarations, for clients, and for servers, and then define a "facade" package that exposes just the API.

That pattern is heavily prescribed in the Ruby on Rails community to combine dozens of files into single giant class. It's not a pattern I want to see replicated in Go. 

If you want to build mega objects the pattern that k8s uses of composing a giant interface is IMO, better. 


I realize you are no fan of the aliases proposal, but I think it provides real opportunities to solve problems of "programming in the large" that aren't just about temporary refactoring.

I've retired hurt from the alias debate, but I'll bet you a steak dinner next time I'm in NYC that aliases will have caused an unexpected increase in circular dependency problems because aliases obscure the true declaration of a symbol. 

Bakul Shah

unread,
Dec 14, 2016, 5:25:34 PM12/14/16
to Alan Donovan, Dave Cheney, golang-nuts, jis...@hifx.co.in

On Dec 14, 2016, at 12:50 PM, 'Alan Donovan' via golang-nuts <golan...@googlegroups.com> wrote:

On 14 December 2016 at 15:13, Dave Cheney <da...@cheney.net> wrote:
For example, net/http contains both http client and server facilities, because they both relate to the use of http. The prevailing style in other languages would have these placed in separate packages, one for client, one for server, and a third for things which are common to both. I think this is unnecessary.

There's a case to be made here for the combined power of internal packages and aliases (as proposed for Go 1.8).  >From the user's perspective, a single net/http package makes sense, but for the maintainers, breaking it up may lighten their burden. 

Within Google, the Go implementation of our in-house RPC system is a complex beast that would benefit from a little modularity, but we can't break the package up without changing its API.  With aliases, it would be possible to define separate internal packages for common declarations, for clients, and for servers, and then define a "facade" package that exposes just the API.

(Unlike Dave Cheney) I like this. I think a key distinction is that packages are *design* objects, not runtime objects — it is how you structure a piece of sottware, separate from its runtime behavior. A hierarchical design is a good thing but we don’t usually need to model hierarchies at runtime. In any case, a user of a package need not care how it is composed. This freedom is very useful to implementers in restructuring the package guts without impacting its design interface.

Why not think about whether a  goal of allowing hierarchical design is what you (Go designers) really want and if alias and internal packages are sufficient/necessary/the right way?

roger peppe

unread,
Dec 15, 2016, 4:39:00 AM12/15/16
to Dave Cheney, Alan Donovan, golang-nuts, jis...@hifx.co.in
On 14 December 2016 at 21:11, Dave Cheney <da...@cheney.net> wrote:
> I've retired hurt from the alias debate, but I'll bet you a steak dinner
> next time I'm in NYC that aliases will have caused an unexpected increase in
> circular dependency problems because aliases obscure the true declaration of
> a symbol.

The nice thing about circular dependency issues is that there's a hard
line there
that the compiler won't let you step over. You either have a circular dependency
or you don't - there is no slippery slope.

FWIW I suspect that the use of aliased types may *reduce* the number
of circular dependency
issues because if you have smaller packages with well delineated
concerns, you're
likely to get less spurious dependencies caused by features that you don't use.

To take net/http as an example. If http.Header was just an alias to
net/textproto/MimeHeader
(it is already very close), then to declare or define a value that
uses http.Header would
need only 34 package dependencies rather than 108 because you could just use
textproto.MimeHeader directly and it would still be compatible.

In my experience it is very common for circular dependencies to arise
not because
of something in a package that I'm using directly, but because of
something semi-related that
happens to sit in the same package.

cheers,
rog.

Alan Donovan

unread,
Dec 15, 2016, 10:47:12 AM12/15/16
to roger peppe, Dave Cheney, golang-nuts, jis...@hifx.co.in
On 15 December 2016 at 04:38, roger peppe <rogp...@gmail.com> wrote:
In my experience it is very common for circular dependencies to arise
not because
of something in a package that I'm using directly, but because of
something semi-related that
happens to sit in the same package.

That's a good point.  If I had a million dollars for each time someone at Google adds a dependency on a massive package just to get at one little function within it...

Dave Cheney

unread,
Dec 15, 2016, 7:53:33 PM12/15/16
to Alan Donovan, roger peppe, golang-nuts, jis...@hifx.co.in

How do aliases help this situation? In my view they'll just obscure the true source of the declaration.

Alan Donovan

unread,
Dec 15, 2016, 9:07:54 PM12/15/16
to Dave Cheney, roger peppe, golang-nuts, jis...@hifx.co.in
On 15 December 2016 at 19:52, Dave Cheney <da...@cheney.net> wrote:

How do aliases help this situation? In my view they'll just obscure the true source of the declaration.

People in a hurry will continue to create bad dependencies whether or not we have aliases, but perhaps aliases might help us reduce the number of pairs of unrelated things that "happen to sit in the same package", as Rog said.

leon...@grabtaxi.com

unread,
Jan 26, 2018, 10:41:15 AM1/26/18
to golang-nuts
Forgive my dull, I'm not seeing the connection between the question and the following discussion. Could anyone enlight me how to resolve this (or what conclusion we have gotten from the discussion)?

Grab is hiring. Learn more at https://grab.careers

By communicating with Grab Inc and/or its subsidiaries, associate companies and jointly controlled entities (“Grab Group”), you are deemed to have consented to processing of your personal data as set out in the Privacy Notice which can be viewed at https://grab.com/privacy/

This email contains confidential information and is only for the intended recipient(s). If you are not the intended recipient(s), please do not disseminate, distribute or copy this email and notify Grab Group immediately if you have received this by mistake and delete this email from your system. Email transmission cannot be guaranteed to be secure or error-free as any information therein could be intercepted, corrupted, lost, destroyed, delayed or incomplete, or contain viruses. Grab Group do not accept liability for any errors or omissions in the contents of this email arises as a result of email transmission. All intellectual property rights in this email and attachments therein shall remain vested in Grab Group, unless otherwise provided by law.
Reply all
Reply to author
Forward
0 new messages