Open weikanglim opened 1 year ago
I love this idea.
One small note - to start with, I would prefer if we kept all our packages, with the exception of the "contracts" package inside of internal/pkg
. The contracts package should be external because it's something we want to contractually guarantee about azd
but I think the rest of the packages should remain internal. I don't think we want to give the impressions these are general purpose packages that are useful outside of the context of azd
or that might be covered by anything that looks like the Go Compatibility Promise.
As our codebase has involved with increasing complexity and functionality, we need a well-defined project layout that is able to organize things efficiently and with hopefully little confusion. I'd like the project layout to be opinionated as a result to avoid confusion.
Problem
The key problem that I've noticed is how to cleanly separate code for a given domain/subsystem such as
auth
,infra
,environment
. Taking a look at theenvironment
package, we can see the desire for the following separation:environment
package that allows for reuse of core saving/loading of anazd
environmentenvironment
package for defining internal-only components of anazd
environmentenvironment
manager that is wired up incmd
Proposal
After reviewing a few different examples, I've opted for the non-official standard project layout for Go: https://github.com/golang-standards/project-layout. The only caveat is instead of
internal/app/azd
, I'm opting forinternal/azd
to avoid the extra directory structure.Example
Let's say we're building a new subsystem for
auth
, that will be used inazd login
andazd logout
. We would do the following:azdCredential
, it would go underinternal/pkg/auth
.pkg/auth
orinternal/pkg/auth
depending on how separated it is fromazd
concepts.authManager
would go intointernal/azd/auth
. It would only be consumed by thecmd
package.login
andlogout
commands, we add the relevant code (command-design andaction
logic) intointernal/azd/cmd
.We largely avoid package naming collision, since
internal/azd/auth
is only imported bycmd
, whereas ifinternal/pkg/auth
is imported by all other packages. The only time where collisions would happen is insidecmd
, that could be reusing both theinternal/azd/auth
andinternal/pkg/auth
. In these case, we should alias
azd/authinto
azdauth`.