Skip to content

add cep for definition of new keys & values in build format - #56

Merged
wolfv merged 43 commits into
conda:mainfrom
wolfv:cep_20.2
Jan 22, 2024
Merged

add cep for definition of new keys & values in build format#56
wolfv merged 43 commits into
conda:mainfrom
wolfv:cep_20.2

Conversation

@wolfv

@wolfv wolfv commented Jun 14, 2023

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md Outdated
license_url: url

# REMOVED:
# prelink_message:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this bit here was added for EULA like stuffs that needs confirmation from the user, I believe NVIDIA or/and intel folks use it? or at least they were keen to have it. I would be careful in removing this one :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes I 100% agree. We have to keep this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I suppose we could use prelink scripts? @jakirkham can comment for the nvidia stuff.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

They aren't using it on conda-forge (I checked)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am also keen on dropping the post-link, pre-link, and post-unlink keys in build.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The keys in the recipe. We would keep the files.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Prelink_message is mainly for eula purposes that the user needs to accept it, it is not related to the prelink and postlink script that are, as far I'm concerned, deprecated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

prelink and postlink script that are, as far I'm concerned, deprecated

post-link and pre-unlink should only be deprecated if similar functionality is offered elsewhere.

The keys in the recipe. We would keep the files.

Personally, I'm not a big fan of the "some file relative to meta.yaml/recipe.yaml triggers some implicit behavior" thing.
(I'd even go as far as removing the implicit invocation of build.sh/bld.bat -- but that might upset people 🤷.)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was there a resolution to this for packages that want / need to display some kind of EULA message or even want to require some kind of interaction from a user, i.e. accepting a EULA?

NVIDIA legal seems to be appeased currently, but from experience these decisions can change, and there will likely be uses outside of NVIDIA packages as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It feels like the "if a file named in this particular way is found then we do X" behaviour will stay, but the keys to change how that file is named will not... If we do so, I'd rather we do it like we treat activation scripts (their target location is the trigger, not the source one); but that doesn't work well for pre-link & post-unlink because the files will be gone.

Comment thread cep-20.2.md Outdated
Comment on lines +491 to +492
script:
script: ${{ "build_mamba.sh" if unix else "build_mamba.bat" }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
script:
script: ${{ "build_mamba.sh" if unix else "build_mamba.bat" }}
script: ${{ "build_mamba.sh" if unix else "build_mamba.bat" }}

Was this a mistake?

Also, on a related note, I've always found it confusing that script: can either be a string that is the name of a file which is a script or it can be a list of strings which will be converted into a bash or bat script. What can this new format do to make this less confusing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep, that was a mistake, thanks!

I see two ways of achieving this, either by having another level in the dict, e.g.

script:
  file: myfile.sh
  # or
  content: |
    ....

Or having an additional key, like script_file vs script or something like that.

Ok, maybe a third one would be something like: script: ${{ embed("build.sh") }} and write a jinja function that pulls in the contents of the file. This could be quite useful for other files as well (e.g. README, ...).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have to say that I like the current syntax a lot but I get that it is confusing.

@dhirschfeld dhirschfeld Jun 14, 2023

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This could potentially allow choosing the interpreter to use:

script:
  shell: bash
  file: build.sh

e.g. https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have to say that I like the current syntax a lot but I get that it is confusing.

@beckermr Could you elaborate on why you like that script: is a keyword with two different meanings?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I like not having to remember the different names for the different things.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actually my first thought when I saw script: ${{ "build_mamba.sh" if unix else "build_mamba.bat" }} was: "can't we have a default that abstracts away the different file extensions?"

Something like1:

        script: build_mamba  # will use .sh on unix and .bat on win

If someone needs differently named scripts, they could always drop down to selectors, but it would make one more source of noise go away in the vast majority of cases.

Footnotes

  1. if we need to disambiguate from script: for compatibility (is this relevant in a new format that's already breaking things?), we could name the key script_auto_ext: or something like that.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actually the logic for that could be (since build_mamba / build_mamba.sh / etc. are just strings): If $script + ".sh" exists (on unix; .bat on windows) execute it, if it doesn't exist, assume the extension is already in the script, i.e. execute $script.

Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md Outdated
preserve_egg_dir: bool (default false)

# only used as a hack to down-prioritize packages
track_features: [string]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it a good moment to rename this (even if we use track_features under the hood)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

probably!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we have an actual proposal for what to call the next thing to replace track features? Maybe that has to come first?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I would propose priority or downprioritize and then an integer (positive or negative)

Comment thread cep-20.2.md Outdated

```yaml
# url pointing to the source tar.gz|zip|tar.bz2|...
url: url

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This can be a list of URLs too (mirrors of the same package with the same hash; used by R packages)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

👍

Comment thread cep-20.2.md Outdated
# extra run dependencies
run: [MatchSpec]
# extra files to add to the package for the test
# Alternatively, use ${{ RECIPE_DIR }} or ${{ SOURCE_DIR }} and a single list?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like this better, imo.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have mixed feelings. I always found files and source_files ambiguous. Your proposed format would help. I also like your alternatives, but I feel like it could cause ambiguity. For example, if we allow ${{ RECIPE_DIR }}, does it mean that we can also do /absolute/path/to/file?

Comment thread cep-20.2.md Outdated

```yaml
# list of imports to try
imports: [string]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As we move to an language agnostic world, should this be renamed to python_imports for clarity?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Or we do

python:
  imports:
    - mypkg
    - mypkg.foo

With the potential to add more keys, e.g. pytest or others?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That could work, yes. I think pytest would be better handled as a command anyway, but maybe there are other Python specific checks to be made.

@kenodegard kenodegard Nov 2, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm thinking renaming imports to python is sufficient:

test:
  python:
    - mypkg
    - mypkg.foo
    - mypkg.foo:function
  rust:
    - mypkg
    - mypkg::foo
    - mypkg::foo::function

Anything more complex is probably better off in a script?

Comment thread cep-20.2.md Outdated
- ${{ compiler('cxx') }}
- cmake
- ninja
- ${{ "python" if win }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What's the returned value happens when there's no else clause and the if clause is not true? null?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, a Yaml::Null value (that we filter out in these ConditionalList).

Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md Outdated
wolfv and others added 4 commits June 15, 2023 09:52
Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
@dhirschfeld

Copy link
Copy Markdown

One thing that I would love to have is an env_vars section which could then be used to automatically create activate and deactivate scripts for all shells which would take care of backing up existing values and setting the new ones on activation and restoring the backed up versions on deactivation.

e.g.

env_vars:
  - DOTNET_ROOT=$CONDA_PREFIX/lib/dotnet
  - DOTNET_TOOLS=$CONDA_PREFIX/lib/dotnet/tools

Potentially a big enough change to deserve it's own CEP though 🤔

Comment thread cep-20.2.md Outdated
Comment on lines +107 to +108
# if it is only one element and ends with `.sh` or `.bat`
script: string | [string]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Does this means build.sh and bld.bat are not automatically detected and need to be explicitly mentioned?
I think that would be better to make it explicit

@wolfv

wolfv commented Jun 15, 2023

Copy link
Copy Markdown
Contributor Author

@baszalmstra did some awesome work at making a pydantic model for the schema presented in this PR. What's awesome is that it allows us to get feedback and inline-help in the VSCode editor (check out this video) with all the red squiggly lines:

Screen.Recording.2023-06-15.at.15.36.55.mov

The repository for the pydantic file and the JSON schema is here: https://github.com/prefix-dev/recipe-format

If you start a new YAML file in VSCode and add the following line to the top, you should have it, too:

# yaml-language-server: $schema=https://raw.githubusercontent.com/prefix-dev/recipe-format/main/schema.json

We also changed a couple of definitions. Most notably the script_env is now:

- script_env:
    # list of environment variables to pass through to the script
    passthrough: [string]
    # dictionary of key/value of environment variables to set in the script
    env: {string: string}
    # list of secrets to pass through from the environment
    secrets: [string]

In the about section we renamed a couple of fields:

description is now either 
description:
  file: path # path to read description from, e.g. ${SRC_DIR}/README.md

 -- or --  
description: string

renamed:

home -> homepage
doc_url -> documentation
dev_url -> repository

And we split the definition of multi-output recipes into a "complex recipe".
Different rules apply to complex aka multi-output recipes:

  • toplevel package field can only have a version (that is used for all outputs, if they do not define their own version)
  • toplevel build field can only have a number that is used for all outputs if they do not define their own build-number
  • toplevel test is disallowed
  • toplevel about and source are still allowed, although we're not sure if we should keep the toplevel source or if that should be done via one of these cache outputs

@AntoinePrv

Copy link
Copy Markdown

Two more things I could think of:

Versioning the recipe format

We could have a metadata section but version is the only useful thing that comes to mind.

recipe:
  version: "1.0"

Parameters

Maybe that would be it's own CEP, but I think it could be valuable to pass values to the recipe from conda-build/boa/ratter-build.
Two use case that come to mind:

  • Pass a path to a directory to a ccache folder reused between builds (could also be done with forwarding an env variable)
  • Dispatch source between an url and a local directory so that feedstocks can be tested locally in project (mamba proves this is currenlty a mess).

@carterbox

Copy link
Copy Markdown
Contributor

I agree with @AntoinePrv that a new format should be accompanied by a version metadata so that parsers can explicitly query which version of the format they are parsing.

@dhirschfeld

Copy link
Copy Markdown

I agree with @AntoinePrv that a new format should be accompanied by a version metadata

Perhaps named schema_version (or similar) as version is a bit overloaded.

@wolfv

wolfv commented Jun 16, 2023

Copy link
Copy Markdown
Contributor Author

An alternative to having the schema_version in the file would be to encode the schema version in the filename (recipe.v1.yaml etc...). But I am fine with having an explicit schema version in the recipe (I think docker-compose does it, too).

@jezdez

jezdez commented Jun 21, 2023

Copy link
Copy Markdown
Member

An alternative to having the schema_version in the file would be to encode the schema version in the filename (recipe.v1.yaml etc...). But I am fine with having an explicit schema version in the recipe (I think docker-compose does it, too).

I'm in favor of having it inside the file rather than the filename carry it

@xhochy

xhochy commented Jan 5, 2024

Copy link
Copy Markdown

Yes

1 similar comment
@ocefpaf

ocefpaf commented Jan 5, 2024

Copy link
Copy Markdown

Yes

@wolfv

wolfv commented Jan 10, 2024

Copy link
Copy Markdown
Contributor Author

@CJ-Wright @goanpeca @chenghlee @marcelotrevisani @jakirkham @mbargull @kkraus14 @jaimergp this is a reminder to please vote with YES / NO / ABSTAIN on this CEP :)

@mbargull

Copy link
Copy Markdown
Member

Could you add a comment on the removed options saying that replacements for them will be re-introduced later?

ping on this

@mbargull mbargull left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes

@jaimergp jaimergp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have some comments before casting my vote (which will be yes).

  • It feels like the current writeup needs some proof-reading. I found some typos and out of date examples that should be sorted out before accepting the CEP.
  • Some ongoing conversations have not been resolved with a explicit decision. It's fine if those are not tackled in the present CEP, but at least a comment should be made mentioning that they will (or not) be worked on in the future.
  • The top-level script vs build/script explanation is not clear right now.
  • A couple sections could use some more details.
  • Some cosmetic changes.

I also have some minor comments that are a matter of taste and uncontroversial (e.g. path vs file). Feel free to ignore those.

Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md

We propose a new recipe format that is heavily inspired by conda-build. The main
change is a pure YAML format without arbitrary Jinja or comments with semantic
meaning.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This probably needs something more specific to this particular part. Not a blocker though.

Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md
Comment thread cep-20.2.md
Comment thread cep-20.2.md Outdated
Comment thread cep-20.2.md
license_file: LICENSE
summary: A fast drop-in alternative to conda, using libsolv for dependency resolution
description: Just a package manager
repository: https://github.com/mamba-org/mamba

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
repository: https://github.com/mamba-org/mamba
development: https://github.com/mamba-org/mamba

Comment thread cep-20.2.md
# pre-link: path
```

### Script section

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this a top-level section or the "value type" for the script key in build?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems to be build/script based on the Markdown header depth, but yeah, I think that should be clarified.

wolfv and others added 5 commits January 15, 2024 10:07
Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
@goanpeca

Copy link
Copy Markdown

Yes 👍🏼

@jaimergp

Copy link
Copy Markdown
Member

Yes.

@wolfv

wolfv commented Jan 17, 2024

Copy link
Copy Markdown
Contributor Author

@CJ-Wright @chenghlee @marcelotrevisani @kkraus14

if you could please vote (even if you vote with abstain), that would be great!!

@wolfv

wolfv commented Jan 17, 2024

Copy link
Copy Markdown
Contributor Author

Forgot @jakirkham

@marcelotrevisani

Copy link
Copy Markdown
Member

Yes

Comment thread cep-20.2.md
Comment on lines +52 to +57
The version can be explicitly set by adding a `schema_version` key to the recipe.

```yaml
# optional, since implicitly defaults to 1
schema_version: 1 # integer
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the old-format meta.yaml or the new-format recipe.yaml? If the latter, I'm inclined to make schema_version required, rather than optional, to avoid future "we can never update the default schema version" issues.

Comment thread cep-20.2.md

# ignore all or specific files for prefix replacement
# was `ignore_prefix_files`
ignore: bool | [path] (defaults to false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would this be better as bool | [glob], rather than requiring explicit paths?

Comment thread cep-20.2.md
Comment on lines +160 to +161
# force the file type of the given files to be TEXT or BINARY
# for prefix replacement

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For clarity, we should define what TEXT and BINARY mean in this context.

Comment thread cep-20.2.md
Comment thread cep-20.2.md
Comment on lines +234 to +235
# The file to use as the script. Automatically adds `bat` or `sh` to the filename
# on Windows or UNIX respectively (if no file extension is given).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure I like the idea of automatically appending a extension, especially on *nix where file extensions historically have had no particular semantics. I'm not sure why conda build should care if build-my-pkg is written in any particular language, especially if I've already specified interpreter. (E.g., if I've provided interpreter: "/usr/bin/env python" and specify file: foo, I don't want conda build trying to run python foo.sh.)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If you want to run a python file you should just specify the extension foo.py? I think it's probably ok to not support running files without an extension?

Comment thread cep-20.2.md
# pre-link: path
```

### Script section

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems to be build/script based on the Markdown header depth, but yeah, I think that should be clarified.

Comment thread cep-20.2.md
Comment thread cep-20.2.md
#### Python test element

The python test element renders a `test_import.py` file that contains the imports to test.
It also automatically runs the `pip check` command to check for missing dependencies.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm also not keen on automatically running pip check, especially since optional features and dependencies are a thing. Need to dig out the specific package name, but we have run into issues where pip check failed because we (as packagers) explicitly decided to turn off a feature but had no way of informing pip of that change.

Comment thread cep-20.2.md
requirements:
# same definition as top level

# same definitions as on top level, by default merged from outer recipe

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1

Comment thread cep-20.2.md
@chenghlee

Copy link
Copy Markdown
Contributor

Left comments, but other than _maybe) making schema_version: N required, none of them would block a "yes" vote from me.

@CJ-Wright

Copy link
Copy Markdown

Yes
I am making this comment solely in my personal capacity and am not conveying any rights to any intellectual property of any third parties.

@wolfv

wolfv commented Jan 19, 2024

Copy link
Copy Markdown
Contributor Author

Hi everyone! I have counted the votes:

  • 12 yes
  • I am counting Cheng as 1 abstain Update: Cheng is also a yes!
  • No no votes

That means 13 people have voted. The council consists of 15 people.

That means that: 86% have voted, and 100% have voted yes! This CEP is accepted! 🎉

@wolfv wolfv removed the vote Voting following governance policy label Jan 19, 2024
@chenghlee

chenghlee commented Jan 19, 2024

Copy link
Copy Markdown
Contributor

@wolfv: you can count me as a "yes". 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.