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

Support named, conditional tasks #229

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

davesteinberg
Copy link

@davesteinberg davesteinberg commented Jul 13, 2020

Just like on a link action, the value is executed in the shell. If it has a non-zero exit code (indicating failure), the whole task is skipped.

This allows tasks to group actions that only apply in certain conditions (e.g. on certain OSes or in certain configurations), and allows all actions (not just link) to be conditional.

Resolves #225.

Just like on a link action, the value is executed in the shell. If
it has a non-zero exit code (failure), the whole task is skipped.
This allows tasks to group actions that only apply in certain
conditions (e.g. on certain OSes or in certain configurations),
and allows all actions (not just link) to be conditional.
@davesteinberg
Copy link
Author

I haven't tackled trying to figure out the testing infrastructure yet, so I haven't written any tests. Here's the install.conf.yaml file I used to manually verify that the new functionality works and that I didn't break link in the refactoring:

- link:
    ~/profile.no:
      path: profile
      if: "false"
    ~/profile.yes:
      path: profile
      if: "true"

- if: "true"
  shell:
    - [touch $HOME/yes, I should do this]

- if: "false"
  shell:
    - [touch $HOME/no, I should not do this]

A new property called task can be used to assign a name. If it is
specified, then the task's actions must be nested under an actions
property, and an if property can be used to make it conditional.
Just like on a link action, the value is executed in the shell. If
it has a non-zero exit code (failure), the whole task is skipped.
This allows tasks to group actions that only apply in certain
conditions (e.g. on certain OSes or in certain configurations),
and allows all actions (not just link) to be conditional.

If there is no task property, then the task behaves exactly as
it did previously.
@davesteinberg davesteinberg changed the title Support if on tasks Support named, conditional tasks Jul 20, 2020
@davesteinberg
Copy link
Author

This PR now supports named tasks, too, as described in #225 (comment)

Here's the install.conf.yaml file I used to manually verify it:

- defaults:
    link:
      create: true
      relink: true
    shell:
      stdin: true
      stdout: true
      stderr: true

- task: Prepare
  actions:
    clean: ["~"]

- link:
    ~/profile.no:
      path: profile
      if: "false"
    ~/profile.yes:
      path: profile
      if: "true"

- task: Go
  if: "true"
  actions:
    shell:
      - [touch $HOME/yes, I should do this]
    link:
      ~/profile.go.yes: profile

- task: No go
  if: "false"
  actions:
    shell:
      - [touch $HOME/no, I should not do this]
    link:
      ~/profile.go.no: profile

- task: No actions

- task: Empty actions
  actions: []

This was referenced Jul 20, 2020
@anishathalye
Copy link
Owner

Thanks for taking the time to submit a PR. I left some general comments related to the discussion in #225 back in #225 (comment).

This is an interesting proposal. While not technically backwards compatible in the strictest sense (there could have been a plugin called "if" or "task"), I don't think it will break anything in practice (nobody is using those plugin names). It does change the execution model for tasks. As it's implemented now, tasks are a set of actions, and Dotbot executes all of them independently (in an arbitrary order).

I wonder what is the use of named tasks, beyond documentation? Would it be equivalent if they were # yaml comments?

Compositionality is a tricky issue... I'm going to spend a bit of time thinking about many of the open issues for Dotbot, thinking a bit about how people are using Dotbot in practice (going to try to do a user study), think about what we'd change if we could break backwards compatibility, and so on. I'll try to see if there's a clean solution to this problem of compositionality (e.g. it's a little annoying if we have a different if: inside link: vs the if: at the level of the task, and I think this sort of problem might come up again in other contexts), thinking about both the case where we stick to a YAML-based config file and also the case where we switch to a different syntax, either something custom or an embedded DSL in a full-fledged programming language.

I'll leave this issue open right now, so I can think about it for a bit. Happy to hear feedback from you on this as well. (Once I make a bit more progress on a user study and going through issues, I might try to come up with a more general way to discuss and get feedback on potential larger-scale changes / a Dotbot 2.0).

@davesteinberg
Copy link
Author

Thanks for considering my proposal and for the feedback here and on the issue.

To answer your question here: I think the main use of named tasks is for log output. It lets dotbot print out the name of the task when it begins running or when it is skipped, giving context that helps the user to understand what happened.

I agree with all of your comments on #225. It's not strictly backwards compatible, but the risk of someone using task or if as a plugin name is very low. It is a bit verbose (especially if you only ever use one action per task), but you can skip all the extra syntax if you don't want to use named/conditional actions, and just continue to do what you do today.

Regarding the limitation that actions in a task are unique and unordered, I think that's okay, since it feels like imposing order or repeating actions within a task are super edge-case. At worst, you could always split one task into more than one if you had such a need, even if it meant repeating a test.

In the end, I still see my proposal as small change that gives you a whole lot more power, and that feels worth it to me. But of course that's based only on my usage. And I can see why you might prefer to shoot for something better in a larger-scale change.

Thanks again!

@Futurile
Copy link

Futurile commented Feb 6, 2022

@anishathalye any chance you will merge this, both the named part and conditional part would be very useful.

Today I'm trying to figure out how to run a command, but only if a directory doesn't already exist. I don't think there's any way to do this, but this PR would solve it.

@anishathalye
Copy link
Owner

For the moment, as a workaround, you could incorporate the check into the command. ! test -d some_dir_name && echo "some_dir_name either doesn't exist or is not a directory".

@max06
Copy link

max06 commented Jun 5, 2022

@anishathalye Sorry for digging out older things here but....

I'd really like to have this!
My max06/dotfiles are constantly growing. I use them heavily in any kind of containerized environment, in an automated manner. These containers serve specific purposes, like eg. containing an openstack client. Adding if-conditions to every task is not exactly a good way to keep the configuration clean.
The automation prevents me from going with the profiles-route described in the wiki - dotbot itself needs to figure out what to use and what to skip. Writing an own script around dotbot to accomodate for this defeats the purpose.
Ideally I'd love to have some kind of "include"-functionality, so I can reference each part in the main config with its filename and one single if condition.
I'm also fine with grouping tasks like it's done here, as long as this reduces the conditions to one per block.

Any chance?

Edit: I need to edit myself...

- shell:
    - description: Include ansible configuration
      command: >
        [ -x "$(command -v ansible)" ] && ./install -c ansible.conf.yaml || true
      stdout: true

seems to do exactly what I had in mind!

(Not the nicest solution but better than nothing.)

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.

Allow if on tasks
4 participants