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

Feature request: keyword to specify a default stage #2072

Open
Fjan opened this issue Jan 3, 2021 · 5 comments
Open

Feature request: keyword to specify a default stage #2072

Fjan opened this issue Jan 3, 2021 · 5 comments

Comments

@Fjan
Copy link

Fjan commented Jan 3, 2021

I would like the option to specify a default stage for a task. I have a number of tasks that only make sense to run on a particular stage, so I find myself typing:
cap backup_server backup_task or cap logging_server logging_task

To save myself from typing out the stage name for these I optimised my workflow a little by adding:

invoke :backup_server if ARGV.first&.start_with?('backup_task')

But this is a bit brittle as it depends on argument order (and depending on plugins it complains about load:default getting loaded twice). It would be really nice if the DSL allowed me to specify default_stage <task> => <stage> or something like that.

Looking at the code it seems it should be fairly straightforward to add this. If we take a shortcut by using the existing DSL and do set :default_stage, {task: stage} then it would just require a few additional lines in the task ensure_stage in task_enhancements.rb. But it would be nicer to add a proper default_stage keyword so that it can be called multiple times so you can call it in the same place where the task is defined.

What do people think?

@leehambley
Copy link
Member

leehambley commented Jan 4, 2021

Hi @Fjan thanks for the report.

Have you considered defining your task like:

task :backup_task => :backup_server do
  # ...
end

I'm shooting a bit here from the hip, but logically this says "backup_task depends on backup_server", if memory serves the "env" task (backup_server) is a simple task and can be declared as a prerequisite this way.

If this works, I'd prefer it over the introduction of a new configuration option, could you try it out and let me know please?

@Fjan
Copy link
Author

Fjan commented Jan 4, 2021

Interesting suggestion, and I agree that might be better than introducing a new configuration option. It doesn't currently work however. It looks like ensure_stage verifies the task at hand before running the dependencies (which makes sense). Perhaps we can make it clever enough to see if there is a stage as one of the dependencies?

@leehambley
Copy link
Member

Thanks for checking that so fast.

I think we could refine/patch {Capistrano|Rake}::Task to have some accessor like defines_a_stage? and ensure_stage could check if one of the prerequisites of the current task already `defines_a_stage?

How would you feel about that?

@Fjan
Copy link
Author

Fjan commented Jan 4, 2021

Yes, it looks like there already is a @top_level_tasks that contains what you need, so the check would need to see if one of the prerequisites is in there.

@Fjan
Copy link
Author

Fjan commented Jan 7, 2021

It turns out that this can be done by adding a single line to the ensure_stages method. I love how succinct ruby makes this monkey patch:

module Capistrano
  module TaskEnhancements
    def ensure_stage
      Rake::Task.define_task(:ensure_stage) do
        next if @top_level_tasks.any?{|task| !(Rake::Task[task.split('[').first].prerequisites & stages).empty?}
        unless stage_set?
          puts t(:stage_not_set)
          exit 1
        end
      end
    end
  end
end

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

No branches or pull requests

2 participants