DigitPaint / roger

Roger is your friendly front-end development toolbox!
MIT License
4 stars 4 forks source link

[WIP] Proposal for guards in documentation #46

Closed flurin closed 8 years ago

flurin commented 9 years ago

As we want to have more control over what get's applied and what not and we also want a way to ensure a sane build before we actually release it I propose that we build guards into the roger release process.

How does it work?

A guard can work in 2 ways:

There is one additional case where the guard can be used:

This last case is especially useful when we want to pass a condition to a finalizer/processor.

Syntax

The basic syntax looks like this

roger.release do |release|
  # Will abort release if guard is not satisfied
  release.guard :the_guard

  # Will not run block if guard is not satisfied
  release.guard :the_guard do 
    # ...
  end

  # Will always run block and pass guard including outcome to the block
  release.guard :the_guard, required: false do |guard|
    # ...
  end

  # Will abort release if guard IS satisfied
  release.guard :the_guard, satisfy_if: false
end

Options

The guard command will have 2 default options:

A guard again is nothing more than an object with a call method. That means you can pass lambda's as well. The only requirement is that it returns a truthy or falsy value.

Proposed built-in guards

The follwing guards could be built-in Roger:

While the guards may be really useful in combination with release there are other scenario's where they could be helpfull in the test/server as well. In the test cases it could probably work just like in the release.

In the server scenario they will probably be run before the server starts, not on a request basis.

hkrutzer commented 9 years ago

Why not write

raise "bye" unless something

instead of

release.guard :the_guard

and

if flag?(:upload) || prompt_upload
    release.finalize :rsync unless flag?(:dont-upload)
end 

instead of

release.guard :commandline_flag, flag: "always-upload", required: false do |guard|
    release.finalize :rsync
end 

?

flurin commented 9 years ago
raise 'z' if something

May work, so I guess that is an option. Not as clear IMHO.

I don't see how your flag?(...) example could work. Roger does not simply run the release code but rather runs a series of processors. So what happens when we now run the Rogerfile is that it will run if flag?(...) || prompt_upload in a totally different context than the actual finalizer.

Another issue is that you now put the asking question prompt concern into the Rogerfile instead of having it in the rsync finalizer.

edwinvdgraaf commented 9 years ago

It should also update roger --help flags in case of a command line flags.

Looks good. 👌

Sent from my iPhone

On 25 aug. 2015, at 14:34, Flurin Egger notifications@github.com wrote:

As we want to have more control over what get's applied and what not and we also want a way to ensure a sane build before we actually release it I propose that we build guards into the roger release process.

How does it work?

A guard can work in 2 ways:

It can stop execution of the release It can stop execution of a block (when used in block syntax) There is one additional case where the guard can be used:

It can pass the outcome of the guard condition to the block if the guard is not required to pass. This last case is especially useful when we want to pass a condition to a finalizer/processor.

Syntax

The basic syntax looks like this

roger.release do |release|

Will abort release if guard is not satisfied

release.guard :the_guard

Will not run block if guard is not satisfied

release.guard :the_guard do

...

end

Will always run block and pass guard including outcome to the block

release.guard :the_guard, required: false do |guard|

...

end

Will abort release if guard IS satisfied

release.guard :the_guard, satisfy_if: false end Options

The guard command will have 2 default options:

Required Wether or not the guard will abort the release or not run the passed block. Default is true Satisfy_if What outcome should satisfy the guard. Can be handy to invert guard behaviour Default is true Writing guards

A guard again is nothing more than an object with a call method. That means you can pass lambda's as well. The only requirement is that it returns a truthy or falsy value.

Proposed built-in guards

The follwing guards could be built-in Roger:

tests A guard that is only satisfied when all of the roger tests run and succeed

commandline_flag A guard that takes a flag option as string so you can pass this on the commandline when running roger release. Can also be very useful in combination with the required: false option.

roger.release do |release| release.guard :commandline_flag, flag: "always-upload", required: false do |guard| release.finalize :rsync, :host => "mywebhost", :username => "myuser", :remote_path => "www", :ask => !guard.flag end end Future development

While the guards may be really useful in combination with release there are other scenario's where they could be helpfull in the test/server as well. In the test cases it could probably work just like in the release.

In the server scenario they will probably be run before the server starts, not on a request basis.

You can view, comment on, or merge this pull request online at:

https://github.com/DigitPaint/roger/pull/46

Commit Summary

Proposal for guards in documentation File Changes

M doc/rogerfile.md (30) Patch Links:

https://github.com/DigitPaint/roger/pull/46.patch https://github.com/DigitPaint/roger/pull/46.diff — Reply to this email directly or view it on GitHub.

edwinvdgraaf commented 9 years ago

Another issue is that you now put the asking question prompt concern into the Rogerfile instead of having it in the rsync finalizer.

Should prompting be a concern of a finalizer?

Sent from my iPhone

On 25 aug. 2015, at 15:33, Flurin Egger notifications@github.com wrote:

raise 'z' if something May work, so I guess that is an option. Not as clear IMHO.

I don't see how your flag?(...) example could work. Roger does not simply run the release code but rather runs a series of processors. So what happens when we now run the Rogerfile is that it will run if flag?(...) || prompt_upload in a totally different context than the actual finalizer.

Another issue is that you now put the asking question prompt concern into the Rogerfile instead of having it in the rsync finalizer.

— Reply to this email directly or view it on GitHub.

flurin commented 9 years ago

Why not? It is after all a specific feature of the finalizer. Otherwise we cannot have sane defaults anywhere.

flurin commented 9 years ago

Well we could add a 3rd built-in guard: :prompt that will work like this:

roger.release do |release|
    release.guard :prompt, type: :yes, prompt: "Do it?" do |guard|
      release.finalize :rsync, :host => "mywebhost", :username => "myuser", :remote_path => "www"
    end 
  end
hkrutzer commented 9 years ago

I think this proposal is better than https://github.com/DigitPaint/roger/pull/45 but it's still a band-aid solution.

Instead of doing release.guard :npm_dependencies there should be a plugin that moves npm- and bower-installed files after those are installed, and checks for their presence on release, without having to add a block. This should be part of a module you just add to the project without having to configure it.

If handling the prompt is something the finalizer does, then it should handle the flag as well. It should handle both the flag and the prompt, or neither.

flurin commented 9 years ago

I agree about the dependencies bit. That was ill advised. I will remove that. Because as you say that should just be a processor that fixes this for you instead of blocking.

The prompt has been added to the finalizer to have a sane default that will prevent accidental uploads. You can't do that from within your Rogerfile. I get your point that for consistencies sake you do one or the other. But if we move the flag bit to the finalizer you get something like this:

release.finalize :rsync, :host => "mywebhost", :username => "myuser", :remote_path => "www", :ask => true, :skip_commandline_flag => "no-upload-mywebhost"

Don't think that is something we want either, right?

flurin commented 8 years ago

I'm closing this one as it's probably not a good idea.