function plugin_button_publish(array $params, Phest $phest) { $phest->registerSection('publish', 'Publish'); $phest->registerSection('publisherror', 'Publishエラー', array('type' => 'danger')); $dir_docs = DIR_PHEST . '/../docs'; if (!is_dir($dir_docs)) { $phest->add('publisherror', 'docs ディレクトリが見つかりません'); return false; } File::removeDir($dir_docs); mkdir($dir_docs, 0777); $phest->add('publish', 'docs/フォルダをクリアしました'); $dir_production = $phest->getOutputPath('', 'production'); if (!is_dir($dir_production)) { $phest->add('publisherror', 'output/production ディレクトリが見つかりません'); return false; } File::copyDir($dir_production, $dir_docs); $phest->add('publish', 'docs/フォルダへoutput/productionの内容をコピーしました'); $path_readme = $dir_docs . '/README.md'; if (!file_exists($path_readme)) { $phest->add('publisherror', 'README.mdが見つかりません'); echo $path_readme; return false; } rename($dir_docs . '/README.md', DIR_PHEST . '/../README.md'); $phest->add('publish', 'docs/README.mdをトップへ移動しました'); rename($dir_docs . '/CHANGELOGS.md', DIR_PHEST . '/../CHANGELOGS.md'); $phest->add('publish', 'docs/CHANGELOGS.mdをトップへ移動しました'); }
function plugin_build_copydir(array $params, Phest $phest) { $dir_source = $phest->getSourcePath(); $from_dpath = $dir_source . '/' . $params['from']; $to_dpath = $dir_source . '/' . $params['to']; $phest->add('build', '[copydir] <b>' . $from_dpath . '</b> から <b>' . $to_dpath . '</b> へコピー'); File::copyDir($from_dpath, $to_dpath, true); return true; }
/** * フォルダを削除する * * @param array $params パラメータ * @param string $params.dir 削除対象のフォルダパス (source/ からの相対パス) * @param Phest $phest Phestオブジェクト * @return bool プラグインの成功判定 */ function plugin_build_removedir(array $params, Phest $phest) { if (empty($params['dir'])) { $phest->add('builderror', '[removedir] dirオプションが指定されていません'); return false; } $dir_source = $phest->getSourcePath(); $dpath = $dir_source . '/' . $params['dir']; if (!is_dir($dpath)) { $phest->add('builderror', '[removedir] dir はディレクトリではありません: ' . $dpath); return false; } $phest->add('build', '[removedir] <b>' . $dpath . '</b> を削除しました'); File::removeDir($dpath); return true; }
function plugin_build_concat(array $params, Phest $phest) { $sourcepath = $phest->getSourcePath(); $output_source = ''; $count = 0; foreach ($params['sources'] as $spath) { $spath = $sourcepath . '/' . $spath; if (file_exists($spath)) { $count++; $output_source .= file_get_contents($spath); } else { $phest->add('builderror', '[concat] sources で指定されたファイルが存在しません: ' . $spath); } } $phest->add('build', '[concat] ' . $count . '個のファイルを結合: /<b>' . $params['output'] . '</b>'); File::buildPutFile($sourcepath . '/' . $params['output'], $output_source); return true; }
function plugin_build_copy(array $params, Phest $phest) { global $phest_plugin_copy_list; $output_dir = rtrim($params['outputdir'], '\\/'); $sourcepath = $phest->getSourcePath(); $count = 0; foreach ($params['sources'] as $spath) { $spath = $sourcepath . '/' . $spath; if (file_exists($spath)) { $count++; File::buildCopy($spath, $sourcepath . '/' . $output_dir . '/' . basename($spath)); } else { $phest->add('builderror', '[copy] sources で指定されたファイルが存在しません: ' . $spath); } } $phest->add('build', '[copy] ' . $count . '個のファイルをコピー: /<b>' . $output_dir . '</b>'); return true; }
/** * 指定したディレクトリから、ファイルのパスの配列を返す * * <pre> * ディレクトリのパスは返さず、ファイルパスのみ返す。 * ./test/ * index.php * counter.php * data/ * count.dat * img/ * * という構成があった場合、 * </pre> * <code> * $file_list = File::getFileList('./test'); * </code> * <pre> * は、 * * array( * './test/index.php', * './test/counter.php', * './test/data/count.dat' * ); * を返す。 * </pre> * * @param string $directory ディレクトリ * @param int $depth たどる階層の深さ -1 だと無制限 * @param array $ignore 無視するパターン (fnmatch関数の引数) * @param array $filter 検出するパターン (fnmatch関数の引数) * @return array ファイルパスのリスト */ public static function getFileList($directory, $depth = -1, $ignore = array(), $filter = array()) { if ($depth == 0) { return array(); } $directory = rtrim($directory, '\\/'); $tmp = array(); if (ECF_FILE_FILESYSTEMITERATOR_EXIST) { $iterator = new RecursiveDirectoryiterator($directory, FilesystemIterator::SKIP_DOTS); } else { $iterator = new RecursiveDirectoryiterator($directory); } foreach ($iterator as $path) { $filename = $path->getBasename(); foreach ((array) $ignore as $ival) { if (fnmatch($ival, $filename)) { continue 2; } } if ($path->isDir()) { if ($depth > 0) { $depth--; } foreach (File::getFileList($directory . '/' . $filename, $depth, $ignore, $filter) as $ppath) { $tmp[] = $ppath; } } else { if ($filter) { $hit = false; foreach ((array) $filter as $fval) { if (fnmatch($fval, $filename)) { $hit = true; break; } } if (!$hit) { continue; } } $tmp[] = $directory . '/' . $filename; } } return $tmp; }
/** * ファイルに更新があるか * * @method hasNew * @return boolean 更新がある場合true */ public function hasNew() { $has_new = false; $path_concat_string = ''; //ページをスキャン foreach ($this->watch_list as $filepath) { if ($this->site_last_buildtime < filemtime($filepath)) { $has_new = true; } $path_concat_string .= ':' . $filepath; } //ファイルパスを全部つないだ文字列のハッシュをとる $source_pathhash = md5($path_concat_string); //ファイルパスの変更があるか if ($this->site_last_buildhash != $source_pathhash) { $has_new = true; } if ($has_new) { $this->site_last_buildhash = $source_pathhash; //ビルド時間を記録 File::buildPutFile($this->path_buildstatus_site, $this->site_last_buildhash); } return $has_new; }
/** * Amazon S3へProductionビルドをアップロード * * @param array $params パラメータ * @param bool $params.enable trueを指定すると実行 * @param string $params.bucket バケット名 * @param enum $params.region リージョン * @param string [$params.prefix] アップロードするキー名につけるPrefix * @param string $params.bucket バケット名 * @param array [$params.protectpatterns] 削除しないキー名の正規表現を配列で指定 * @param string $params.key AWSのアクセスキー * @param string $params.secret AWSのシークレットキー * @param Phest $phest Phestオブジェクト * @return bool プラグインの成功判定 */ function plugin_button_s3deploy(array $params, Phest $phest) { $phest->registerSection('s3deployerror', 'デプロイエラー', array('type' => 'danger')); if ($phest->hasError()) { $phest->add('s3deployerror', 'エラーが発生しているためデプロイしません'); return false; } $dryrun = true; if (isset($params['dryrun'])) { $dryrun = $params['dryrun']; } if ($dryrun) { $phest->registerSection('s3deploy', 'デプロイ完了 [dryrun]', array('type' => 'warning')); } else { $phest->registerSection('s3deploy', 'デプロイ完了'); } $prefix = ''; if (isset($params['prefix'])) { $prefix = $params['prefix']; } if (isset($params['buildtype'])) { $buildtype = $params['buildtype']; } else { $buildtype = 'production'; } $protectpatterns = array(); if (isset($params['protectpatterns']) and is_array($params['protectpatterns'])) { $protectpatterns = $params['protectpatterns']; } if (!is_array($protectpatterns)) { $protectpatterns = array(); } //ignore check $protect_req_list = array(); foreach ($protectpatterns as $pattern) { $protect_req_list[] = '/' . str_replace('/', '\\/', $pattern) . '/'; } //$buckets = $s3->listBuckets(); //print_a($buckets); $upload_dir = $phest->getOutputPath($phest->getLang(), $buildtype); if (!is_dir($upload_dir)) { $phest->add('s3deployerror', $buildtype . 'でビルドされたファイルが存在しません'); return false; } //認証情報を読み込み if (isset($params['credentialkey'])) { $credential = $phest->getCredential($params['credentialkey']); if (!$credential) { $phest->add('s3deployerror', 'credentialkeyで指定されたキーの認証情報が読み出せません: ' . $params['credentialkey']); } else { $params = array_merge($params, $credential); } } $is_error = false; $required = array('bucket', 'region', 'key', 'secret'); foreach ($required as $rval) { if (empty($params[$rval])) { $phest->add('s3deployerror', 'オプションが指定されていません: ' . $rval); $is_error = true; } } $region_key = ''; if (!$is_error) { $regions = array('US_EAST_1', 'VIRGINIA', 'NORTHERN_VIRGINIA', 'US_WEST_1', 'CALIFORNIA', 'NORTHERN_CALIFORNIA', 'US_WEST_2', 'OREGON', 'EU_WEST_1', 'IRELAND', 'AP_SOUTHEAST_1', 'SINGAPORE', 'AP_SOUTHEAST_2', 'SYDNEY', 'AP_NORTHEAST_1', 'TOKYO', 'SA_EAST_1', 'SAO_PAULO', 'US_GOV_WEST_1', 'GOV_CLOUD_US'); $region_key = strtoupper($params['region']); if (!in_array($region_key, $regions)) { $phest->add('s3deployerror', 'regionの指定が正しくありません。regionには次の値が指定できます(大文字小文字の違いは無視されます): ' . implode(', ', $regions)); $is_error = true; } } if ($is_error) { return false; } $bucket = $params['bucket']; $region = constant('\\Aws\\Common\\Enum\\Region::' . $region_key); $access_key = $params['key']; $secret_key = $params['secret']; $phest->add('s3deploy', 'リージョン: ' . $region . ' バケット: ' . $bucket . ' ビルド: ' . $buildtype); try { $s3 = S3Client::factory(array('key' => $access_key, 'secret' => $secret_key, 'region' => $region)); } catch (\Exception $e) { $phest->add('s3deployerror', $e->getMessage()); return false; } //S3上のアップロード状況を確認 $object_flag = array(); try { $iterator = $s3->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $prefix)); foreach ($iterator as $object) { if ($object['Size'] !== 0 and substr($object['Key'], -1) !== '/') { $object_flag[$object['Key']] = true; } } } catch (\Exception $e) { $phest->add('s3deployerror', $e->getMessage()); return false; } $message_option = ''; if ($dryrun) { $message_option = ' <code>[dryrun]</code>'; } //ローカルファイルをスキャンしてアップロード $file_list = File::getFileList($upload_dir); foreach ($file_list as $filepath) { $key = strtr(ltrim(substr($filepath, strlen($upload_dir)), '\\/'), '\\', '/'); //upload $keyname = $prefix . $key; try { if (!$dryrun) { //何か出力しないとブラウザ側でタイムアウトするので空白を出力 echo '<span></span>'; @flush(); @ob_flush(); $result = $s3->putObject(array('Bucket' => $bucket, 'Key' => $keyname, 'Body' => EntityBody::factory(fopen($filepath, 'r')), 'ACL' => CannedAcl::PUBLIC_READ)); } if (isset($object_flag[$keyname])) { unset($object_flag[$keyname]); $phest->add('s3deploy', '更新: ' . $keyname . $message_option); } else { $phest->add('s3deploy', '追加: ' . $keyname . $message_option); } } catch (S3Exception $e) { $phest->add('s3deployerror', 'PutObject: ' . $e->getMessage()); } catch (\Exception $e) { $phest->add('s3deployerror', 'PutObject: ' . $e->getMessage()); return false; } } //サーバーにアップされてて、ローカルにないファイルを削除 foreach (array_chunk(array_keys($object_flag), 1000) as $chunked_key_list) { $key_list = array(); foreach ($chunked_key_list as $key) { //ignore check foreach ($protect_req_list as $pattern) { if (preg_match($pattern, $key)) { $phest->add('s3deploy', '保持: ' . $key . $message_option); continue 2; } } $key_list[] = array('Key' => $key); } if (!$key_list) { continue; } try { if (!$dryrun) { $result = $s3->deleteObjects(array('Bucket' => $bucket, 'Objects' => $key_list)); } foreach ($key_list as $item) { $phest->add('s3deploy', '削除: ' . current($item) . $message_option); } } catch (S3Exception $e) { $phest->add('s3deployerror', 'DeleteObject: ' . $e->getMessage()); } catch (\Exception $e) { $phest->add('s3deployerror', 'DeleteObject: ' . $e->getMessage()); return false; } } }
File::buildPutFile($dir_output . '/' . $filepath, $source); if ($is_js and !$is_nolint) { //lint check $lint_error = jslint($pathname); if ($lint_error) { foreach ($lint_error as $lerr) { $phest->add('jslint', $basename . ':' . $lerr); } } } } } else { $outputpath = $dir_output . '/' . $filepath; $tmp_dir = dirname($outputpath); if (!is_dir($tmp_dir)) { File::buildMakeDir($tmp_dir); } copy($pathname, $outputpath); } if ($create_option) { $create_option = ' <code>' . trim($create_option) . '</code>'; } $subsection_key = 'etc'; if (isset($create_subsection_pattern[$last_extension])) { $subsection_key = $create_subsection_pattern[$last_extension]; } $anchortext = ''; if ($subsection_key == 'image') { $anchortext = '<img src="' . $home_local . '/' . $filepath . '" style="width:30px;height:30px;" /> ' . $filepath; } else { $anchortext = $filepath;