Skip to content

Commit

Permalink
Merge branch 'next' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
franzliedke committed Apr 6, 2016
2 parents b5a28cf + 9b173ff commit 34ff3f5
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 108 deletions.
5 changes: 2 additions & 3 deletions bin/studio
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ use Studio\Console\LoadCommand;
use Studio\Console\ScrapCommand;
use Symfony\Component\Console\Application;

$studioFile = getcwd().'/studio.json';
$config = new Config(new FileStorage($studioFile));
$config = Config::make();

$application = new Application('studio', '0.10.0');
$application->add(new CreateCommand($config));
$application->add(new CreateCommand);
$application->add(new LoadCommand($config));
$application->add(new ScrapCommand($config));
$application->run();
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
},
"extra": {
"branch-alias": {
"dev-master": "0.10.x-dev"
"dev-master": "0.10.x-dev",
"dev-next": "0.11.x-dev"
},
"class": "Studio\\Composer\\StudioPlugin"
},
Expand Down
18 changes: 3 additions & 15 deletions src/Composer/StudioPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,16 @@ public static function getSubscribedEvents()
public function registerStudioPackages(Event $event)
{
$this->targetDir = realpath($event->getComposer()->getPackage()->getTargetDir());
$studioFile = "{$this->targetDir}/studio.json";

$config = $this->getConfig($studioFile);
$config = Config::make("{$this->targetDir}/studio.json");

if ($config->hasPackages()) {
$io = $event->getIO();
$repoManager = $event->getComposer()->getRepositoryManager();
$composerConfig = $event->getComposer()->getConfig();

foreach ($config->getPackages() as $package => $path) {
$io->writeError("[Studio] Registering package $package with $path");
foreach ($config->getPaths() as $path) {
$io->writeError("[Studio] Loading path $path");
$repoManager->prependRepository(new PathRepository(
['url' => $path],
$io,
Expand All @@ -65,15 +64,4 @@ public function registerStudioPackages(Event $event)
}
}
}

/**
* Instantiate and return the config object.
*
* @param string $file
* @return Config
*/
protected function getConfig($file)
{
return new Config(new FileStorage($file));
}
}
92 changes: 70 additions & 22 deletions src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,105 @@
class Config
{
/**
* @var StorageInterface
* @var Serializer
*/
protected $storage;
protected $serializer;

protected $packages;
protected $paths;

protected $loaded = false;

protected $file;

public function __construct(StorageInterface $storage)

public function __construct($file, Serializer $serializer)
{
$this->file = $file;
$this->serializer = $serializer;
}

public static function make($file = null)
{
if (is_null($file)) {
$file = getcwd().'/studio.json';
}

return new static(
$file,
VersionedSerializer
::withDefault(1, new Version1Serializer)
->version(2, new Version2Serializer)
);
}

protected function readPaths()
{
$this->storage = $storage;
if (!file_exists($this->file)) return [];

$data = $this->readFromFile();
return $this->serializer->deserializePaths($data);
}

public function getPackages()
public function getPaths()
{
if (! $this->loaded) {
$this->packages = $this->storage->load();
$this->paths = $this->readPaths();
$this->loaded = true;
}

return $this->packages;
return $this->paths;
}

public function addPackage(Package $package)
public function addPath($path)
{
// Ensure our packages are loaded
$this->getPackages();
// Ensure paths are loaded
$this->getPaths();

$this->packages[$package->getComposerId()] = $package->getPath();
$this->storage->store($this->packages);
$this->paths[] = $path;
$this->dump();
}

public function hasPackages()
{
// Ensure our packages are loaded
$this->getPackages();
// Ensure paths are loaded
$this->getPaths();

return ! empty($this->packages);
return ! empty($this->paths);
}

public function removePackage(Package $package)
{
// Ensure our packages are loaded
$this->getPackages();
// Ensure paths are loaded
$this->getPaths();

$key = $package->getComposerId();
$path = $package->getPath();

if (isset($this->packages[$key])) {
unset($this->packages[$key]);
$this->storage->store($this->packages);
if (($key = array_search($path, $this->paths)) !== false) {
unset($this->paths[$key]);
$this->dump();
}
}

protected function dump()
{
$this->writeToFile(
$this->serializer->serializePaths($this->paths)
);
}

protected function writeToFile(array $data)
{
file_put_contents(
$this->file,
json_encode(
$data,
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
)."\n"
);
}

protected function readFromFile()
{
return json_decode(file_get_contents($this->file), true);
}
}
43 changes: 0 additions & 43 deletions src/Config/FileStorage.php

This file was deleted.

10 changes: 10 additions & 0 deletions src/Config/Serializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Studio\Config;

interface Serializer
{
public function deserializePaths($obj);

public function serializePaths(array $paths);
}
10 changes: 0 additions & 10 deletions src/Config/StorageInterface.php

This file was deleted.

44 changes: 44 additions & 0 deletions src/Config/Version1Serializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Studio\Config;

use Studio\Package;

class Version1Serializer implements Serializer
{
public function deserializePaths($obj)
{
return array_values($obj['packages']);
}

public function serializePaths(array $paths)
{
$globbedPaths = array_map(function ($path) {
return glob($path, GLOB_MARK | GLOB_ONLYDIR);
}, $paths);

$allPaths = array_reduce($globbedPaths, function ($collect, $pathOrPaths) {
if (is_array($pathOrPaths)) {
return array_merge($collect, $pathOrPaths);
} else {
$collect[] = $pathOrPaths;
return $collect;
}
}, []);

$allPaths = array_filter($allPaths, function ($path) {
return is_dir($path) && file_exists("$path/composer.json");
});

$packages = array_map(function ($path) {
return Package::fromFolder(rtrim($path, '/'));
}, $allPaths);

$packagePaths = array_reduce($packages, function ($collect, Package $package) {
$collect[$package->getComposerId()] = $package->getPath();
return $collect;
}, []);

return ['packages' => $packagePaths];
}
}
16 changes: 16 additions & 0 deletions src/Config/Version2Serializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Studio\Config;

class Version2Serializer implements Serializer
{
public function deserializePaths($obj)
{
return $obj['paths'];
}

public function serializePaths(array $paths)
{
return ['paths' => array_values($paths)];
}
}
74 changes: 74 additions & 0 deletions src/Config/VersionedSerializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Studio\Config;

/**
* A decorator for serializing from/to multiple versions
*
* We support several versions of the Studio config file.
*
* This serializer class uses the serializer according to
* the "version" field or the default one if no "version"
* is provided for reading.
*
* For writing, the serializer with the highest version
* number is used.
*
* @package Studio\Config
*/
class VersionedSerializer implements Serializer
{
/**
* @var Serializer[]
*/
protected $serializers;

/**
* @var int
*/
protected $defaultVersion;

/**
* @param int $version
* @param Serializer $serializer
* @return static
*/
public static function withDefault($version, Serializer $serializer)
{
return new static([$version => $serializer], $version);
}

public function __construct(array $serializers, $defaultVersion)
{
$this->serializers = $serializers;
$this->defaultVersion = $defaultVersion;
}

public function version($version, Serializer $serializer)
{
$this->serializers[$version] = $serializer;

return $this;
}

public function deserializePaths($obj)
{
if (!isset($obj['version'])) {
$serializer = $this->serializers[$this->defaultVersion];
} else if (array_key_exists(intval($obj['version']), $this->serializers)) {
$serializer = $this->serializers[$obj['version']];
} else {
throw new \InvalidArgumentException('Invalid version');
}

return $serializer->deserializePaths($obj);
}

public function serializePaths(array $paths)
{
$lastVersion = max(array_keys($this->serializers));
$serializer = $this->serializers[$lastVersion];

return ['version' => $lastVersion] + $serializer->serializePaths($paths);
}
}
Loading

0 comments on commit 34ff3f5

Please sign in to comment.