diff --git a/code/CSSAbsolutePathRewriter.php b/code/CSSAbsolutePathRewriter.php
index 215b442..500e7a2 100644
--- a/code/CSSAbsolutePathRewriter.php
+++ b/code/CSSAbsolutePathRewriter.php
@@ -5,63 +5,73 @@
*
* @package compass
*/
-class CSSAbsolutePathRewriter extends Requirements_Backend {
-
- function css($file, $media = null) {
- $isurl = (bool)preg_match('{^\w+://}', $file);
- return parent::css($isurl ? $file : $this->baseRewrite($file), $media);
- }
+class CSSAbsolutePathRewriter extends Requirements_Backend
+{
+
+ public function css($file, $media = null)
+ {
+ $isurl = (bool)preg_match('{^\w+://}', $file);
+ return parent::css($isurl ? $file : $this->baseRewrite($file), $media);
+ }
- function customCSS($script, $uniquenessID = null) {
- return parent::customCSS($this->baseReplace($script), $uniquenessID);
- }
-
- function baseReplace($css) {
- return str_replace('BASE', Director::baseURL(), $css);
- }
-
- function baseRewrite($file) {
- if (preg_match('/^(jsparty|sapphire|cms)/', $file)) return $file;
-
- $name = basename($file, '.css');
- $dir = dirname($file);
- $path = BASE_PATH.'/'.$file;
-
- $hash = sha1(Director::baseURL());
- $tstamp = filemtime($path);
-
- $out = str_replace('/', '_', $dir)."_{$name}_{$hash}_{$tstamp}.css";
-
- $lnkname = "{$dir}/{$out}";
- $outname = 'assets/'.$out;
- $outpath = BASE_PATH.'/'.$outname;
-
- if (!file_exists($outpath)) {
- $css = file_get_contents($path);
- if (strpos($css, 'BASE') === FALSE) return $file;
-
- file_put_contents($outpath, $this->baseReplace($css));
- }
-
- return $lnkname;
- }
-
- /**
- * Default includeInHTML strips out CSS if the file doesn't exist. We need to add it back in if it's a redirected rewrite
- * @see sapphire/core/Requirements_Backend#includeInHTML($templateFile, $content)
- */
- function includeInHTML($templateFile, $content) {
- $content = parent::includeInHTML($templateFile, $content);
- $requirements = '';
-
- foreach(array_diff_key($this->css,$this->blocked) as $file => $params) {
- $path = self::path_for_file($file);
- if (!$path && ($path = self::path_for_file('assets/'.basename($file)))) {
- $media = (isset($params['media']) && !empty($params['media'])) ? " media=\"{$params['media']}\"" : "";
- $requirements .= "\n";
- }
- }
-
- return preg_replace("/(<\/head[^>]*>)/i", $requirements . "\\1", $content);
- }
-}
\ No newline at end of file
+ public function customCSS($script, $uniquenessID = null)
+ {
+ return parent::customCSS($this->baseReplace($script), $uniquenessID);
+ }
+
+ public function baseReplace($css)
+ {
+ return str_replace('BASE', Director::baseURL(), $css);
+ }
+
+ public function baseRewrite($file)
+ {
+ if (preg_match('/^(jsparty|sapphire|cms)/', $file)) {
+ return $file;
+ }
+
+ $name = basename($file, '.css');
+ $dir = dirname($file);
+ $path = BASE_PATH.'/'.$file;
+
+ $hash = sha1(Director::baseURL());
+ $tstamp = filemtime($path);
+
+ $out = str_replace('/', '_', $dir)."_{$name}_{$hash}_{$tstamp}.css";
+
+ $lnkname = "{$dir}/{$out}";
+ $outname = 'assets/'.$out;
+ $outpath = BASE_PATH.'/'.$outname;
+
+ if (!file_exists($outpath)) {
+ $css = file_get_contents($path);
+ if (strpos($css, 'BASE') === false) {
+ return $file;
+ }
+
+ file_put_contents($outpath, $this->baseReplace($css));
+ }
+
+ return $lnkname;
+ }
+
+ /**
+ * Default includeInHTML strips out CSS if the file doesn't exist. We need to add it back in if it's a redirected rewrite
+ * @see sapphire/core/Requirements_Backend#includeInHTML($templateFile, $content)
+ */
+ public function includeInHTML($templateFile, $content)
+ {
+ $content = parent::includeInHTML($templateFile, $content);
+ $requirements = '';
+
+ foreach (array_diff_key($this->css, $this->blocked) as $file => $params) {
+ $path = self::path_for_file($file);
+ if (!$path && ($path = self::path_for_file('assets/'.basename($file)))) {
+ $media = (isset($params['media']) && !empty($params['media'])) ? " media=\"{$params['media']}\"" : "";
+ $requirements .= "\n";
+ }
+ }
+
+ return preg_replace("/(<\/head[^>]*>)/i", $requirements . "\\1", $content);
+ }
+}
diff --git a/code/Compass.php b/code/Compass.php
index 6ca47ab..b868473 100644
--- a/code/Compass.php
+++ b/code/Compass.php
@@ -3,376 +3,431 @@
/**
* @package compass
*/
-class Compass extends Controller {
-
- /**
- * @var array
- */
- public static $url_handlers = array(
- '$Action' => '$Action'
- );
+class Compass extends Controller
+{
+
+ /**
+ * @var array
+ */
+ public static $url_handlers = array(
+ '$Action' => '$Action'
+ );
- /**
- * @var bool Are compass errors actually errors, or should we just ignore
- * them? True means complain, false means don't, null means don't complain
- * on live servers, do otherwise.
- */
- public static $errors_are_errors = null;
-
- /**
- * @var bool Set to true to force no automatic rebuilding, even if isDev()
- * is true or flush is passed and the gems are all available.
- */
- public static $force_no_rebuild = false;
+ /**
+ * @var bool Are compass errors actually errors, or should we just ignore
+ * them? True means complain, false means don't, null means don't complain
+ * on live servers, do otherwise.
+ */
+ public static $errors_are_errors = null;
+
+ /**
+ * @var bool Set to true to force no automatic rebuilding, even if isDev()
+ * is true or flush is passed and the gems are all available.
+ */
+ public static $force_no_rebuild = false;
- /**
- * @var float Which version of sass should we use.
- */
- public static $sass_version = '3';
-
- /**
- * @var string - preferred syntax to use.
- */
- public static $syntax = "scss";
+ /**
+ * @var float Which version of sass should we use.
+ */
+ public static $sass_version = '3';
+
+ /**
+ * @var string - preferred syntax to use.
+ */
+ public static $syntax = "scss";
- /**
- * @var array map of required gems for each version.
- */
- public static $required_gems = array(
- '2' => array(
- 'yard' => '', 'maruku' => '', 'haml' => '~> 2.2', 'compass' => '~> 0.8.0', 'compass-colors' => ''
- ),
- '3' => array(
- 'yard' => '', 'maruku' => '', 'sass' => '~>3.2', 'compass' => '~> 0.12.2', 'compass-colors' => ''
- ),
- 'latest' => array(
- 'yard' => '', 'maruku' => '', 'sass' => '', 'compass' => '', 'compass-colors' => ''
- )
- );
-
- /**
- * @var bool Internal cache variable - is the version of rubygems currently
- * available good enough?
- */
- private static $check_gems_result = null;
-
- /**
- * Directory to store sass cache. Defaults to temp_folder/.sass.
- *
- * @see set_tmp_dir()
- * @var string
- */
- private static $temp_dir;
-
-
- protected function checkGems() {
- if (self::$check_gems_result === null) {
-
- self::$check_gems_result = true;
-
- foreach (self::$required_gems[self::$sass_version] as $gem => $version) {
- if(!$version) $version = ">= 0";
-
- if($error = Rubygems::require_gem($gem, $version)) {
- self::$check_gems_result = $error;
- }
- }
- }
-
- return self::$check_gems_result;
- }
+ /**
+ * @var array map of required gems for each version.
+ */
+ public static $required_gems = array(
+ '2' => array(
+ 'yard' => '', 'maruku' => '', 'haml' => '~> 2.2', 'compass' => '~> 0.8.0', 'compass-colors' => ''
+ ),
+ '3' => array(
+ 'yard' => '', 'maruku' => '', 'sass' => '~>3.2', 'compass' => '~> 0.12.2', 'compass-colors' => ''
+ ),
+ 'latest' => array(
+ 'yard' => '', 'maruku' => '', 'sass' => '', 'compass' => '', 'compass-colors' => ''
+ )
+ );
+
+ /**
+ * @var bool Internal cache variable - is the version of rubygems currently
+ * available good enough?
+ */
+ private static $check_gems_result = null;
+
+ /**
+ * Directory to store sass cache. Defaults to temp_folder/.sass.
+ *
+ * @see set_tmp_dir()
+ * @var string
+ */
+ private static $temp_dir;
+
+
+ protected function checkGems()
+ {
+ if (self::$check_gems_result === null) {
+ self::$check_gems_result = true;
+
+ foreach (self::$required_gems[self::$sass_version] as $gem => $version) {
+ if (!$version) {
+ $version = ">= 0";
+ }
+
+ if ($error = Rubygems::require_gem($gem, $version)) {
+ self::$check_gems_result = $error;
+ }
+ }
+ }
+
+ return self::$check_gems_result;
+ }
- static function error($message) {
- // If errors_are_errors is null, work out if it should be true or false based on server mode
- if (self::$errors_are_errors === null) {
- $runningTest = class_exists('SapphireTest',false) && SapphireTest::is_running_test();
- self::$errors_are_errors = Director::isDev() && !$runningTest;
- }
+ public static function error($message)
+ {
+ // If errors_are_errors is null, work out if it should be true or false based on server mode
+ if (self::$errors_are_errors === null) {
+ $runningTest = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
+ self::$errors_are_errors = Director::isDev() && !$runningTest;
+ }
- // Then raise the actual error (if errors are errors)
- if (self::$errors_are_errors) user_error('Compass Error:
' . preg_replace('/[\r\n]+/', '
', $message), E_USER_ERROR);
- return false;
- }
-
- public function init() {
- parent::init();
-
- // We allow access to this controller regardless of live-status or
- // ADMIN permission only if on CLI. Access to this controller is
- // always allowed in "dev-mode", or of the user is ADMIN.
-
- $canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN"));
-
- if (!$canAccess) {
- return Security::permissionFailure($this);
- }
- }
-
- /**
- * Convert a css based theme to a sass based one
- *
- * Designed to be called as a sake command
- *
- *
- * sapphire/sake dev/compass/convert --theme=blackcandy
- *
- *
- * @param bool $verbose to anything positive to output
- * status (calling as a controller passed HTTPRequest, which is good enough)
- */
- function convert($verbose = false) {
- $dir = null;
-
- if (@$_GET['theme']) $dir = THEMES_PATH . DIRECTORY_SEPARATOR . $_GET['theme'];
- if (@$_GET['module']) $dir = BASE_PATH . DIRECTORY_SEPARATOR . $_GET['module'];
+ // Then raise the actual error (if errors are errors)
+ if (self::$errors_are_errors) {
+ user_error('Compass Error:
' . preg_replace('/[\r\n]+/', '
', $message), E_USER_ERROR);
+ }
+ return false;
+ }
+
+ public function init()
+ {
+ parent::init();
+
+ // We allow access to this controller regardless of live-status or
+ // ADMIN permission only if on CLI. Access to this controller is
+ // always allowed in "dev-mode", or of the user is ADMIN.
- // Check for no arguments
- if (!$dir) {
- echo "\n";
- echo "Usage: convert --module=module | convert --theme=theme\n";
- echo "Alternatively, use convertTheme or convertModule\n\n";
- exit();
- }
-
- // Check the directory exists
- if (!is_dir($dir)) {
- echo "\nERROR:\n\nPath $dir doesn't exist.\n\n";
- exit();
- }
-
- // And has css in it
- if (!is_dir($dir . DIRECTORY_SEPARATOR . 'css')) {
- echo "\nERROR:\n\nPath $dir doesn't contain any css\n\n";
- exit();
- }
-
- // And doesn't have sass commands in it
- if(is_dir($dir . DIRECTORY_SEPARATOR . self::$syntax)) {
- if (!@$_GET['force'] && array_search('--force', (array)@$_GET['args']) === false) {
- echo "\nERROR:\n\nPath $dir is already a compass or sass based theme or module.\nUse --force to force overwriting\n\n";
- exit();
- }
- }
-
- self::generate_config($dir);
-
- // Make sure the gems we need are available
- if (($error = $this->checkGems()) !== true) return self::error($error);
+ $canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN"));
+
+ if (!$canAccess) {
+ return Security::permissionFailure($this);
+ }
+ }
+
+ /**
+ * Convert a css based theme to a sass based one
+ *
+ * Designed to be called as a sake command
+ *
+ *
+ * sapphire/sake dev/compass/convert --theme=blackcandy
+ *
+ *
+ * @param bool $verbose to anything positive to output
+ * status (calling as a controller passed HTTPRequest, which is good enough)
+ */
+ public function convert($verbose = false)
+ {
+ $dir = null;
+
+ if (@$_GET['theme']) {
+ $dir = THEMES_PATH . DIRECTORY_SEPARATOR . $_GET['theme'];
+ }
+ if (@$_GET['module']) {
+ $dir = BASE_PATH . DIRECTORY_SEPARATOR . $_GET['module'];
+ }
- $this->recursivelyConvert($dir.DIRECTORY_SEPARATOR.'css', $dir.DIRECTORY_SEPARATOR.'sass');
-
- if ($verbose) echo "\nConversion succesfull\n";
- }
-
- protected function recursivelyConvert($from, $to) {
-
- $dir = dir($from);
- if (!is_dir($to)) mkdir($to);
-
- while ($entry = $dir->read()) {
-
- $from_ = $from.DIRECTORY_SEPARATOR.$entry;
-
- if (fnmatch('.*', $entry)) continue;
-
- if (is_dir($from_)) {
- $this->recursivelyConvert($from_, $to.DIRECTORY_SEPARATOR.$entry);
- }
-
- else if (fnmatch('*.css', $entry) && is_file($from_)) {
-
- $to_ = $to.DIRECTORY_SEPARATOR.preg_replace('/.css$/', '.sass', $entry);
-
- $res = Rubygems::run(self::$required_gems[self::$sass_version], 'css2sass', "'$from_' '$to_'", $out, $err);
-
- if ($res != 0) {
- echo "\nError converting ".Director::makeRelative($from_)."\n\nError from css2sass was:\n$err";
- }
- }
- }
- }
+ // Check for no arguments
+ if (!$dir) {
+ echo "\n";
+ echo "Usage: convert --module=module | convert --theme=theme\n";
+ echo "Alternatively, use convertTheme or convertModule\n\n";
+ exit();
+ }
+
+ // Check the directory exists
+ if (!is_dir($dir)) {
+ echo "\nERROR:\n\nPath $dir doesn't exist.\n\n";
+ exit();
+ }
+
+ // And has css in it
+ if (!is_dir($dir . DIRECTORY_SEPARATOR . 'css')) {
+ echo "\nERROR:\n\nPath $dir doesn't contain any css\n\n";
+ exit();
+ }
+
+ // And doesn't have sass commands in it
+ if (is_dir($dir . DIRECTORY_SEPARATOR . self::$syntax)) {
+ if (!@$_GET['force'] && array_search('--force', (array)@$_GET['args']) === false) {
+ echo "\nERROR:\n\nPath $dir is already a compass or sass based theme or module.\nUse --force to force overwriting\n\n";
+ exit();
+ }
+ }
+
+ self::generate_config($dir);
+
+ // Make sure the gems we need are available
+ if (($error = $this->checkGems()) !== true) {
+ return self::error($error);
+ }
- /**
- * Utility function that returns an array of all themes.
- *
- * @return array
- */
- protected function getAllThemes() {
- $baseDir = BASE_PATH . DIRECTORY_SEPARATOR . THEMES_DIR;
-
- $themes = array();
-
- if(is_dir($baseDir)) {
- $dir = dir($baseDir);
-
- while ($file = $dir->read()) {
- $fullPath = $baseDir . DIRECTORY_SEPARATOR . $file;
- if (strpos($file, '.') === false && is_dir($fullPath)) $themes[$file] = $file;
- }
- }
-
- return $themes;
- }
+ $this->recursivelyConvert($dir.DIRECTORY_SEPARATOR.'css', $dir.DIRECTORY_SEPARATOR.'sass');
+
+ if ($verbose) {
+ echo "\nConversion succesfull\n";
+ }
+ }
+
+ protected function recursivelyConvert($from, $to)
+ {
+ $dir = dir($from);
+ if (!is_dir($to)) {
+ mkdir($to);
+ }
+
+ while ($entry = $dir->read()) {
+ $from_ = $from.DIRECTORY_SEPARATOR.$entry;
+
+ if (fnmatch('.*', $entry)) {
+ continue;
+ }
+
+ if (is_dir($from_)) {
+ $this->recursivelyConvert($from_, $to.DIRECTORY_SEPARATOR.$entry);
+ } elseif (fnmatch('*.css', $entry) && is_file($from_)) {
+ $to_ = $to.DIRECTORY_SEPARATOR.preg_replace('/.css$/', '.sass', $entry);
+
+ $res = Rubygems::run(self::$required_gems[self::$sass_version], 'css2sass', "'$from_' '$to_'", $out, $err);
+
+ if ($res != 0) {
+ echo "\nError converting ".Director::makeRelative($from_)."\n\nError from css2sass was:\n$err";
+ }
+ }
+ }
+ }
- /**
- * Utility function that returns an array of all modules.
- *
- * @return array Map of module names to their path
- */
- protected function getAllModules() {
- $modules = array();
-
- if(class_exists('SS_ClassLoader')) {
- // SilverStripe 3.x
- $modules = SS_ClassLoader::instance()->getManifest()->getModules();
- } else {
- // SilverStripe 2.x
- global $_CLASS_MANIFEST;
- $paths = $_CLASS_MANIFEST;
- foreach ($paths as $path) {
- if (preg_match('#'.preg_quote(BASE_PATH, '#').'/([^/]+)/#', $path, $matches)) {
- $modules[$matches[1]] = BASE_PATH . DIRECTORY_SEPARATOR . $matches[1];
- }
- }
- }
+ /**
+ * Utility function that returns an array of all themes.
+ *
+ * @return array
+ */
+ protected function getAllThemes()
+ {
+ $baseDir = BASE_PATH . DIRECTORY_SEPARATOR . THEMES_DIR;
+
+ $themes = array();
+
+ if (is_dir($baseDir)) {
+ $dir = dir($baseDir);
+
+ while ($file = $dir->read()) {
+ $fullPath = $baseDir . DIRECTORY_SEPARATOR . $file;
+ if (strpos($file, '.') === false && is_dir($fullPath)) {
+ $themes[$file] = $file;
+ }
+ }
+ }
+
+ return $themes;
+ }
- return $modules;
- }
-
- /**
- * Convert the sass files to css files
- *
- * Called automatically on dev machines, and when flush=all. Can also be
- * called as a sake command (sapphire/sake dev/compass/rebuild).
- *
- * Set $verbose to anything positive to output status (calling as a
- * controller passed HTTPRequest, which is good enough).
- *
- * @param bool $verbose - use Compass::$errors_are_errors = false to suppress.
- */
- function rebuild($verbose = false) {
- // Make sure the gems we need are available
- if (($error = $this->checkGems()) !== true) return self::error($error);
+ /**
+ * Utility function that returns an array of all modules.
+ *
+ * @return array Map of module names to their path
+ */
+ protected function getAllModules()
+ {
+ $modules = array();
+
+ if (class_exists('SS_ClassLoader')) {
+ // SilverStripe 3.x
+ $modules = SS_ClassLoader::instance()->getManifest()->getModules();
+ } else {
+ // SilverStripe 2.x
+ global $_CLASS_MANIFEST;
+ $paths = $_CLASS_MANIFEST;
+ foreach ($paths as $path) {
+ if (preg_match('#'.preg_quote(BASE_PATH, '#').'/([^/]+)/#', $path, $matches)) {
+ $modules[$matches[1]] = BASE_PATH . DIRECTORY_SEPARATOR . $matches[1];
+ }
+ }
+ }
- $dir = null;
-
- if (@$_GET['theme']) $dir = THEMES_PATH . DIRECTORY_SEPARATOR . $_GET['theme'];
- if (@$_GET['module']) $dir = BASE_PATH . DIRECTORY_SEPARATOR . $_GET['module'];
+ return $modules;
+ }
+
+ /**
+ * Convert the sass files to css files
+ *
+ * Called automatically on dev machines, and when flush=all. Can also be
+ * called as a sake command (sapphire/sake dev/compass/rebuild).
+ *
+ * Set $verbose to anything positive to output status (calling as a
+ * controller passed HTTPRequest, which is good enough).
+ *
+ * @param bool $verbose - use Compass::$errors_are_errors = false to suppress.
+ */
+ public function rebuild($verbose = false)
+ {
+ // Make sure the gems we need are available
+ if (($error = $this->checkGems()) !== true) {
+ return self::error($error);
+ }
- if ($dir) {
- $this->rebuildDirectory($dir);
- }
- else {
- if ($verbose) echo "\nRebuilding all\n";
-
- foreach ($this->getAllThemes() as $theme) {
- $dir = THEMES_PATH . DIRECTORY_SEPARATOR . $theme;
-
- if (file_exists($dir . DIRECTORY_SEPARATOR . 'config.rb')) {
- if ($verbose) echo "\nRebuilding theme: $theme\n";
- $this->rebuildDirectory($dir);
- }
- }
+ $dir = null;
+
+ if (@$_GET['theme']) {
+ $dir = THEMES_PATH . DIRECTORY_SEPARATOR . $_GET['theme'];
+ }
+ if (@$_GET['module']) {
+ $dir = BASE_PATH . DIRECTORY_SEPARATOR . $_GET['module'];
+ }
- foreach ($this->getAllModules() as $name => $path) {
- // If this is in the compass module, skip
- if ($name == 'compass') continue;
-
- if (file_exists($path . DIRECTORY_SEPARATOR . 'config.rb')) {
- if ($verbose) echo "\nRebuilding module: $name\n";
- $this->rebuildDirectory($path);
- }
- }
- }
-
- if ($verbose) echo "\nRebuild succesfull\n";
- }
-
- /**
- * Rebuild the scss files from a given directory
- *
- * @param string $dir
- */
- protected function rebuildDirectory($dir) {
- if (!is_dir($dir)) return self::error("Could not rebuild $dir, as it doesn't exist");
-
- self::generate_config($dir);
-
- $orig = getcwd();
- chdir($dir);
-
- $args = (self::$sass_version > 2) ? "compile -e production ": "";
- if(isset($_REQUEST['flush'])) $args .= "--force";
-
- $code = Rubygems::run(self::$required_gems[self::$sass_version], "compass", $args, $out, $err);
- chdir($orig);
-
- if ($code !== 0) return self::error($err);
- }
+ if ($dir) {
+ $this->rebuildDirectory($dir);
+ } else {
+ if ($verbose) {
+ echo "\nRebuilding all\n";
+ }
+
+ foreach ($this->getAllThemes() as $theme) {
+ $dir = THEMES_PATH . DIRECTORY_SEPARATOR . $theme;
+
+ if (file_exists($dir . DIRECTORY_SEPARATOR . 'config.rb')) {
+ if ($verbose) {
+ echo "\nRebuilding theme: $theme\n";
+ }
+ $this->rebuildDirectory($dir);
+ }
+ }
- /**
- * Make sure the compass and sass gems are up to date.
- *
- * If the gems are not present, the system will install them automatically,
- * but won't update them after that for speeds sake. Call this from sake to
- * ensure you've got the most up-to-date version.
- *
- * Designed to be called as a sake command:
- *
- * sapphire/sake dev/compass/updategems
- *
- *
- * @param bool $verbose - use Compass::$errors_are_errors = false to suppress.
- *
- */
- public function updategems($verbose = false) {
- foreach (self::$required_gems[self::$sass_version] as $gem => $version) {
- if (is_numeric($gem)) { $gem = $version; $version = null; }
- if ($error = Rubygems::require_gem($gem, $version, true)) echo $error;
- }
-
- if ($verbose) echo "\nGem update succesfull\n";
- }
-
- /**
- * Generate a configuration file for a given directory
- *
- * @param string - folder name
- */
- protected function generate_config($dir) {
- if(!is_file($dir . DIRECTORY_SEPARATOR . 'config.rb')) {
- file_put_contents(
- $dir . DIRECTORY_SEPARATOR . 'config.rb',
- $this->customise(new ArrayData(array(
- 'TmpDir' => self::get_temp_dir(),
- 'Mode' => self::$syntax
- )))->renderWith('CompassConfig')
- );
- }
- }
-
- /**
- * Set the temp directory for storing the compass cache. Path should be a folder
- * to filesystem which is writable by the web server.
- *
- * @param string
- */
- public static function set_temp_dir($dir) {
- self::$temp_dir = $dir;
- }
-
- /**
- * Return the temp directory for storing the sass cache. Path should be writable
- * by the web server.
- *
- * @return string
- */
- public static function get_temp_dir() {
- if(!self::$temp_dir)
- return Controller::join_links(TEMP_FOLDER, '.sass-cache');
-
- return self::$temp_dir;
- }
+ foreach ($this->getAllModules() as $name => $path) {
+ // If this is in the compass module, skip
+ if ($name == 'compass') {
+ continue;
+ }
+
+ if (file_exists($path . DIRECTORY_SEPARATOR . 'config.rb')) {
+ if ($verbose) {
+ echo "\nRebuilding module: $name\n";
+ }
+ $this->rebuildDirectory($path);
+ }
+ }
+ }
+
+ if ($verbose) {
+ echo "\nRebuild succesfull\n";
+ }
+ }
+
+ /**
+ * Rebuild the scss files from a given directory
+ *
+ * @param string $dir
+ */
+ protected function rebuildDirectory($dir)
+ {
+ if (!is_dir($dir)) {
+ return self::error("Could not rebuild $dir, as it doesn't exist");
+ }
+
+ self::generate_config($dir);
+
+ $orig = getcwd();
+ chdir($dir);
+
+ $args = (self::$sass_version > 2) ? "compile -e production ": "";
+ if (isset($_REQUEST['flush'])) {
+ $args .= "--force";
+ }
+
+ $code = Rubygems::run(self::$required_gems[self::$sass_version], "compass", $args, $out, $err);
+ chdir($orig);
+
+ if ($code !== 0) {
+ return self::error($err);
+ }
+ }
+
+ /**
+ * Make sure the compass and sass gems are up to date.
+ *
+ * If the gems are not present, the system will install them automatically,
+ * but won't update them after that for speeds sake. Call this from sake to
+ * ensure you've got the most up-to-date version.
+ *
+ * Designed to be called as a sake command:
+ *
+ * sapphire/sake dev/compass/updategems
+ *
+ *
+ * @param bool $verbose - use Compass::$errors_are_errors = false to suppress.
+ *
+ */
+ public function updategems($verbose = false)
+ {
+ foreach (self::$required_gems[self::$sass_version] as $gem => $version) {
+ if (is_numeric($gem)) {
+ $gem = $version;
+ $version = null;
+ }
+ if ($error = Rubygems::require_gem($gem, $version, true)) {
+ echo $error;
+ }
+ }
+
+ if ($verbose) {
+ echo "\nGem update succesfull\n";
+ }
+ }
+
+ /**
+ * Generate a configuration file for a given directory
+ *
+ * @param string - folder name
+ */
+ protected function generate_config($dir)
+ {
+ if (!is_file($dir . DIRECTORY_SEPARATOR . 'config.rb')) {
+ file_put_contents(
+ $dir . DIRECTORY_SEPARATOR . 'config.rb',
+ $this->customise(new ArrayData(array(
+ 'TmpDir' => self::get_temp_dir(),
+ 'Mode' => self::$syntax
+ )))->renderWith('CompassConfig')
+ );
+ }
+ }
+
+ /**
+ * Set the temp directory for storing the compass cache. Path should be a folder
+ * to filesystem which is writable by the web server.
+ *
+ * @param string
+ */
+ public static function set_temp_dir($dir)
+ {
+ self::$temp_dir = $dir;
+ }
+
+ /**
+ * Return the temp directory for storing the sass cache. Path should be writable
+ * by the web server.
+ *
+ * @return string
+ */
+ public static function get_temp_dir()
+ {
+ if (!self::$temp_dir) {
+ return Controller::join_links(TEMP_FOLDER, '.sass-cache');
+ }
+
+ return self::$temp_dir;
+ }
}
/**
@@ -384,21 +439,30 @@ public static function get_temp_dir() {
*
* @package compass
*/
-class Compass_RebuildDecorator extends DataExtension {
-
- public function init() {
- // Don't auto-rebuild if explicitly disabled
- if (Compass::$force_no_rebuild) return;
-
- // Don't auto-rebuild in test mode
- $runningTest = class_exists('SapphireTest',false) && SapphireTest::is_running_test();
- if ($runningTest) return;
+class Compass_RebuildDecorator extends DataExtension
+{
+
+ public function init()
+ {
+ // Don't auto-rebuild if explicitly disabled
+ if (Compass::$force_no_rebuild) {
+ return;
+ }
+
+ // Don't auto-rebuild in test mode
+ $runningTest = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
+ if ($runningTest) {
+ return;
+ }
- // If we are in dev mode, or flush called, auto-rebuild
- if (Director::isDev() || @$_GET['flush']) singleton('Compass')->rebuild();
- }
-
- public function contentcontrollerInit() {
- return $this->init();
- }
+ // If we are in dev mode, or flush called, auto-rebuild
+ if (Director::isDev() || @$_GET['flush']) {
+ singleton('Compass')->rebuild();
+ }
+ }
+
+ public function contentcontrollerInit()
+ {
+ return $this->init();
+ }
}
diff --git a/code/Rubygems.php b/code/Rubygems.php
index 2b99ef7..1e6225d 100644
--- a/code/Rubygems.php
+++ b/code/Rubygems.php
@@ -3,177 +3,200 @@
/**
* @package compass
*/
-class Rubygems extends Object {
-
- /**
- * @var bool - is ruby available?
- */
- private static $ruby_ok = null;
+class Rubygems extends Object
+{
+
+ /**
+ * @var bool - is ruby available?
+ */
+ private static $ruby_ok = null;
- /**
- * @var bool - is the version of rubygems currently available good enough?
- */
- private static $gem_version_ok = null;
-
- /**
- * Get the path that gems live in, creating it if it doesn't exist .
- *
- * @return string
- */
- private static function gem_path() {
- $path = TEMP_FOLDER . '/gems';
- if (defined('SS_GEM_PATH')) $path = SS_GEM_PATH;
-
- if (!file_exists($path)) mkdir($path, 0770);
- return $path;
- }
+ /**
+ * @var bool - is the version of rubygems currently available good enough?
+ */
+ private static $gem_version_ok = null;
+
+ /**
+ * Get the path that gems live in, creating it if it doesn't exist .
+ *
+ * @return string
+ */
+ private static function gem_path()
+ {
+ $path = TEMP_FOLDER . '/gems';
+ if (defined('SS_GEM_PATH')) {
+ $path = SS_GEM_PATH;
+ }
+
+ if (!file_exists($path)) {
+ mkdir($path, 0770);
+ }
+ return $path;
+ }
- /**
- * Internal helper function that calls an external executable - can't just
- * use backticks, as we want stderr and stdout as separate variables
- *
- * Also sets this modules gem path into the environment of the external
- * executable
- *
- * @param $cmd string - the command to run
- * @param $stdout reference to string - the resultant stdout
- * @param $stderr reference to string - the resultant stderr
- *
- * @return int - process exit code, or -1 if the process couldn't be executed
- */
- protected static function _run($cmd, &$stdout, &$stderr) {
- $descriptorspec = array(
- 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
- 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
- 2 => array("pipe", "w") // stderr is a file to write to
- );
-
- $gempath = self::gem_path();
- $process = proc_open("HOME='$gempath' GEM_HOME='$gempath' " . (@$_GET['flush'] ? "FLUSH={$_GET['flush']} " : '') . $cmd, $descriptorspec, $pipes);
-
- $stdout = "";
- $stderr = "";
-
- if (!is_resource($process)) return -1;
+ /**
+ * Internal helper function that calls an external executable - can't just
+ * use backticks, as we want stderr and stdout as separate variables
+ *
+ * Also sets this modules gem path into the environment of the external
+ * executable
+ *
+ * @param $cmd string - the command to run
+ * @param $stdout reference to string - the resultant stdout
+ * @param $stderr reference to string - the resultant stderr
+ *
+ * @return int - process exit code, or -1 if the process couldn't be executed
+ */
+ protected static function _run($cmd, &$stdout, &$stderr)
+ {
+ $descriptorspec = array(
+ 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
+ 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
+ 2 => array("pipe", "w") // stderr is a file to write to
+ );
+
+ $gempath = self::gem_path();
+ $process = proc_open("HOME='$gempath' GEM_HOME='$gempath' " . (@$_GET['flush'] ? "FLUSH={$_GET['flush']} " : '') . $cmd, $descriptorspec, $pipes);
+
+ $stdout = "";
+ $stderr = "";
+
+ if (!is_resource($process)) {
+ return -1;
+ }
- fclose($pipes[0]); // close child's input immediately
- stream_set_blocking($pipes[1],false);
- stream_set_blocking($pipes[2],false);
-
- while (true) {
- $read = array();
- $w = null;
- $e = null;
-
- if (!feof($pipes[1])) $read[]= $pipes[1];
- if (!feof($pipes[2])) $read[]= $pipes[2];
-
- if (!$read) break;
- if (!stream_select($read, $w, $e, 120)) break;
-
- foreach ($read as $r) {
- $s = fread($r,1024);
- if ($r == $pipes[1]) $stdout .= $s; else $stderr .= $s;
- }
- }
-
- fclose($pipes[1]);
- fclose($pipes[2]);
-
- return proc_close($process);
- }
-
- /**
- * Make sure a gem is available
- *
- * @param $gem string - the name of the gem to install
- * @param $version string - the specific version to install
- * @param $tryupdating bool - if the gem is present, check for update? (hits the internet, so slow)
- *
- * @return null | string - an error string on error, nothing on success
- */
- public static function require_gem($gem, $version = null, $tryupdating = false) {
- // Check that ruby exists
- if (self::$ruby_ok === null) {
- self::$ruby_ok = (bool)`which ruby`;
- }
-
- if (!self::$ruby_ok) {
- return 'Ruby isn\'t present. The "ruby" command needs to be in the webserver\'s path';
- }
-
- // Check that rubygems exists and is a good enough version
- if (self::$gem_version_ok === null) {
- $code = self::_run('gem environment version', $ver, $err);
-
- if ($code !== 0) {
- return 'Ruby is present, but there was a problem accessing the \
+ fclose($pipes[0]); // close child's input immediately
+ stream_set_blocking($pipes[1], false);
+ stream_set_blocking($pipes[2], false);
+
+ while (true) {
+ $read = array();
+ $w = null;
+ $e = null;
+
+ if (!feof($pipes[1])) {
+ $read[]= $pipes[1];
+ }
+ if (!feof($pipes[2])) {
+ $read[]= $pipes[2];
+ }
+
+ if (!$read) {
+ break;
+ }
+ if (!stream_select($read, $w, $e, 120)) {
+ break;
+ }
+
+ foreach ($read as $r) {
+ $s = fread($r, 1024);
+ if ($r == $pipes[1]) {
+ $stdout .= $s;
+ } else {
+ $stderr .= $s;
+ }
+ }
+ }
+
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+
+ return proc_close($process);
+ }
+
+ /**
+ * Make sure a gem is available
+ *
+ * @param $gem string - the name of the gem to install
+ * @param $version string - the specific version to install
+ * @param $tryupdating bool - if the gem is present, check for update? (hits the internet, so slow)
+ *
+ * @return null | string - an error string on error, nothing on success
+ */
+ public static function require_gem($gem, $version = null, $tryupdating = false)
+ {
+ // Check that ruby exists
+ if (self::$ruby_ok === null) {
+ self::$ruby_ok = (bool)`which ruby`;
+ }
+
+ if (!self::$ruby_ok) {
+ return 'Ruby isn\'t present. The "ruby" command needs to be in the webserver\'s path';
+ }
+
+ // Check that rubygems exists and is a good enough version
+ if (self::$gem_version_ok === null) {
+ $code = self::_run('gem environment version', $ver, $err);
+
+ if ($code !== 0) {
+ return 'Ruby is present, but there was a problem accessing the \
current rubygems version - is rubygems available? The "gem" \
command needs to be in the webserver\'s path.';
- }
-
- $vers = explode('.', $ver);
-
- self::$gem_version_ok = (($vers[0] >= 1 && $vers[1] >= 2) OR ($vers[0] >= 2));
- }
+ }
+
+ $vers = explode('.', $ver);
+
+ self::$gem_version_ok = (($vers[0] >= 1 && $vers[1] >= 2) or ($vers[0] >= 2));
+ }
- if (!self::$gem_version_ok) {
- return "Rubygems is too old. You have version $ver, but we need at \
+ if (!self::$gem_version_ok) {
+ return "Rubygems is too old. You have version $ver, but we need at \
least version 1.2. Please upgrade.";
- }
-
- $veropt = $version ? "-v '$version'" : '';
+ }
+
+ $veropt = $version ? "-v '$version'" : '';
- // See if the gem exists. If not, try adding it
- self::_run("gem list -i $gem $veropt", $out, $err);
+ // See if the gem exists. If not, try adding it
+ self::_run("gem list -i $gem $veropt", $out, $err);
- if (trim($out) != 'true' || $tryupdating) {
- $code = self::_run("gem install $gem $veropt --no-rdoc --no-ri", $out, $err);
-
- if ($code !== 0) {
- return "Could not install required gem $gem. Either manually \
+ if (trim($out) != 'true' || $tryupdating) {
+ $code = self::_run("gem install $gem $veropt --no-rdoc --no-ri", $out, $err);
+
+ if ($code !== 0) {
+ return "Could not install required gem $gem. Either manually \
install, or repair error. Error message was: $err";
- }
- }
- }
-
- /**
- * Execute a command provided by a gem
- *
- * @param string | array $gem - the name of the gem, or an array of names
- * of gems, possibly associated with versions, to require.
- *
- * @param string $command - the name of the command
- * @param string $args - arguments to pass to the command
- * @param string $out - stdout result of the command
- * @param string $err - stderr result of the command
- *
- * @return int - process exit code, or -1 if the process couldn't be executed
- */
- public static function run($gems, $command, $args="", &$out, &$err) {
- $reqs = array();
+ }
+ }
+ }
+
+ /**
+ * Execute a command provided by a gem
+ *
+ * @param string | array $gem - the name of the gem, or an array of names
+ * of gems, possibly associated with versions, to require.
+ *
+ * @param string $command - the name of the command
+ * @param string $args - arguments to pass to the command
+ * @param string $out - stdout result of the command
+ * @param string $err - stderr result of the command
+ *
+ * @return int - process exit code, or -1 if the process couldn't be executed
+ */
+ public static function run($gems, $command, $args="", &$out, &$err)
+ {
+ $reqs = array();
- if (is_string($gems)) {
- $reqs[] = "-e 'gem \"$gem\", \">= 0\"'";
- } else {
- foreach ($gems as $gem => $version) {
- if (!$version) {
- $version = '>= 0';
- }
-
- $reqs[] = "-e 'gem \"$gem\", \"$version\"'";
- }
- }
-
- $version = (isset($gems[$command])) ? $gems[$command] : ">= 0";
- $reqs = implode(' ', $reqs);
+ if (is_string($gems)) {
+ $reqs[] = "-e 'gem \"$gem\", \">= 0\"'";
+ } else {
+ foreach ($gems as $gem => $version) {
+ if (!$version) {
+ $version = '>= 0';
+ }
+
+ $reqs[] = "-e 'gem \"$gem\", \"$version\"'";
+ }
+ }
+
+ $version = (isset($gems[$command])) ? $gems[$command] : ">= 0";
+ $reqs = implode(' ', $reqs);
- return self::_run(
- sprintf("ruby -rubygems $reqs -e 'load Gem.bin_path(\"%s\", \"%s\", \"%s\")' -- $args",
- $command, $command, $version
- ),
- $out,
- $err
- );
- }
+ return self::_run(
+ sprintf("ruby -rubygems $reqs -e 'load Gem.bin_path(\"%s\", \"%s\", \"%s\")' -- $args",
+ $command, $command, $version
+ ),
+ $out,
+ $err
+ );
+ }
}