Skip to content

Commit 06b1cd0

Browse files
committed
Initial commit.
0 parents  commit 06b1cd0

3 files changed

Lines changed: 156 additions & 0 deletions

File tree

composer.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "wpscholar/github-archive-installer",
3+
"description": "A custom Composer installer that will install a dependency from a GitHub release archive .zip file when installing from distribution.",
4+
"type": "composer-plugin",
5+
"license": "GPL-2.0-or-later",
6+
"authors": [
7+
{
8+
"name": "Micah Wood",
9+
"email": "micah@wpscholar.com"
10+
}
11+
],
12+
"require": {
13+
"composer-plugin-api": "^1.1"
14+
},
15+
"autoload": {
16+
"psr-4": {
17+
"wpscholar\\Composer\\": "src"
18+
}
19+
},
20+
"extra": {
21+
"class": "wpscholar\\Composer\\GithubArchiveInstaller"
22+
}
23+
}

readme.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# GitHub Archive Installer
2+
3+
A custom Composer installer that will install a dependency from a GitHub release archive .zip file when installing from distribution.
4+
5+
## Why You Need It
6+
It is very common that you might have a number of development only files in your code library source files. Unless explicitly installing from source, you generally don't need to have development only files in your final distribution. You may also want to perform some specific build steps such as building some production-ready JavaScript files. This installer allows you to keep generated code out of your repository while still being able to reliably deliver it in your final distribution.
7+
8+
Using a tool like Travis CI, you can automate the build of your final distribution and automatically attach the generated .zip file to the release on GitHub. Then, using this installer, you can easily configure your library to install the generated .zip file when installing as `dist` in Composer.
9+
10+
## How it Works
11+
12+
Any package with a direct dependency on `wpscholar/github-archive-installer` and a valid stable version number being installed from distribution will be installed from the GitHub archive `<repo-name>.zip` file associated with a specific release.
13+
14+
For example, if my Composer package is named `wpscholar/hello-world` then my generated .zip file should be named `hello-world.zip` in order to be properly installed using this installer.
15+
16+
This installer only changes the `distUrl` for the package in Composer. It doesn't override any existing installers that work based off of the `type` property in your `composer.json` file. For example, if you have a package of type `wordpress-plugin` your package would still install in the correct location in WordPress. However, when installing from `dist` it would simply pull from the .zip file attached to your GitHub release.

src/GithubArchiveInstaller.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
/**
3+
* Installs GitHub archive files from a release when installing from distribution.
4+
*
5+
* @package wpscholar/Composer/GithubArchiveInstaller
6+
*/
7+
8+
namespace wpscholar\Composer;
9+
10+
use Composer\Composer;
11+
use Composer\DependencyResolver\Operation\OperationInterface;
12+
use Composer\EventDispatcher\EventSubscriberInterface;
13+
use Composer\Installer\PackageEvent;
14+
use Composer\Installer\PackageEvents;
15+
use Composer\IO\IOInterface;
16+
use Composer\Plugin\PluginInterface;
17+
18+
/**
19+
* Class GithubArchiveInstaller
20+
*
21+
* @package wpscholar\Composer
22+
*/
23+
class GithubArchiveInstaller implements PluginInterface, EventSubscriberInterface {
24+
25+
const PACKAGE_TYPE = 'github-archive-installer';
26+
27+
/**
28+
* Composer instance.
29+
*
30+
* @var \Composer\Composer
31+
*/
32+
protected $composer;
33+
34+
/**
35+
* Input/Output interface.
36+
*
37+
* @var \Composer\IO\IOInterface
38+
*/
39+
protected $io;
40+
41+
/**
42+
* Apply plugin modifications to Composer.
43+
*
44+
* @param \Composer\Composer $composer Composer instance
45+
* @param \Composer\IO\IOInterface $io Input/Output interface
46+
*/
47+
public function activate( Composer $composer, IOInterface $io ) {
48+
$this->composer = $composer;
49+
$this->io = $io;
50+
}
51+
52+
/**
53+
* Returns an array of event names this subscriber wants to listen to.
54+
*
55+
* @return array
56+
*/
57+
public static function getSubscribedEvents() {
58+
return array(
59+
PackageEvents::PRE_PACKAGE_INSTALL => 'preInstall',
60+
PackageEvents::PRE_PACKAGE_UPDATE => 'preInstall',
61+
);
62+
}
63+
64+
/**
65+
* Set distribution URL before installing.
66+
*
67+
* @param \Composer\Installer\PackageEvent $event The package install or update event.
68+
*/
69+
public function preInstall( PackageEvent $event ) {
70+
71+
/**
72+
* Get the package instance.
73+
*
74+
* @var \Composer\Package\Package $package
75+
*/
76+
$package = $this->getPackageFromOperation( $event->getOperation() );
77+
78+
if ( array_key_exists( 'wpscholar/github-archive-installer', $package->getRequires() ) ) {
79+
if ( version_compare( $package->getFullPrettyVersion(), '0.0.0', '>=' ) ) {
80+
$package->setDistUrl(
81+
sprintf(
82+
'https://github.com/%1$s/releases/download/%2$s/%3$s.zip',
83+
$package->getName(),
84+
$package->getFullPrettyVersion(),
85+
explode( '/', $package->getName() )[1]
86+
)
87+
);
88+
}
89+
}
90+
}
91+
92+
/**
93+
* Convert operation to package instance.
94+
*
95+
* @param \Composer\DependencyResolver\Operation\OperationInterface $operation The operation
96+
*
97+
* @return \Composer\Package\PackageInterface The package of the operation
98+
*/
99+
public function getPackageFromOperation( OperationInterface $operation ) {
100+
if ( 'update' === $operation->getJobType() ) {
101+
/**
102+
* Operation is an update operation.
103+
*
104+
* @var \Composer\DependencyResolver\Operation\UpdateOperation $operation
105+
*/
106+
return $operation->getTargetPackage();
107+
}
108+
109+
/**
110+
* Operation is an install operation.
111+
*
112+
* @var \Composer\DependencyResolver\Operation\InstallOperation $operation
113+
*/
114+
return $operation->getPackage();
115+
}
116+
117+
}

0 commit comments

Comments
 (0)