Browse Source

updated build command to set up dev environment

issue #7812
tags/2.0.4
Carsten Brandt 10 years ago
parent
commit
7fba1698b3
  1. 4
      .gitignore
  2. 124
      build/controllers/AppController.php
  3. 267
      build/controllers/DevController.php
  4. 8
      docs/internals/getting-started.md

4
.gitignore vendored

@ -30,3 +30,7 @@ composer.phar
phpunit.phar
# local phpunit config
/phpunit.xml
# ignore sub directory for dev installed apps and extensions
/apps
/extensions

124
build/controllers/AppController.php

@ -1,124 +0,0 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\build\controllers;
use Yii;
use yii\console\Controller;
use yii\helpers\FileHelper;
/**
* AppController will link the yii2 dev installation to the containted applications vendor dirs
* to help working on yii using the application to test it.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class AppController extends Controller
{
public $defaultAction = 'link';
/**
* Properly removes symlinked directory under Windows, MacOS and Linux
*
* @param string $file path to symlink
*/
protected function unlink($file)
{
if (is_dir($file) && DIRECTORY_SEPARATOR === '\\') {
rmdir($file);
} else {
unlink($file);
}
}
/**
* This command runs the following shell commands in the dev repo root:
*
* - Run `composer update`
* - `rm -rf apps/basic/vendor/yiisoft/yii2`
* - `rm -rf apps/basic/vendor/yiisoft/yii2-*`
*
* And replaces them with symbolic links to the extensions and framework path in the dev repo.
* @param string $app the application name `basic` or `advanced`.
*/
public function actionLink($app)
{
// root of the dev repo
$base = dirname(dirname(__DIR__));
$appDir = "$base/apps/$app";
// cleanup
if (is_link($link = "$appDir/vendor/yiisoft/yii2")) {
$this->stdout("Removing symlink $link.\n");
$this->unlink($link);
}
$extensions = $this->findDirs("$appDir/vendor/yiisoft");
foreach($extensions as $ext) {
if (is_link($link = "$appDir/vendor/yiisoft/yii2-$ext")) {
$this->stdout("Removing symlink $link.\n");
$this->unlink($link);
}
}
// composer update
chdir($appDir);
passthru('composer update --prefer-dist');
// link directories
if (is_dir($link = "$appDir/vendor/yiisoft/yii2")) {
$this->stdout("Removing dir $link.\n");
FileHelper::removeDirectory($link);
$this->stdout("Creating symlink for $link.\n");
symlink("$base/framework", $link);
}
$extensions = $this->findDirs("$appDir/vendor/yiisoft");
foreach($extensions as $ext) {
if (is_dir($link = "$appDir/vendor/yiisoft/yii2-$ext")) {
$this->stdout("Removing dir $link.\n");
FileHelper::removeDirectory($link);
$this->stdout("Creating symlink for $link.\n");
symlink("$base/extensions/$ext", $link);
}
}
$this->stdout("done.\n");
}
/**
* Finds linkable applications
*
* @param string $dir directory to search in
* @return array list of applications command can link
*/
protected function findDirs($dir)
{
$list = [];
$handle = @opendir($dir);
if ($handle === false) {
return [];
}
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (is_dir($path) && preg_match('/^yii2-(.*)$/', $file, $matches)) {
$list[] = $matches[1];
}
}
closedir($handle);
foreach($list as $i => $e) {
if ($e == 'composer') { // skip composer to not break composer update
unset($list[$i]);
}
}
return $list;
}
}

267
build/controllers/DevController.php

@ -0,0 +1,267 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\build\controllers;
use Yii;
use yii\console\Controller;
use yii\helpers\Console;
use yii\helpers\FileHelper;
/**
* This command helps to set up a dev environment with all extensions and applications
*
* It will clone an extension or app repo and link the yii2 dev installation to the containted applications/extensions vendor dirs
* to help working on yii using the application to test it.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class DevController extends Controller
{
public $defaultAction = 'all';
public $apps = [
'basic' => 'git@github.com:yiisoft/yii2-app-basic.git',
'advanced' => 'git@github.com:yiisoft/yii2-app-advanced.git',
];
public $extensions = [
'apidoc' => 'git@github.com:yiisoft/yii2-apidoc.git',
'authclient' => 'git@github.com:yiisoft/yii2-authclient.git',
'bootstrap' => 'git@github.com:yiisoft/yii2-bootstrap.git',
'codeception' => 'git@github.com:yiisoft/yii2-codeception.git',
'composer' => 'git@github.com:yiisoft/yii2-composer.git',
'debug' => 'git@github.com:yiisoft/yii2-debug.git',
'elasticsearch' => 'git@github.com:yiisoft/yii2-elasticsearch.git',
'faker' => 'git@github.com:yiisoft/yii2-faker.git',
'gii' => 'git@github.com:yiisoft/yii2-gii.git',
'imagine' => 'git@github.com:yiisoft/yii2-imagine.git',
'jui' => 'git@github.com:yiisoft/yii2-jui.git',
'mongodb' => 'git@github.com:yiisoft/yii2-mongodb.git',
'redis' => 'git@github.com:yiisoft/yii2-redis.git',
'smarty' => 'git@github.com:yiisoft/yii2-smarty.git',
'sphinx' => 'git@github.com:yiisoft/yii2-sphinx.git',
'swiftmailer' => 'git@github.com:yiisoft/yii2-swiftmailer.git',
'twig' => 'git@github.com:yiisoft/yii2-twig.git',
];
/**
* Install all extensions and advanced + basic app
*/
public function actionAll()
{
if (!$this->confirm('Install all applications and all extensions now?')) {
return 1;
}
foreach($this->extensions as $ext => $repo) {
$ret = $this->actionExt($ext, $repo);
if ($ret !== 0) {
return $ret;
}
}
foreach($this->apps as $app => $repo) {
$ret = $this->actionApp($app, $repo);
if ($ret !== 0) {
return $ret;
}
}
return 0;
}
/**
* This command installs an application template in the `apps` directory and links the framework and extensions
*
* It basically runs the following commands in the dev repo root:
*
* - Run `composer update`
* - `rm -rf apps/basic/vendor/yiisoft/yii2`
* - `rm -rf apps/basic/vendor/yiisoft/yii2-*`
*
* And replaces them with symbolic links to the extensions and framework path in the dev repo.
*
* Extensions required by the application are automatically installed using the `ext` action.
*
* @param string $app the application name e.g. `basic` or `advanced`.
* @param string $repo url of the git repo to clone if it does not already exist.
*/
public function actionApp($app, $repo = null)
{
// root of the dev repo
$base = dirname(dirname(__DIR__));
$appDir = "$base/apps/$app";
if (!file_exists($appDir)) {
if (empty($repo)) {
if (isset($this->apps[$app])) {
$repo = $this->apps[$app];
} else {
$this->stderr("Repo argument is required for app '$app'.\n", Console::FG_RED);
return 1;
}
}
$this->stdout("cloning application repo '$app' from '$repo'...\n", Console::BOLD);
passthru('git clone ' . escapeshellarg($repo) . ' ' . $appDir);
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
}
// cleanup
$this->stdout("cleaning up application vendor directory...\n", Console::BOLD);
$this->cleanupVendorDir($appDir);
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
// composer update
$this->stdout("updating composer...\n", Console::BOLD);
chdir($appDir);
passthru('composer update --prefer-dist');
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
// link directories
$this->stdout("linking framework and extensions to vendor dir...\n", Console::BOLD);
$this->linkFrameworkAndExtensions($appDir, $base);
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
}
/**
* This command installs an extension in the `extensions` directory and links the framework and other extensions
*
* @param string $extension the application name e.g. `basic` or `advanced`.
* @param string $repo url of the git repo to clone if it does not already exist.
*/
public function actionExt($extension, $repo = null)
{
// root of the dev repo
$base = dirname(dirname(__DIR__));
$extensionDir = "$base/extensions/$extension";
if (!file_exists($extensionDir)) {
if (empty($repo)) {
if (isset($this->extensions[$extension])) {
$repo = $this->extensions[$extension];
} else {
$this->stderr("Repo argument is required for extension '$extension'.\n", Console::FG_RED);
return 1;
}
}
$this->stdout("cloning extension repo '$extension' from '$repo'...\n", Console::BOLD);
passthru('git clone ' . escapeshellarg($repo) . ' ' . $extensionDir);
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
}
// cleanup
$this->stdout("cleaning up extension vendor directory...\n", Console::BOLD);
$this->cleanupVendorDir($extensionDir);
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
// composer update
$this->stdout("updating composer...\n", Console::BOLD);
chdir($extensionDir);
passthru('composer update --prefer-dist');
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
// link directories
$this->stdout("linking framework and extensions to vendor dir...\n", Console::BOLD);
$this->linkFrameworkAndExtensions($extensionDir, $base);
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
}
protected function cleanupVendorDir($dir)
{
if (is_link($link = "$dir/vendor/yiisoft/yii2")) {
$this->stdout("Removing symlink $link.\n");
$this->unlink($link);
}
$extensions = $this->findDirs("$dir/vendor/yiisoft");
foreach($extensions as $ext) {
if (is_link($link = "$dir/vendor/yiisoft/yii2-$ext")) {
$this->stdout("Removing symlink $link.\n");
$this->unlink($link);
}
}
}
protected function linkFrameworkAndExtensions($dir, $base)
{
if (is_dir($link = "$dir/vendor/yiisoft/yii2")) {
$this->stdout("Removing dir $link.\n");
FileHelper::removeDirectory($link);
$this->stdout("Creating symlink for $link.\n");
symlink("$base/framework", $link);
}
$extensions = $this->findDirs("$dir/vendor/yiisoft");
foreach($extensions as $ext) {
if (is_dir($link = "$dir/vendor/yiisoft/yii2-$ext")) {
$this->stdout("Removing dir $link.\n");
FileHelper::removeDirectory($link);
$this->stdout("Creating symlink for $link.\n");
if (!file_exists("$base/extensions/$ext")) {
$ret = $this->actionExt($ext);
if ($ret !== 0) {
return $ret;
}
}
symlink("$base/extensions/$ext", $link);
}
}
}
/**
* Properly removes symlinked directory under Windows, MacOS and Linux
*
* @param string $file path to symlink
*/
protected function unlink($file)
{
if (is_dir($file) && DIRECTORY_SEPARATOR === '\\') {
rmdir($file);
} else {
unlink($file);
}
}
/**
* Finds linkable applications
*
* @param string $dir directory to search in
* @return array list of applications command can link
*/
protected function findDirs($dir)
{
$list = [];
$handle = @opendir($dir);
if ($handle === false) {
return [];
}
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (is_dir($path) && preg_match('/^yii2-(.*)$/', $file, $matches)) {
$list[] = $matches[1];
}
}
closedir($handle);
foreach($list as $i => $e) {
if ($e == 'composer') { // skip composer to not break composer update
unset($list[$i]);
}
}
return $list;
}
}

8
docs/internals/getting-started.md

@ -3,11 +3,11 @@ Getting started with Yii2 development
1. Clone your fork of yii2 `git clone git@github.com:<yourname>/yii2.git`.
2. Change into the repo folder `cd yii2`.
3. run `./build/build app/link basic` to install composer dependecies for the basic app.
3. run `./build/build dev/app basic` to clone the basic app and install composer dependencies for the basic app.
This command will install foreign composer packages as normal but will link the yii2 repo to
the currently checked out repo, so you have one instance of all the code installed.
4. Do the same for the advanced app if needed: `./build/build app/link advanced`
This command will also be used to update dependecies, it runs `composer update` internally.
4. Do the same for the advanced app if needed: `./build/build dev/app advanced`
This command will also be used to update dependencies, it runs `composer update` internally.
5. Now you have a working playground for hacking on Yii 2.
You may also add the yii2 upstream repo to pull the latest changes:
@ -32,6 +32,8 @@ You may limit the tests to a group of tests you are working on e.g. to run only
Extensions
----------
> Note: this section is outdated as we are currently changing the repository structure. instructions will be updated soon.
To work on extensions you have to install them in the application you want to try them in.
Just add them to the `composer.json` as you would normally do e.g. add `"yiisoft/yii2-redis": "*"` to the
`require` section of the basic app.

Loading…
Cancel
Save