Skip to content

Instantly share code, notes, and snippets.

@mberends
Created March 25, 2009 08:59
Show Gist options
  • Save mberends/85378 to your computer and use it in GitHub Desktop.
Save mberends/85378 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# NAME
# hello.bash - a canonical "hello, world!" project for proto
#
# SYNOPSIS
# bash hello.bash # creates and uploads everything in /tmp/hello
#
# DESCRIPTION
# Implements proto's PIONEER plan in code
cat <<EOF
This is 'hello.bash', a project generator for masak's 'proto' installer.
You first need to have done the following:
1. Create a github account at https://github.com/signup/free
2. Login to your github account: https://github.com/login
3. Create a new repository: http://github.com/repositories/new
4. Enter your Project Name, Description, optional Homepage and click Create.
5. This script will take care of the 'Next steps:' part.
If 'Create' worked, continue with this script, otherwise type Control-C to exit.
EOF
echo -n 'Git username :'
read GITUSER
echo -n 'Project name :'
read PROJECT
export GITUSER PROJECT
#Currently using github username $GITUSER, project name $PROJECT.
#Edit this script to change those.
# Begin with some steps from "Create New Repository" at github.com
cd /tmp
rm -rf $PROJECT # ensure a clean start every time
mkdir $PROJECT
cd $PROJECT
mkdir lib t
git init
# The project should consist mainly of Perl modules.
# Module files contain classes, roles, grammars and documentation.
mkdir lib/Example
cat >lib/Example/Hello.pm <<EOF
class Example::Hello
{
method greet { return "hello" }
method place { return "world" }
}
=begin pod
=head1 NAME
Example::Hello - canonical "hello, world!" project for proto
=head1 AUTHOR
$GITUSER ($GITUSER at github.com and @email.com)
=end pod
EOF
# Include a test suite to improve your karma (and your code quality)
# Beware the \ escapes for bash:
cat >t/01-simple.t <<EOF
use Example::Hello;
use Test;
plan 3;
my Example::Hello \$greeter .= new;
isa_ok( \$greeter, 'Example::Hello', 'create object' );
is( \$greeter.greet, 'hello', 'greet' );
is( \$greeter.place, 'world', 'place' );
EOF
# Create a Makefile.in like this example from mattw's form project.
# note the \$ escaping to play nicely with bash.
cat >Makefile.in <<EOF
RAKUDO=<RAKUDO>
RAKUDO_DIR=<RAKUDO_DIR>
SOURCES=lib/Example/Hello.pm
PIRS=\$(SOURCES:.pm=.pir)
all: \$(PIRS) lib/Test.pir
%.pir: %.pm
\$(RAKUDO) --target=pir --output=\$@ \$<
clean:
rm -f \$(PIRS)
tests: test
test: all
prove -e '\$(RAKUDO)'\
-r --nocolor t/
EOF
# The above 'Makefile.in' needs something active to convert it into a
# Makefile. Currently proto calls the the Perl 5 standard Makefile.PL.
# Also copied from mattw's form. Beware the many \ escapes for bash.
cat >Makefile.PL <<EOF
#!/usr/bin/perl
\$|++;
use strict;
use warnings;
use File::Spec;
my \$rakudo_dir = \$ENV{RAKUDO_DIR};
my \$parrot_dir = \$ENV{PARROT_DIR};
my \$rakudo;
\$rakudo_dir or \$parrot_dir or die 'Please set \$RAKUDO_DIR or \$PARROT_DIR (see README).'."\n";
\$ENV{PERL6LIB} or die 'Please set \$PERL6LIB (see README).'."\n";
if ( ! \$rakudo_dir ) {
# we have to assume rakudo-inside-parrot
# and synthesise a rakudo_dir from that
# We know we have parrot_dir if we got this far
if ( ! -d \$parrot_dir ) {
die <<EOT;
Not a directory \$parrot_dir, no \\\$RAKUDO_DIR provided.
Please set \\\$RAKUDO_DIR or \\\$PARROT_DIR correctly (see README).
EOT
}
\$rakudo_dir = File::Spec->catfile(\$parrot_dir, 'languages', 'rakudo');
}
if ( \$rakudo_dir ) {
if ( ! -d \$rakudo_dir ) {
die <<EOT
Not a directory \$rakudo_dir.
Please set \\\$RAKUDO_DIR or \\\$PARROT_DIR correctly (see README).
EOT
}
else {
if ( ! \$parrot_dir ) {
# parrot-inside-rakudo
\$parrot_dir = File::Spec->catfile(\$rakudo_dir, 'parrot');
}
\$rakudo = File::Spec->catfile(\$rakudo_dir, 'perl6');
if ( ! -x \$rakudo ) {
# try 'parrot perl6.pbc'
my \$parrot = File::Spec->catfile(\$parrot_dir, 'parrot');
if ( ! -x \$parrot ) {
# that's it, no more options
die <<EOT
Not an executable \$rakudo
Not an executable \$parrot
Please set \\\$RAKUDO_DIR or \\\$PARROT_DIR correctly.
Please ensure you have built Rakudo in those locations.
See README for further information.
EOT
}
my \$rakudo_pbc = File::Spec->catfile(\$rakudo_dir, 'perl6.pbc');
if ( ! -f \$rakudo_pbc ) {
die <<EOT
Not an executable \$rakudo
File not found \$rakudo_pbc
Please set \\\$RAKUDO_DIR or \\\$PARROT_DIR correctly.
Please ensure you have built Rakudo in those locations.
See README for further information.
EOT
}
\$rakudo = "\$parrot \$rakudo_pbc";
}
}
}
print <<EOT;
Using Rakudo: \$rakudo
RAKUDO_DIR: \$rakudo_dir
PARROT_DIR: \$parrot_dir
EOT
my @infiles = map { \$_.'.in' } qw< Makefile >;
my %replacements = (
PARROT_DIR => \$parrot_dir,
RAKUDO_DIR => \$rakudo_dir,
RAKUDO => \$rakudo
);
if ( !-e 'lib/Test.pm' ) {
# Note: bad: this won't work on Windows
# Maybe we should be ensuring \$rakudo_dir is in PERL6LIB?
!system("ln -s \$rakudo_dir/Test.pm lib/") or die @!;
print "Symlinked Test.pm from the Rakudo directory \n";
}
for my \$infile (@infiles) {
if ((my \$outfile = \$infile) =~ s/\.in\$//g) {
open my \$IN, '<', \$infile or die "Couldn't open \$infile, \$!, \$?";
open my \$OUT, '>', \$outfile or die "Couldn't open \$outfile, \$!, \$?";
while (my \$line = <\$IN>) {
while ( \$line =~ /<(.*?)>/g ) {
my \$repl = \$1;
if (exists \$replacements{\$repl}) {
\$line =~ s/<\$repl>/\$replacements{\$repl}/g;
}
}
print \$OUT \$line;
}
print "Created \$outfile \n";
}
}
EOF
# Notify proto about dependencies on other modules. The installer will
# ensure that PERL6LIB can also find the content of their lib
# directories so that 'use thatmodule;' Just Works.
cat >deps.proto <<EOF
form
EOF
# Some more steps from "Create New Repository" at github.com
git add deps.proto Makefile* lib/Example/* t/*
git commit -m 'first commit'
git remote add origin git@github.com:$GITUSER/$PROJECT.git
git push origin master
# Add these lines to proto's modules.list
cat <<EOF
6. If there were NO errors above, your repository on github should be ready:
in your browser click on 'continue' or
http://github.com/$GITUSER/$PROJECT/tree/master
7. Ask a proto maintainer to add these lines to 'modules.list', or simply
edit your local copy:
$PROJECT:
home: github
owner: $GITUSER
8. Then you should be able to install your project:
./proto install $PROJECT
Now your work really starts :)
9. Replace proto/projects/$PROJECT/lib/Example/Hello.pm with your module file(s)
and update SOURCES in proto/projects/$PROJECT/Makefile.in accordingly.
Run 'perl Makefile.PL' after each change to Makefile.in.
10. Add README, LICENCE and other instructions.
11. Revise and extend proto/projects/$PROJECT/t/01-simple.t as well, and run
'make test' after every change that affects execution of your code.
12. Use 'git push' early and often.
EOF
# Discussion points from mberends:
# 1. proto should provide the universally required utilities
# - most projects currently need to bring their own
# - a Makefile builder
# - a test harness
# - proto could already install them as standard projects
# 2. Makefile.in
# - masak's http://gist.github.com/83545 would help
# 3. PERL6LIB
# - proto currently appends a :$PROJECT/lib per module
# - mberends would prefer it fairly constant even with many modules
# - would need proto/projects/lib or equivalent
# 4. Makefile.PL versus Configure.p6
# - Makefile.PL is now. Depends on Perl 5, but that's still OK.
# - Configure.p6 could be future, works in Pod::Parser etc.
# 5. modules.list
# - proto maintainers control content
# - http://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar
# - results in (some) cathedral engineering
# - move modules.list info to $PROJECT/deps.proto for a bazaar
# 6. Test::Harness
# - Currently Perl 5 based
# - perl6-examples has a working embryonic Perl 6 replacement
# - Test.pm is Perl 6 anyway and Makefile.PL symlinks to <RAKUDO_DIR>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment