Doit - an experimental scripting framework ========================================== Doit is a framework for writing imperative scripts which feel in the execution like declarative ones. The commands implemented in this framework follow these priciples: * A failing command throws an exception and thus stops the script (unless caught). This is like a Perl script using "use autodie", but in Doit it is implemented consistently for all framework commands. "use autodie" knows only about Perl builtins, not about module functions * Before executing a command a check is done whether the command has to run at all. This makes it possible to write "converging" scripts: a first run would do the changes, subsequent runs would not do at all. * Command execution is logged --- so one actually see what changes are done to a system. A command which doesn't have to run won't output anything. So "convergent" scripts are typically silent after the first run. There's a dry-run mode built-in, which would just show what commands would run, similar like make's -n switch or puppet's --noop --test options. Status ------ This module is experimental, but already used in productive scripts. Backward-incompatible changes to the module are possible, but will be kept to a low number. Examples -------- Here's an example using a command from the git component. It just either clones the given git repository to the given directory, or does a fetch if the repository is already cloned: use Doit; my $doit = Doit->init; $doit->add_component("git"); $doit->git_repo_update( repository => "git://github.com/eserte/Doit", directory => "$ENV{HOME}/src/Doit", ); An excerpt from a real-world system setup script (for setup of FreeBSD and Linux based smokers for CPAN Testers): use Doit; my $doit = Doit->init; $d->add_component('user'); my $root = $doit->do_sudo; # for running commands/scripts as root $root->write_binary('/etc/sudoers.d/20_cpansand', <<'EOF'); # for auto-installing system depencies with CPAN::Plugin::Sysdeps cpansand ALL=(ALL) NOPASSWD: /usr/bin/apt-get install * cpansand ALL=(ALL) NOPASSWD: /usr/bin/apt-get -y install * EOF $root->chmod(0440, '/etc/sudoers.d/20_cpansand'); chomp(my $zsh = `which zsh`); $root->user_account( username => 'cpansand', uid => 1234, shell => $zsh, ssh_keys => ['ssh-rsa ... '], ); my $cpansand = $d->do_sudo(sudo_opts => [qw(-u cpansand)]); # for running commands as cpansand user $cpansand->make_path("/home/cpansand/.cpan/build"); $cpansand->mkdir("/home/cpansand/.cpanreporter"); $cpansand->write_binary("/home/cpansand/.cpanreporter/config.ini", <<'EOF'); edit_report=default:no email_from=somebody@example.com send_report=default:yes fail:ask/yes transport = Metabase uri http://metabase.cpantesters.org/beta/ id_file /home/cpansand/.cpanreporter/somebody_metabase_id.json EOF ... Installation ------------ The distribution is installed like a normal CPAN distribution. You don't have to download it but use CPAN.pm or cpanm: cpan Doit or cpanm Doit An extracted tarball or git clone may be installed like this: perl Build.PL ./Build ./Build test ./Build install (on Windows use just "Build" instead of "./Build") The Build script itself is a Doit script and not implementing all features of a Module::Build-based script, but it provides some interesting actions like test_installed test_in_docker debian_package debian_package_with_docker You don't have to install the distribution at all --- just leave the extracted or cloned directory where it is and specify in your script use lib "/path/to/Doit/lib"; use Doit; Or if the extracted is relative to a script, say, in an "inc" subdirectory: use FindBin; use lib "$FindBin::RealBin/inc/Doit/lib"; use Doit;