Hi I think one of the main struggles stems from "dependency" having two technical meanings: a) If a package a imports a package b then a depends on b. This is a priori agnostic to versions. This type of dependency is expressed by a simple import "import/path/of/b" in a's source code. b) Some set of packages might depend on an other set of packages in a specific version. This is expressed by a require directive in a go.mod file. Do not conflate these two.
One more point to takeaway: A module is a set of packages which are developed together and released together with a single version number. On Wednesday, 23 October 2019 21:09:51 UTC+2, Stuart Davies wrote: > Ok this is my current understanding. Please correct me if I am wrong. > > 1) The main purpose of a go.mod file is to indicate where the dependencies > are and their version number. > > Not exactly. There are two main purposes: - Specify the name of the module. As the name of the module is kinda prefix of all package import path living in this module this a _very_ important thing and must be done properly (especially for version >= 2.0.0 of a module). - List the direct and indirect dependencies and their (minimal) version. Dependencies in a go.mod are modules. A module is a set of packages with a common version (versioned together). Packages are identified by their import path. The "where the dependencies are" is secondary. The "wehere" can be changed by a replace directive. > 2) In my small project the 'module' is 'where the go.mod file is' (root of > webserver). > You project is badly organized or I missread your last post. The best advice is: Stop trying to get fancy until you feel comfortable working with modules. So please: Put the go.mod in the toplevel dir of your git repo an have just one go.mod file and thus just one module. (It is perfectly fine to have tens of module in a git repo but such a setup is *not helpful* while trying to understand the basics.) > > 3) A module contains packages in sub dirs (these are what we import). > a) If it has no packages in sub dirs is it still a module? > No really. This is just plain nonsense. The right way to think of modules is: A module groups packages. A module without packages is nothing sensible. A set of packages versioned together is a module. b) Import dependencies between packages in a module must use the full > module path and the package name > No. What you state here is not really wrong, it just is not right either. It is kinda the other way around. The main concept is: Packages are identifed by their import path. Package path lookup works by finding the module and the package inside the module. If you have a package in subdirectory foo/bar of your module xyz/wuz then its import path is xyz/wuz/foo/bar. (The package name is what you call the package in its first line in the source code with the "package name" declaration and this is of no concern for dependencies or importing packages). c) There should be no main() in a module > No. 100% false. You can have a lots of package main in a singel module. Remember: "A module is a group of packages versioned together." Whether these packages are "libraries" or "program" does not matter at all. 4) The directory 'example' is a module (it has a go.mod) file. > Yes > a) It has NO packages of it's own. > Wrong. It contains a file webserver.go and this is the package making up this module. b) It has a dependency on the 'webserver' module which must have a > go.mod file (as it does). > Well, true, but nonsensical. > c) The purpose of the 'example' mod file is to locate the module > dependencies (not the packages) > There is no purpose for a go.mod file in the example directory except. Really. This is complete nonsense. > d) Strictly speaking this is NOT a module (nothing will depend on it) > so I should either move it outside the module or get go mod to ignore it by > prefixing with '_' > Whether something depend on something has no influence on being a module. A module is a group of packages versioned together. Nothing less but especially nothing more. Go code depends on packages (that's what you import). Packages which work together and are versioned are grouped in a module. A module has a version e) It is where the main() is. > Location of package main and func main() has literally nothing to do with modules. > f) Is there any reason it could not be a module and be a dependent of > another module? > If have no idea what you mean here. Best advice: Stop going micro-module. Technically each and every of your packages you ever develop could live in its own module. But this is nonsense in real life where you develop a program, a set of programs working togther or a set of library packages working together and this "together" is tested, versioned and released together under one version number. > > Modules are normally stored in git (or equivilant) but even if they are > not they need a module name that includes the git path and a go.mod file. > Technically no. Now you enter a different real here: How to find the source code of a module. Formally you could name your module x whatever you like, store it on disk wherever you like and add a replace directive to each module which import a package from x pointing to that disk location. So basically a "Yes!" on this. Your module are named github.com/<youraccount>/<repo> > > My 'webserver' go.mod file was created with the name: > github.com/mygit/webserver > > My 'example' was created with the name: > github.com/mygit/webserver/example > > I have a sneeking feeling that if outside of 'webserver' it would be: > github.com/mygit/example > Could it be: > github.com/mygit/webserver/example > Or if renamed: > github.com/mygit/webserver/_example > I do not understand your structure well enough to comment on this. > I am really not sure what the correct name is here. If not a dependency, > does it matter? > Probably you are conflating import dependency and version dependency. On any case: Yes the module name *does* matter! If you have a module foo/bar/xyz then the import path of each and every package in this module start with foo/bar/xyz, e.g. foo/bar/xyz/wuz/kik for a package in wuz/kik. > > > *Now for 'replace' this is where I get a bit vague.* > Replace, changes a module's dependency path. Either changing the version > number or the actual modules full path. E.g. => > github.com/someothergit/webserver. > Not really. It can change the version and/or where to find it. There simply is no "module path". A module has a name specified with the module directive in the go.mod. This name cannot be changed with a replace directive. > > Replace can change a modules path to a local directory path. > Correct if you thing of "module path" as "where to find the module". > > a) A local path of ./ indicates that the dependency (module) is in the > same 'module' (as with example currently) > Maybe. This is useless and never needed. > > b) A Local path of ../ indicates that the dependency (module) is one level > up. > Is this in the same module or one levelup from the go.mod file? > Even more strange here. No specifiying that the source of a module lifes one level up in the file system directory structure is plain nonsense. > > c) A Local path of ../foo indicates that the dependency (module) is one > level up in the directory called 'foo'. > In my case if 'foo' contained 'webserver' would the path be: > ../foo/webserver > Or > ../foo > Maybe. At least this is no longer nonsensical. Stop going clever with ../ and use an absolute path, with this you will understand what is going on. Such a replace directive tell Go where on disk to find the source code of that module. Thats all to know. Again: The best advice is: Use *one* go.mod at the source of your git repo and treat everything in there as one module. This is perfectly fine for your repo: You want to version your example and your server together! Nobody ever will want your webserver code in version 1.2.3 but your example in version 3.4.5! Are there any diagnostics for dependency resolution. > > Is there anyway of logging what the actual resultant 'replace' finds (or > not). It seems to fallback, ignoring the replace, if it cannot be found. > This would be really informative. > I doubt it fallback. The problems in your code stems from not treating a set of packages versioned together as a single module. Your could would not need any replace directive. V. -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/b0dc887a-a8d6-451b-918e-643fa0e74b47%40googlegroups.com.