Skip to content
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

Combined parsing and schema generations (libfetchers, WIP) #9273

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

roberth
Copy link
Member

@roberth roberth commented Nov 1, 2023

Motivation

By combining parsing and schema generation (for docs), we achieve the following

  • keep the implementation and docs closely in sync
  • make it easy to have fields for every attribute
    • this will have a canonicalizing effect on the output of the fetcher. Improves consistency of returned values (and perhaps default handling)

Eventually, this helps with removing submodules "leak"

TODO

It's currently not useful at all.

Must have

  • resolve the little conflict
  • add documentation fields
  • write the Schema to JSON
  • union (e.g. path or string)

Should have

  • Input subclasses,
    • or at least move checks into the lambda where parsed values are directly available)
  • type tag node in the schema

Nice to have

  • add libexpr-level schema check, as that will be able to refer to attribute positions

Context

Priorities

Add 👍 to pull requests you find important.

@github-actions github-actions bot added with-tests Issues related to testing. PRs with tests have some priority fetching Networking with the outside (non-Nix) world, input locking labels Nov 1, 2023
using namespace testing;

namespace nix::fetchers {
using namespace parsers;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should deindent these like the rest of the code (and go back and deindent the other indented tests too.

bool required;
std::shared_ptr<Schema> type;
bool operator==(const Attr & other) const;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
};
};

Attrs() {};
Attrs(std::map<std::string, Attr> && attrs)
: attrs(attrs) {};
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
};
};

@@ -5,6 +5,14 @@

namespace nix::fetchers {

std::string attrType(const Attr &attr) {
Copy link
Member

@Ericson2314 Ericson2314 Nov 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::string attrType(const Attr &attr) {
std::string attrType(const Attr & attr) {

our usual format

@@ -12,6 +12,9 @@

namespace nix::fetchers {

/**
* A primitive value that can be used in a fetcher attribute.
*/
typedef std::variant<std::string, uint64_t, Explicit<bool>> Attr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some later PR we should probably do a wrapper struct (per #7479 (comment)) so the functions below can be methods.


namespace nix::fetchers {

struct Schema;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not indent the outermost namespace

Suggested change
struct Schema;
struct Schema;

std::apply([&](auto&&... args) { (f(args), ...); }, t);
}

/** Accepts an 'Attrs'. Composes 'Attr' (singular) parsers. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Accepts an 'Attrs'. Composes 'Attr' (singular) parsers. */
/** Accepts an `Attrs`. Composes `Attr` (singular) parsers. */


public:
Attrs(Callable lambda, AttrParsers *... parsers)
: lambda(lambda), parsers(parsers...) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
: lambda(lambda), parsers(parsers...) {
: lambda(lambda), parsers(parsers...)
{

class Attrs
: public Parser<
nix::fetchers::Attrs,
std::invoke_result_t<Callable, typename AttrParsers::Out ...>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::invoke_result_t<Callable, typename AttrParsers::Out ...>> {
std::invoke_result_t<Callable, typename AttrParsers::Out ...>>
{

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-11-03-nix-team-meeting-minutes-100/35245/1

@roberth roberth force-pushed the libfetchers-combined-parsing-schema branch from 9c75cb8 to f014413 Compare January 9, 2024 19:08
new OptionalAttr<TarballAttrs,Int>("revCount", Int {}, [](auto x) { return x.revCount; }),
new OptionalAttr<TarballAttrs,Int>("lastModified", Int {}, [](auto x) { return x.lastModified; })
);
}();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm debating whether this is a good solution.
Good:

  • it's functional
  • we can initialize a const TarballAttrs
  • no lists of functions or such, that may slow it down (as it would be nice to have a similar solution that works for defining primops with attr based arguments etc)
  • bidirectional

Bad:

  • boilerplate
  • too little type inference
  • unparseAttr is super ad hoc. Doesn't have a proper interface. Just "happy" template accidents.
  • making the arguments and parser codecs line up is a manual process and the error messages are useless

Perhaps a Setting-like alternative would be easier to use?
It would allow us to spend some template "budget" on declaring what kinds of fields they are, so that we have a variation of the TarballAttrs to represent a properly locked input, or a variation for the attrs that should be returned by fetchTree.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a syntax like this can provide better inference, at the cost of needing another type.

OptionalAttr("revCount", Int {}).getter([](TarballAttrs x){ return x.revCount; })

Regarding the boilerplate - maybe feel quite that way if we make more use of this feature when extended with doc strings.

Ericson2314 added a commit that referenced this pull request Jan 9, 2024
The renaming task is splatting everything together into markdown lists.
I think I want to do that with the lowdown AST; I opened
kristapsdz/lowdown#131 for this purpose

PR #9273 should be able to improve upon this a good bit, but I think it
is still a useful stepping stone.
Ericson2314 added a commit that referenced this pull request Jan 9, 2024
The renaming task is splatting everything together into markdown lists.
I think I want to do that with the lowdown AST; I opened
kristapsdz/lowdown#131 for this purpose

PR #9273 should be able to improve upon this a good bit, but I think it
is still a useful stepping stone.
Ericson2314 added a commit that referenced this pull request Jan 12, 2024
The renaming task is splatting everything together into markdown lists.
I think I want to do that with the lowdown AST; I opened
kristapsdz/lowdown#131 for this purpose

PR #9273 should be able to improve upon this a good bit, but I think it
is still a useful stepping stone.
Ericson2314 added a commit to obsidiansystems/nix that referenced this pull request Jan 15, 2024
The renaming task is splatting everything together into markdown lists.
I think I want to do that with the lowdown AST; I opened
kristapsdz/lowdown#131 for this purpose

PR NixOS#9273 should be able to improve upon this a good bit, but I think it
is still a useful stepping stone.
Ericson2314 added a commit to obsidiansystems/nix that referenced this pull request Jan 15, 2024
The renaming task is splatting everything together into markdown lists.
I think I want to do that with the lowdown AST; I opened
kristapsdz/lowdown#131 for this purpose

PR NixOS#9273 should be able to improve upon this a good bit, but I think it
is still a useful stepping stone.
Ericson2314 added a commit that referenced this pull request Jan 16, 2024
The renaming task is splatting everything together into markdown lists.
I think I want to do that with the lowdown AST; I opened
kristapsdz/lowdown#131 for this purpose

PR #9273 should be able to improve upon this a good bit, but I think it
is still a useful stepping stone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fetching Networking with the outside (non-Nix) world, input locking with-tests Issues related to testing. PRs with tests have some priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants