Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Lifecycle hooks #1183

Closed
adamblake opened this issue Apr 12, 2024 · 11 comments
Closed

Lifecycle hooks #1183

adamblake opened this issue Apr 12, 2024 · 11 comments
Labels
✨ enhancement Feature request

Comments

@adamblake
Copy link

Problem description

There was a brief proposal regarding lifecycle hooks in #524 but that issue was framed around Python dependencies. With the addition of the new pypi-dependencies the issue was more or less discarded. However there are other common use-cases for lifecycle hooks, especially when using pixi to setup development environments. Here's an example that will probably look familiar:

[dependencies]
pre-commit = ">=3.7.0,<3.8"

[tasks]
postinstall = "pre-commit install"

Love this project, and always looking forward to the new features. The pypi-dependencies addition has seriously made life easier!

@adamblake adamblake added the ✨ enhancement Feature request label Apr 12, 2024
@adamblake
Copy link
Author

I also just saw that this is mentioned as one of the requests in #1128

@tdejager
Copy link
Contributor

I was thinking about this a bit, do you think that instead of like a 'postinstall' we can create a trigger that uses the hash of a file to automatically trigger a task after a or a number of tasks.

Think of having both a Python project that uses npm as well. You could make a "trigger" that triggers when the package.json changes after an install or maybe any other task.

Might be more powerful than a postinstall.

@adamblake
Copy link
Author

I think that it could a good addition to the idea. It definitely would make this a more complex feature to implement though. If it went that way I would think it could be some kind of configurable trigger, e.g.

[tasks]
list-files = "ls -lah"
reset = "chartpress --reset"

[triggers]
post-install = ["list-files"]

[file-triggers]
"pixi.toml" = ["reset", "list-files"]

@ruben-arts
Copy link
Contributor

What about adding it to the task definition:

[tasks]
install-npm = { cmd = "npm install", trigger = "post-install", inputs = ["package.json", "src/javascript/*.js" }

Where those triggers are predefined names that pixi looks for when it runs the install. These could be extended with more triggers, but I would like to add them based on use-case/on-request.

This would allow you to do something similar to the life cycle scripts from npm but without predefined names for the tasks.

@pavelzw
Copy link
Contributor

pavelzw commented Apr 16, 2024

Actually, the postinstall = "pip install --no-deps --editable --no-build-isolation ." problem is not quite solved for me yet (because adding pypi-dependencies introduces more complexity into conda-only projects due to additional uv calls which i would like to avoid). Maybe just making postinstall a lifecycle script could solve this issue for me.

@bollwyvl
Copy link
Contributor

Having now tried a few different pixi things: it seems like the task primitive is probably enough for just about everything, where lock and install are just hidden, special cases... making them even more special (or introducing more special tasks) would likely complicate things further.

I've ended up with a pattern like this for a monorepo where i can't use pixi/uv-managed editable installs:

[feature.pip.tasks.install-editable]
inputs = ["pyproject.toml", "contrib/*/pyproject.toml", "editable.txt"]
outputs = ["build/pip-freeze/$PIXI_ENVIRONMENT_NAME.txt"]
cmd = """
  rm -f build/pip-freeze/$PIXI_ENVIRONMENT_NAME.txt
  && python -m pip install -vv --no-deps --no-build-isolation --ignore-installed -r editable.txt
  && mkdir -p build/pip-freeze
  && pip freeze > build/pip-freeze/$PIXI_ENVIRONMENT_NAME.txt"""

... and then have any downstream tasks depends_on: ["install-editable"], with an input of the pip freeze output. This ensures if some packaging-related thing changes (e.g. entry_points), the env in question will be brought up-to-date before trying to test it.

This still gets a little annoying further down the line when the -e argument isn't enough to fully specify the required intermediate environments... indeed, consider a fan-in reporting use case which still needs an editable install:

[feature.docs.tasks.report]
depends_on = [
  "install-editable", # where the current -e will be right
  {task="test", environment="some-env"},
  {task="test", environment="some-other-env"},
]
inputs = [
  "build/pip-freeze/$PIXI_ENVIRONMENT_NAME.txt", 
  "build/reports/some-env.txt", 
  "build/reports/some-other-env.txt"
]

Running pixi run report should then end up running install-editable (up to) three times, each time in a different env (which it may have also created). If the cache data is right, these might have been on entirely separate machines in CI.

Alternately, as the task name regex is luckily already quite tight, a separator could be introduced:

depends_on = ["install-editable", "some-env::test", "some-other-env::test"]

Of course, if inputs/outputs already defined the task-task relationship, and only one task was permitted to outputs a particular file, there would be no need for duplicating or specifying depends_on at all (see #1139).

@nicornk
Copy link
Contributor

nicornk commented Apr 25, 2024

I have the need for this as well. I want to install a binary (that is not available in conda-forge/pypi) manually using curl into my environment/bin after pixi is finished building it. Reading this thread makes me think that triggering this automaticaly is not possible today?

@tdejager
Copy link
Contributor

@nicornk if building is task, you can achieve this with a depends_on and a correct input/output. If I understand what you are saying.

@nicornk
Copy link
Contributor

nicornk commented Apr 25, 2024

I was referring to calling „pixi install“.

@tdejager
Copy link
Contributor

Ah I understand, that would be the requested feature indeed.

@adamblake
Copy link
Author

I have the need for this as well. I want to install a binary (that is not available in conda-forge/pypi) manually using curl into my environment/bin after pixi is finished building it. Reading this thread makes me think that triggering this automaticaly is not possible today?

This is basically one of my use-cases as well --- I want to install a Helm plugin after install, and to do the pre-commit startups and stuff like that. @tdejager maybe it could just be as simple as exposing the "install" as a task that can be depended on (possibly namespacing it to avoid collisions with user-named task install)?

@stanmart stanmart mentioned this issue May 30, 2024
14 tasks
@prefix-dev prefix-dev locked and limited conversation to collaborators Aug 23, 2024
@baszalmstra baszalmstra converted this issue into discussion #1897 Aug 23, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
✨ enhancement Feature request
Projects
None yet
Development

No branches or pull requests

6 participants