-
Notifications
You must be signed in to change notification settings - Fork 391
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(gno.land/cmd): auto load and sort pkgs from examples #763
Conversation
8dbd922
to
2f6e8e6
Compare
2f6e8e6
to
54b8ffa
Compare
makeGenesisDoc()
auto load pkgs
Can a solution be found to add gno.mod to invalid packages while providing an option to skip them? Asking users to create gno.mod after package creation is undesirable, as opposed to 'go' which begins with go mod init. |
What about marking module as Deprecated? and not include deprecated modules automatically
or Support something new. maybe
Edit: For supporting something new we need to use custom type. Currently we are using |
@moul @harry-hov Sorry for the lack of context from me, but what's the point of this deprecated instruction ? |
A way to exclude modules from automated publishing systems, such as auto-loading the |
Currently as far as I know we don't automatically publish all the modules from the About So maybe I'm wrong but I'm not convinced about the usage of this new instruction. |
@tbruyelle Let me try to convince you with my understanding of the flow. Currently(in gno/gno.land/cmd/gnoland/main.go Lines 208 to 230 in 71f0bd5
It's not simple as adding the pkg to the list. You need to keep check of the dependency. IOW, in the list pkg[i] should not depend on pkg[j] , if j > i .
This PR makes it automatic. It loads list of all the pkgs from the We want to include all the pkgs in the example dir, but there are few exception like The original idea is not to have gno.mod file in pkgs that we don't want to include. But @moul suggested including gno.mod in all pkgs even if we want to ignore them for now (I agree with it). Now we need to think of the way to ignore them and still have gno.mod file. I suggested marking pkg as deprecated. I think it's good to support parsing phewww. |
@harry-hov Thanks for the clarification, indeed I missed that part where the |
@tbruyelle we can still change the name to something better. What about something self-explaining like Edit: WIP in #790 |
cc @ilgooz would like your opinion on usage of |
Apologies for the late reply; I'll try to some up some of my thoughts and try to sum up also what we discussed earlier today.
True; however it does make it more redundant to structure "programs" with more than one package; as is often the case for any reasonably complex codebase. While this is not currently the case for most gno programs, which generally have at most one package together with one realm, this eventuality should be considered. I think this also ties reasonably well with your issue on #852. My thinking is that big refactorings where packages and directory structures are moved around are rare and not necessarily something we should look to facilitate; rather, it is a good structuring of the code that should be facilitated, into writing many individual useful components (packages). Thus, I think that ideally the publish/addpkg command should work on the "module" as a unit, and publish any individual sub-packages (or, in the case of realms, sub-realms) together. When working on repositories outside monorepo, as we were discussing today, I think there are a couple of reasonable arrangements for the usual single pkg + realm configuration.
Structure 2 is also valid because, like in Go, I think our tooling should consider any subdirectory which has its own gno.mod as a "separate module" -- and thus not one to be concerned with, ie. not subpackage. We do the same in this monorepo ( In the future, as we were discussing today, an idea floating around is that of doing away with the "r/" and "p/", and moving towards "directory extensions", ie. In any case, one of the crucial parts is that today gno.mod serves a primary purpose in first of all determining the full import path (= publish path) of the package/realm. I think this is very important as it allows work outside of the monorepo, and we should enrichen it with the possibility of structuring subdirectories; additionally making
Yes; but I do think the information is redundant, when the dependency graph can be determined just as easily by static code analysis. In other words, it does solve the issue, but I think the better way is understanding package dependencies through the AST rather than gno.mod. This also makes sense long-term, as we want to support multi-pkg modules, as gno.mod should only declare the individual modules, not subpackages.
Just reporting on this as we discussed it today with @moul, but I think a reasonable idea that he had was that of having only these packages with a go.mod, and making the function generating the loading order for gnoland stop at module boundaries. If we do this, I think that for clarity of any observers, we should add the following in the readmes:
Apologies for the long reply, but I do hope it's exhaustive. :) |
One more note we were discussing; if we add AST analysis for import dependencies, as @moul was suggesting, this should (either in this or a future PR) be also public through either a Hopefully this also helps in the usecase @ilgooz would have for having a gno.mod in each package directory? |
I've had a call with Hariom to try to gather insight on each other's point of view. I think there are two main approaches we could go with and I'm slightly leaning towards Hariom's idea now: (1) 🚀 one single gno.mod in examples/gno.land/gno.modPros:
Cons:
(2) 👀 one gno.mod for each (future) modulePros:
Cons:
I think one of the significant drawbacks of (1) is that it is still a temporary and transitory measure -- which we can understand and recognise as transitory even now, while (2) in many ways is already looking more realistically at how we'll want to be working with gno code and gno modules -- or at least, our current idea and understanding of it. Notwithstanding, I think that (2) has mostly some usability concerns which I mentioned in the cons, so I think that if we do go with (2), after merging this PR we should give priority to Secondly, I think it might be nice to restructure Further comments and takes on the topic are welcome; please also cast a vote with a 🚀 or 👀 reaction on this comment to see if we're strongly leaning towards one of the two options :) |
For the IDE, we like the 2nd approach better because it helps us to define realms and packages, visualize and manage them. The 1st approach seems to be same as with how Packages and realms in Gno is "deployable" and they will always have independent versions, they are slightly different than how standard Go packages are organized. In Go, packages are only reusable libraries and they do not need to have a separate go.mod unless you want to version them separately and release (git-tag) them independently. But in Gno, you always need to version and deploy every package by default. Same applies to realms too. I believe that everything that is deployable should have its own gno.mod file. Your realm and package can have some sub directories for code organization, and those dirs don’t need a gno.mod (because they are not deployable alone). |
TL;DR: Each realm and package ( Detailed:
These suggestions aim to provide clarity in package and realm identification, enhance the developer experience, and maintain consistency within the gno.land ecosystem. |
I have 2 questions here:
Did you mean: Just publish I believe it would be beneficial to have a Another concern I have is how we will manage versioning without a |
A project not using the replace directive.
The "Import path in comment" approach is suitable for simpler packages where the use of a gno.mod file may not be necessary. It allows for the proposal of one-file contracts that can be easily reviewed, shared, tweeted, or used in presentations. The idea is to have a simplified import path that is self-contained within the code file, without the need for a separate gno.mod file. The use of gno.mod is more beneficial for complex repositories that consist of multiple independent modules, such as multiple realms or packages. In such cases, the replace directive becomes necessary. However, gno.mod files are local-first and should be skipped from the chain to avoid publishing outdated or incorrect information. While I suggest implementing the import comment as an alternative to gno.mod in the future, for now, it is recommended to make gno.mod files mandatory.
Having a gno.mod file on the chain may not be practical or meaningful once the code is deployed on-chain. The replace directive within gno.mod loses its significance in an on-chain context. Furthermore, if the import path can change due to versioning, it would require patching the .gno files after uploading to ensure deterministic import paths. By default, a published gno.mod file is considered false, and over time it becomes even less accurate. Therefore, it is recommended to skip gno.mod during addpkg, and we should continue to use it primarily for local development and related purposes. Edit: I will provide guidance on managing versioning in a safe manner. It's important to note that the concept of "latest" is only applicable during local development. Once code is published, if a "latest" alias was used, it is recommended to either replace it with specific linked versions or annotate the |
Doesn't have to be this way -- addpkg, as far as I know, potentially supports having sub-directories. And I think it makes sense for an entire module to be published on chain at once; including its subpackages.
I think in some cases they could be deployable alone, this is not the "true" distinction I would argue. It's more about what makes sense, from an author's perspective, to be published together in a single module and to have all of the dependencies grouped together; as well as have the dependants update them simultaneously.
Didn't we agree that -- maybe eventually -- but for dependency management (ie. version locking), it's important for chains to consider the gno.mod dependencies?
I know this is thinking ahead to an issue we'll need to tackle further down the line; does this imply, however, that these "simpler" packages have all of their dependencies always at the latest version? Or maybe "latest-compatible"? Coming back to the PR at hand; I think that if we agree to have several gno.mods in examples/, the only code change to have in this case would be to make sure that the package loader can properly support loading sub-packages of the modules in the correct order. |
Yep, having one gno.mod for a single module makes sense. The module can be small, big, or have subfolders. However, we shouldn't have a gno.mod per subfolder. For two independent realms, whether they are small or big, they should always have independent addpkg commands. When it comes to pure packages (p/), it's a good practice to keep them small and focused, with their own dedicated gno.mod. As we develop better indexers and package explorers that showcase realms as applications in an app store and pure packages like npm, the developer perspective will adapt. Subfolders won't be something people generally discover, but rather something they will come across while exploring a specific module.
I suggest implementing the patching of .gno files at the addpkg stage to specify the unspecified versions. The reason behind my push for this approach is that, once a module is addpkged, the gno.mod file can either be incorrect or differ between the local and remote development environments. This inconsistency goes against the principles of simplicity and obviousness. I believe in the importance of having self-explanatory, copy-pastable code. Also, what about documentation if a gno.mod has a different usage and sense when onchain or locally. I think that skipping gno.mod files during addpkg would make things simpler. Please feel free to share your thoughts, insights, and examples.
How about using "latest" as the default version when unspecified (in repositories, snippets, discussions)? Then, users can manually fix the version in .gno imports or gno.mod locally. When on-chain, contracts are always explicitly specified, which can be achieved thanks to auto-patching.
Yes 👍 |
* feat: add gno.mod to each package * feat: add logic to load and sort gno pkgs * feat(gno.land/cmd): auto load pkgs from examples * fix failing tests * Use more concise if statement * Move pkg loading and sorting logic to gnomod * Fix review comments * Fix gno.mod files * Extract visit() as named func * Skip draft or depends on draft * s/v0.0.0/v0.0.0-latest * Fix `ListPkgs()` * Test `ListPkgs()` * oversight: remove print statement * Export `Pkg` and add field `draft` * Refactor and improvements * make fmt * ListPkgs(): don't skip nested pkgs * Add gno.mod files to `tests/subtests` * No need to subtests manually
Description
This PR and add gno.mod file to every individual pkg inside
examples
dir. The gno.mod file's purpose is to specify each package's name and dependencies so that the cmd/gnoland tool can automatically load, sort, and add the packages when the chain starts.Related #743
Note:
gno.land/p/demo/rand
is marked asdraft
. Which means pkggno.land/p/demo/rand
and pkg that depends on it are not automatically included when the chain starts. The reason for this isgno.land/p/demo/rand
depend on themath/rand
package which is missing from stdlibs (see Add the deterministicmath/rand
helpers to stdlibs #744).gno.land/r/demo/x/upgrade
is also marked s draft. Will discuss it in a separate issue.