Giter Club home page Giter Club logo

rulebow's Introduction

RULEBOW

Homepage - Report Issue - Source Code - IRC Channel

"Hey, you got logic in my build tool!"

Rulebow is a build tool that promotes continuous integration via logic programming. With Rulebow, the Ruby developer defines rules and state conditions called facts. The rules are applied when their conditions are met. Through repetitive application, this allows a project to all but manage itself.

Rulebow is not complicated. It does not require a bazillion plug-ins. Although some external tools can be helpful and used with it, and it makes some procedures more convenient. For example, it makes FileUtils methods directly available in the build script context. Mostly it just trusts the developer to know how to write the build scripts they need.

Below you will find a brief "Hot Minute" guide for getting up and running with Rulebow quickly. It's just enough to give you familiarity the basic ideas of Rulebow and how to start putting it to good use. For more detailed instruction, explanation of terms and how the dickens does it work under-the-hood, please consider any of the following resources.

Rulebow in a Hot Minute

To install, either use RubyGems directly:

  $ gem install rulebow

Or add gem "rulebow" to your Gemfile and run:

  $ bundle

Creat a Rulebook file in your project.

  $ vi Rulebook

And add the following example script to the file.

ruleset :default => [:manifest, :test]

ruleset :manifest do
  desc "update manifest"

  globs = %w[bin/**/* lib/**/* *.md]

  fact :need_manifest? do
    if File.exist?('MANIFEST')
      files = globs.map{ |d| Dir[d] }.flatten
      saved = File.readlines('MANIFEST').map{ |f| f.strip }
      files != saved
    else
      true
    end
  end

  rule :need_manifest? do
    files = globs.map{ |d| Dir[d] }.flatten
    File.open('MANIFEST', 'w'){ |f| f << files.join("\n") }
  end
end

ruleset :test do
  desc "run my minitests"

  rule 'lib/**/*.rb' do |libs|
    $: << 'lib'
    files = Dir.glob('test/**/*_test.rb') 
    files.each{|file| require "./" + file}
  end

Now run it with:

$ bow

And there you go. Rulebow, in a hot minute!

A Few More Minutes

As the capable Ruby programmer, it probable doesn't require much explanation to understand the above code and what happened when you ran it. Just the same, it can help to go over it with the proper terminology. Of course, the rules in our example are simplistic and they make some basic assumptions about a project, so you will want to modify these to suite your needs (or dispose of them and write fresh). Nonetheless, this example provides some clear examples of the basics of writing Rulebow scripts.

The first line in the script defines the defauly ruleset. This is the ruleset the is executes when no specific ruleset is designated on the command line. In this case we see that it simply depends on two other rulesets, test and manifest.

Nex in the example we create the manifest ruleset. In it we first create a state called update_manifest?. It simply checks to see if the list of files in the project's MANIFEST file matches the project files expected to be there. Notice it returns a boolean value, true or false. Along with this state we create a rule that uses the state by calling the update_manifest? method. This method was created by the state definition above. The rule procedure updates the MANIFEST file whenever the state returns true, i.e. the manifest does not have the expected content.

At the end of our example script we create an additional ruleset. This one does not reference a defined state. Instead it creates a file state implicitly by passing a string argument to rule. A file state has a very simple and very useful definition. It returns true whenever a matching file has changed from one execution of rulebow to the next. In other words, per this example, whenever a Ruby file in the lib directory changes, Rulebow is going to run the units tests in the test directory.

Okay, so now we have an example rulebook and have a basic grasp of how it works. And we know we can run the rules simple by invoking the rulebow command on the command line. But if we want to have rulebow run automatically periodically, we can pass it the number of seconds to wait between runs via the -a/--auto option.

$ bow -a 180

See it pays to read all the way to the end ;)

Contributing

The Rulebow repository is hosted on GitHub. If you would like to contribute to the project (and we would be over joyed if you did!) the rules of engagements are very simple.

  1. Fork the repo.
  2. Branch the repo.
  3. Code and test.
  4. Push the branch.
  5. Submit pull request.

Copyrights

Rulebow is copyrighted open-source software.

Copyright (c) 2011 Rubyworks. All rights reserved.

It is modifiable and redistributable under the terms of the BSD-2-Clause license.

See the enclosed LICENSE.txt file for details.

(็ซ ็”ฑ)

rulebow's People

Contributors

trans avatar

Stargazers

Max Surkov avatar Jochen Seeber avatar

Watchers

James Cloos avatar  avatar  avatar

rulebow's Issues

Simplify logic system

It might be better to simplify things by removing the set-logic, and just rely on Boolean logic. That's a hard choice to make b/c the set-logic system was the essence of the "ah ha" moment that led to this project, and in-itself it is very cool and makes a hell of a lot of sense. The problem is, as it turns out, the degree of flexibility it provide is almost never needed.

For example, lets say we have two facts (or states, for older versions). We can write it either of two ways. Like this:

  fact :need_docs? do
    ...
  end

  fact :has_manpages? do
    ...
  end

  rule need_docs? & has_manpages? do
    ...
  end

Or like this:

  def need_docs? do
    ...
  end

  def has_manpages? do
    ...
  end

  rule fact(:need_docs?) & fact(:has_manpages?) do
    ...
  end

But we really don't need to go to all that trouble because we could just define a separate fact that combines the other two in it's definition. Like so:

  def need_docs?
    ...
  end

  def has_manpages?
    ...
  end

  def run_ronn?
    needs_docs? && has_manpages?
  end

  rule :run_ronn? => :run_ronn 

Notice there is no need for the fact method at all. Moreover we can extend the rule method to at least handle simple AND conjunctions, like this:

  rule :needs_docs?, :has_manpages? => :run_ronn

We could still keep the set-logic system under the hood. It wouldn't hurt anything to have and it may still be of some use in combining file-facts. If in the end, that too proves to be unnecessary then we can remove it altogether.

Convenience Methods

Make sure it provides convenience methods like #ask? See 'facets/kernel/ask'.

Limit files tracked to rules

Presently all files are tracked for each ruleset, and can only be filtered down via ignore. This is inefficient. The only files that need to be tracked are those in the file rules, unless otherwise stated.

Groups/namespaces

Add support for groups/namespaces.

Which term should we use? Maybe support both as alias?

RC

Add support for RC based configuration once the RC api is solidified.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.