function build() { /* Function: build() * Builds the project. * * Description: * This is the main function that builds the documentation. This is * called when the user types `ss build` in the command line (or just * plain `ss` as it's the default action). It does the things below: * * 1. The source path is scanned for files recursively, and it'll * delegate each file to it's respective `reader` to be read. * * 2. These readers will parse out the files and call [[register()]] * when it finds a block. * * 3. It checks the outputs to be made (defined in the configuration * file) and delegates to each output driver the task of producing * the documentation files. * * * References: * This is called by the default action of [[class Scribe]], * namely [[Scribe::do_build()]]. Being the default action, this fires * up when the user types `ss` in the command line. */ ScStatus::status('Starting build process:'); // Scan the files ScStatus::updateStart("Scanning files"); $file_count = 0; $options = array('recursive' => 1, 'mask' => '/./', 'fullpath' => 1); // Take the exclusions list into consideration if (isset($this->options['exclude'])) { $options['exclude'] = array(); foreach ($this->options['exclude'] as $ex) { $options['exclude'][] = ':' . $ex . ':'; /* Regex, you see */ } } // For each source path... foreach ((array) $this->options['src_path'] as $path) { // Parse each of the files $files = aeScandir($path, $options); foreach ($files as $file) { // Find out which reader it's assigned to foreach ($this->options['include'] as $spec => $reader_name) { if (preg_match("~{$spec}~", $file) == 0) { continue; } // Show status of what file we're reading $file_min = substr(realpath($file), 1 + strlen(realpath($this->cwd))); ScStatus::update("[{$reader_name}] {$file_min}"); $file_count++; // And read it $this->registerStart(); $reader = $this->Sc->Readers[$reader_name]; $blocks = $reader->parse($file, $this); break; } } } ScStatus::updateDone("{$file_count} files scanned."); $this->_doPostBuild(); $this->_loadOutputDrivers(); // Spit out the outputs. // Do this for every output defined... foreach ($this->options['output'] as $id => $output_options) { // Make sure we have an output driver if (!isset($output_options['driver'])) { return ScStatus::error("No driver defined for output {$id}"); } // Load it and make sure it exists $driver =& $this->Sc->loadOutputDriver($output_options['driver'], $this, $options); $driver =& $this->outputs[$id]; if (!$driver) { continue; } // Initialize ScStatus::updateStart('Writing ' . $output_options['driver'] . ' output'); $path = $output_options['path']; // Mkdir the path $path = $this->cwd . DS . $path; $result = @mkdir($path, 0744, true); if (!is_dir($path)) { return $this->Sc->error("Can't create folder for {$driver} output."); } // Run $driver->run($path); ScStatus::updateDone('Done.'); } ScStatus::status('Build complete.'); $output = serialize($this->Sc); }
function aeScandir($dirPath, $opts = array(), $internal = '/') { $f = array(); $dirPath = realpath($dirPath); $dir = opendir($dirPath); // If we're looking for DIR's, make sure to include the root if ($internal == '/' && isset($opts['directory']) && @$opts['directory'] === TRUE) { $f[] = '/'; } while ($fname = readdir($dir)) { if ($fname != '.' && $fname != '..') { $result = $internal . $fname; $file = $dirPath . DIRECTORY_SEPARATOR . $fname; // Recurse if needed if (is_dir($file) && @$opts['recursive']) { $f = array_merge($f, aeScandir($file, $opts, $result . '/')); } // 'mask' => Include masks. (Goes back if it doesn't match) if (isset($opts['mask'])) { foreach ((array) $opts['mask'] as $mask) { if (!preg_match($mask, $result)) { continue 2; } } } // 'exclude' => Exclude masks (Goes back if it matches) if (isset($opts['exclude'])) { foreach ((array) $opts['exclude'] as $mask) { if (preg_match($mask, $result)) { continue 2; } } } // Append dir to results (if its asked for) if (is_dir($file) && isset($opts['directory'])) { $f[] = $result; } else { if (is_file($file) && !isset($opts['directory'])) { // 'cnewer' => Newer than ctime if (isset($opts['cnewer'])) { if (filectime($file) < $opts['cnewer']) { continue; } } // 'mnewer' => Newer than mtime and ctime if (isset($opts['mnewer'])) { if (filemtime($file) < $opts['mnewer']) { continue; } } $f[] = $result; } } } } if (isset($opts['fullpath']) && $internal == '/') { for ($i = 0; $i < count($f); ++$i) { $f[$i] = realpath($dirPath . DIRECTORY_SEPARATOR . $f[$i]); } } return $f; }