#!/usr/bin/php -q <? chdir(__DIR__); define('VERSION','0.6.5'); define("SITES_PATH",reset(explode(basename(__DIR__),__DIR__))); define("DB_PW",generate_pw()); define("FTP_PW",generate_pw()); define("EMAIL_PW",generate_pw()); define("FINGERPRINT",strtoupper(generate_pw(20))); define("DEVELOPER",trim(get_current_user())); define("DEVELOPER_EMAIL",strtolower(DEVELOPER).'@bytestudios.com'); define("ICON",__DIR__.'/icon.png'); define("TEXTMATE",__DIR__.'/lib/mate'); define("CODA",__DIR__.'/lib/coda'); define("SUBL",__DIR__.'/lib/subl'); define("GROWL",__DIR__.'/lib/growlnotify'); $args = parse_args($argv); switch ($args['action']){ case 'new': install($args); break; case 'generate': generate($args); break; default: print_help(true); break; } function prompt_silent($prompt = "Enter password:"){ $command = "/usr/bin/env bash -c 'echo OK'"; if (rtrim(shell_exec($command)) !== 'OK') { trigger_error("Can't invoke bash"); return; } $command = "/usr/bin/env bash -c 'read -s -p \"" . addslashes($prompt) . "\" mypassword && echo \$mypassword'"; $password = rtrim(shell_exec($command)); echo "\n\n"; return $password; } function rrmdir($dir) { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object); } } reset($objects); if (rmdir($dir) && realpath(dirname(dirname($dir))) === realpath(SITES_PATH)){ #only print this if it's at the base directory echo "\033[00;31mdelete \033[00m/".basename($dir)."\n"; } } } function generate_pw($length=10){ $chars = "abcdefghijkmnopqrstuvwxyz023456789"; srand((double)microtime()*1000000); $i = 0; $pass = '' ; while ($i <= $length) { $num = rand() % 33; $tmp = substr($chars, $num, 1); $pass = $pass . $tmp; $i++; } return $pass; } function parse_args($argv) { $test = false; $force = false; foreach ($argv as $key=>$value){ if ($value === '--version' || $value === '-v') exit("Helm ".VERSION."\n"); if ($value === '--help' || $value === '-h') print_help(true); if ($value === '--pretend' || $value === '-p' || $value === '-pf' || $value === '-fp'){ $test = true; unset($argv[$key]); } if ($value === '-f' || $value === '--force' || $value === '-fp' || $value === '-pf'){ $force = true; unset($argv[$key]); } } $argv = array_values($argv); if (!count($argv)) print_help(true); $action = $argv[1]; switch ($action){ case 'new': $url = str_replace(array('http://','www.'),'',$argv[2]); $username = reset(explode('.',substr($url,0,16))); #16 character limit $name = strtolower($argv[3]); $args = array('action'=>$action, 'url'=>$url, 'username'=>$username); break; case 'generate': $type = $argv[2]; $name = strtolower($argv[3]); $args = array('action'=>$action, 'type'=>$type, 'name' => $name); break; default: break; } $args['test'] = (bool)$test; $args['force'] = (bool)$force; return $args; } function print_help($exit=false) { echo "usage: new siteurl.com\n\n--pretend\n-p\t\tpretend mode \tjust a dry run\n\n--force\n-f\t\tforce mode\tautomatically overwrite existing databases & directories\n\n"; if ($exit) exit; } function install($args){ $icon = ICON; $url = $args['url']; $username = $args['username']; $dir = SITES_PATH.$url; $webroot = '/httpdocs/'; echo "\n\033[1;32mcreate\t\033[00mremote ftp \033[1;30m\n\tuser: \033[1;33m{$username}\033[1;30m\n\tpass: \033[00;33m".FTP_PW."\033[1;30m\n\thost: \033[00;36m{$url}\033[00m\n\n"; echo "\033[1;32mcreate\t\033[00mremote db \033[1;30m\n\tuser: \033[1;33m{$username}\033[1;30m\n\tpass: \033[00;33m".DB_PW."\033[1;30m\n\thost: \033[00;36mlocalhost\033[00m\n\n"; enter_password: if (isset($output)) unset($output); $mamp_pw = prompt_silent('mysql root pw: '); $create_db_attempts = 0; retry_create_db: if (isset($output)) unset($output); $create_db_attempts++; $force = ($args['force']) ? '-f' : ''; exec("mysql {$force} -u root -e \"create database {$username} default character set utf8\" -p{$mamp_pw} 2>&1", $output, $return); if ($return){ if (stripos($output[0],'Can\'t connect to local MySQL server') !== false){ echo "\033[00;31mfail\033[00m can't connect to mysql\n"; echo "\033[1;32mlaunch \033[00mmamp pro\n"; if ($create_db_attempts <= 5): sleep(2); goto retry_create_db; else: exit("\033[00;31mfail\033[00m gave up\n"); endif; } if (stripos($output[0],'exists') !== false) echo "\n\033[1;33mskip \033[00mduplicate db \"{$username}\""; if (stripos($output[0],'Access denied for user') !== false){ echo "\033[00;31mfail\033[00m access denied \033[1;30m(typo?)\033[00m\n\n"; goto enter_password; } unset($output); } else { unset($output); exec("mysql {$force} -u root -e \"grant all privileges on {$username}.* to {$username}@localhost identified by '".DB_PW."'\" -p{$mamp_pw} 2>&1", $output, $return); if ($return) exit("\033[00;31m".$output[0]."\n"); unset($output); echo "\n\033[1;32mcreate\t\033[00mlocal db \033[1;30m\n\tuser: \033[1;33m{$username}\033[1;30m\n\tpass: \033[00;33m".DB_PW."\033[1;30m\n\thost: \033[00;36mlocalhost\033[00m\n\n"; } echo "\ncloning helm skeleton…\n"; if (!$args['test']){ if (file_exists(SITES_PATH.$url) && $args['force'] && $url) rrmdir(SITES_PATH.$url); exec("git clone --depth 1 ssh://git@wintermute.local/Users/git/skeleton.git {$dir}"); rrmdir(SITES_PATH."{$url}/.git"); rrmdir(SITES_PATH."{$url}/.gitattributes"); rrmdir(SITES_PATH."{$url}/.gitignore"); } echo "\033[1;32mclone \033[00mhelm skeleton\n"; exec("'".GROWL."' --title 'Git Clone Complete' --message 'helm skeleton' --name 'Helm' --image '{$icon}'"); echo "\ninitializing bare git repository…\n"; exec("ssh git@wintermute.local git init --bare {$username}.git"); echo "\033[1;32minitialize \033[00m{$username}.git\n"; exec("'".GROWL."' --title 'Git Init Complete' --message '{$username}.git' --name 'Helm' --image '{$icon}'"); $git_post_hook = "/Users/git/{$username}.git/hooks/post-receive"; exec("ssh root@wintermute.local touch '{$git_post_hook}'"); exec("ssh root@wintermute.local chmod 755 '{$git_post_hook}'"); exec("ssh root@wintermute.local 'echo \"#!/bin/sh\" > {$git_post_hook}'"); exec("ssh root@wintermute.local 'echo \"mkdir -p /Users/git/Sites/{$url}/httpdocs/\" >> {$git_post_hook}'"); exec("ssh root@wintermute.local 'echo \"GIT_WORK_TREE=/Users/git/Sites/{$url}/httpdocs/ git checkout -f\" >> {$git_post_hook}'"); chdir("{$dir}{$webroot}"); exec("git init"); exec("git config --global color.ui true"); exec("touch README"); exec("git add README"); exec("git commit -m 'initial commit'"); //exec("git remote add origin -m master deploy ssh://{$username}@spindle.bytestudios.com/var/www/vhosts/{$url}/private/deploy.git"); exec("git remote add origin ssh://git@wintermute.local/users/git/{$username}.git"); exec("git push --quiet -u origin master"); echo "\033[1;32mpush \033[00m{$username}.git\n"; exec("'".GROWL."' --title 'Pushed to remote repo' --message 'made your first push to {$username}.git' --name 'Helm' --image '{$icon}'"); $htaccess = <<<TPL Options +FollowSymlinks RewriteEngine on RewriteBase / #in development, this path is forwarding to the webroot of your site php_value auto_prepend_file "/var/www/vhosts/{$url}/httpdocs/@helm/init.php" TPL; if (!$args['test']){ if (!file_exists("{$dir}{$webroot}.htaccess")) exec("touch '{$dir}{$webroot}.htaccess'"); $previous_data = file_get_contents("{$dir}{$webroot}.htaccess"); file_put_contents("{$dir}{$webroot}.htaccess","{$htaccess}\n\n{$previous_data}"); } echo "\n\033[1;32mcreate \033[00m/{$webroot}.htaccess"; #write the configuration file if (!$args['test']){ if (file_exists("{$dir}{$webroot}/@helm/config/base.yml")){ $base_yml = file_get_contents("{$dir}{$webroot}/@helm/config/base.yml"); $database_match = "/db:\n\tmain:\n\t\thost: \n\t\tport: \n\t\tname: \n\t\tuser: \n\t\tpw: /"; $database_replace = "db:\n\tmain:\n\t\thost: \n\t\tport: 3306\n\t\tname: {$username}\n\t\tuser: {$username}\n\t\tpw: ".DB_PW; $base_yml = preg_replace($database_match, $database_replace, $base_yml); $site_match = "/site:\n\tname: \n\turl: \n\tfingerprint: /"; $site_replace = "site:\n\tname: {$username}\n\turl: {$url}\n\tfingerprint: ".FINGERPRINT; $base_yml = preg_replace($site_match, $site_replace, $base_yml); $social_match = "/\tfacebook: \n\ttwitter: \n\tyoutube: /"; $social_replace = "\tfacebook: {$username}\n\ttwitter: {$username}\n\tyoutube: {$username}"; $base_yml = preg_replace($social_match, $social_replace, $base_yml); $email_match = "/\temail:\n\t\taddress: \n\t\tpassword: /"; $email_replace = "\temail:\n\t\taddress: messenger@{$url}\n\t\tpassword: ".EMAIL_PW; $base_yml = preg_replace($email_match, $email_replace, $base_yml); $developer_match = "/\tdevelopers:\n/"; $developer_replace = "\tdevelopers:\n\t\t- ".DEVELOPER." <".DEVELOPER_EMAIL.">\n"; $base_yml = preg_replace($developer_match, $developer_replace, $base_yml); file_put_contents("{$dir}{$webroot}/@helm/config/base.yml",$base_yml); echo "\n\033[1;32mcreate \033[00mconfig files"; } } echo "\n\n\033[1;32m(▰˘◡˘▰)\n\n"; exec("open http://{$url}.build"); exec(SUBL." {$dir}{$webroot}"); exec("'".GROWL."' --title '{$username} Was Created!' --message '{$dir}{$webroot}' --name 'Helm' --image '{$icon}'"); } function generate($args){ if (!is_array($args) || (is_array($args) && !array_key_exists('name', $args))) print_help(true); $class = $args['name']; $full_path = "../@app/models/custom/{$args['name']}.php"; $template_str = get_template($class); if (file_exists($full_path)) exit("model already exists\n"); $file_result = file_put_contents($full_path, $template_str); if (!$file_result): exit("Error writing to models directory/file. Do you have sufficient privileges?\n"); else: $uclass = ucfirst($class); echo "\n\033[1;32mcreate \033[00m\"{$full_path}\"\n"; exec("php migrate/generate.php create_{$class}s"); echo "\n\033[1;32mcreate \033[00m\"../@app/db/migrate/20110102002_create_{$class}s.php\"\n\n"; echo "\tget started!\n\n"; echo "1. define your table structure in \"/@app/db/migrate/20110102002_create_{$class}s.php\".\n"; echo "2. run \033[1;32mhelm db:migrate\033[00m to create your {$class}s table.\n"; echo "3. run \033[1;32mhelm db:seed\033[00m to populate with test data.\n"; echo "4. \${$uclass} = new {$uclass}();\n \${$uclass}->find();\n \twhile(\${$uclass}->hasnext()){\n echo '{$uclass}->id';\n\t}\n\n"; endif; } function get_template($class){ $class = ucfirst($class); $template = <<<TPL <? class {$class} extends Record { #you don't need anything else here to use basic ORM functionality } ?> TPL; return $template; } ?>