├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bin ├── console └── resque ├── cache └── .gitkeep ├── composer.json ├── composer.lock ├── config.yml.dist ├── docker-compose.yml ├── docker └── nginx │ └── vhost.common.d │ └── vhost.common.conf ├── lib └── Composer │ ├── LICENSE │ ├── NOTES.md │ └── Repository │ └── Vcs │ ├── GitHubDriver.php │ └── GitLabDriver.php ├── logs └── .gitkeep ├── migrations.yml ├── phpunit.xml ├── satis └── .gitkeep ├── src ├── Application.php ├── Console │ ├── Application.php │ ├── Command │ │ ├── ContainerAwareCommand.php │ │ ├── Queue │ │ │ ├── ClearCommand.php │ │ │ └── ListCommand.php │ │ └── Worker │ │ │ ├── ListCommand.php │ │ │ ├── StartCommand.php │ │ │ └── StopCommand.php │ └── CommandRegistry.php ├── Controller │ ├── ContainerAwareController.php │ ├── DefaultController.php │ ├── ManageController.php │ ├── PackageController.php │ ├── RemoteController.php │ └── WebHookController.php ├── DependencyInjection │ ├── Compiler │ │ └── OverrideServicesCompilerPass.php │ ├── PackagesConfiguration.php │ └── PackagesExtension.php ├── Entity │ ├── Package.php │ └── Remote.php ├── Event │ ├── PackageEvent.php │ ├── PackageUpdateEvent.php │ └── RemoteEvent.php ├── Events.php ├── Helper │ ├── PluginHelper.php │ ├── ResqueHelper.php │ ├── SyncAdapterInterface.php │ └── SyncHelper.php ├── Job │ └── ContainerAwareJob.php ├── Migration │ ├── Version3100.php │ └── Version3300.php ├── Plugin │ ├── Actions.php │ ├── Bitbucket │ │ ├── Controller.php │ │ ├── PackageConfiguration.php │ │ ├── PackageSubscriber.php │ │ ├── Plugin.php │ │ ├── RemoteConfiguration.php │ │ ├── RemoteSubscriber.php │ │ └── SyncAdapter.php │ ├── CloneProject │ │ ├── CloneProjectJob.php │ │ ├── Controller.php │ │ ├── EventSubscriber.php │ │ ├── Events.php │ │ ├── PackageCloneEvent.php │ │ ├── PackageConfiguration.php │ │ └── Plugin.php │ ├── CompilerAwarePluginInterface.php │ ├── ControllerManager.php │ ├── ControllerManagerInterface.php │ ├── GitHub │ │ ├── Controller.php │ │ ├── PackageConfiguration.php │ │ ├── PackageSubscriber.php │ │ ├── Plugin.php │ │ ├── RemoteConfiguration.php │ │ ├── RemoteSubscriber.php │ │ └── SyncAdapter.php │ ├── GitLab │ │ ├── Controller.php │ │ ├── PackageConfiguration.php │ │ ├── PackageSubscriber.php │ │ ├── Plugin.php │ │ ├── RemoteConfiguration.php │ │ ├── RemoteSubscriber.php │ │ └── SyncAdapter.php │ ├── PluginInterface.php │ ├── RouterPluginInterface.php │ ├── Sami │ │ ├── Controller.php │ │ ├── EventSubscriber.php │ │ ├── PackageConfiguration.php │ │ ├── Plugin.php │ │ └── UpdateJob.php │ └── Satis │ │ ├── Command │ │ ├── BuildCommand.php │ │ └── UpdateCommand.php │ │ ├── ConfigurationHelper.php │ │ ├── Controller.php │ │ ├── EventSubscriber.php │ │ ├── FirewallCompilerPass.php │ │ ├── FrontendController.php │ │ ├── InventoryController.php │ │ ├── PackageConfiguration.php │ │ ├── Plugin.php │ │ └── UpdateAndBuildJob.php ├── Router │ └── RouteCollector.php ├── Security │ └── FirewallSubscriber.php ├── Twig │ ├── PackagesConfigExtension.php │ ├── PluginControllerExtension.php │ └── SecurityExtension.php └── Version.php ├── tests ├── Entity │ ├── PackageTest.php │ └── RemoteTest.php ├── Event │ ├── PackageEventTest.php │ ├── PackageUpdateEventTest.php │ └── RemoteEventTest.php └── Helper │ └── PluginHelperTest.php ├── views ├── Default │ ├── base.html.twig │ ├── index.html.twig │ └── login.html.twig ├── Manage │ └── index.html.twig ├── Package │ ├── edit.html.twig │ └── index.html.twig ├── Plugin │ ├── Bitbucket │ │ ├── edit.html.twig │ │ └── new.html.twig │ ├── CloneProject │ │ └── edit.html.twig │ ├── GitHub │ │ ├── edit.html.twig │ │ └── new.html.twig │ ├── GitLab │ │ ├── edit.html.twig │ │ └── new.html.twig │ ├── Sami │ │ └── edit.html.twig │ ├── Satis │ │ ├── Inventory │ │ │ ├── index.html.twig │ │ │ └── view.html.twig │ │ └── edit.html.twig │ └── _box.html.twig ├── Remote │ ├── edit.html.twig │ ├── index.html.twig │ └── new.html.twig └── base.html.twig └── web ├── .htaccess ├── css ├── AdminLTE.css ├── bootstrap.min.css ├── font-awesome.min.css ├── jquery.dataTables.min.css └── public.css ├── favicon.ico ├── fonts ├── images ├── img └── debut_light.png ├── index.php ├── index_dev.php ├── js ├── AdminLTE │ └── app.js ├── bootstrap.min.js ├── jquery.dataTables.min.js └── jquery.min.js └── robots.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /.settings 3 | /.project 4 | /.buildpath 5 | /.composer 6 | /satis.phar 7 | /vendor 8 | /satis.json 9 | /web/packages.json 10 | /web/include 11 | /web/dist 12 | !/web/robots.txt 13 | /config.yml 14 | /cache/* 15 | /logs/* 16 | /satis/* 17 | /database.sqlite 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.6 4 | - 7.0 5 | - 7.1 6 | install: 7 | - composer install 8 | script: 9 | - php ./vendor/bin/phpunit 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing Guidelines 2 | ======================= 3 | 4 | This document outlines the recommended way to contribute to Packages. 5 | 6 | > More information can be found in the [project documentation](http://docs.terramarlabs.com/packages/3.2). 7 | 8 | Getting started 9 | --------------- 10 | 11 | 1. Fork the [Packages repository](https://github.com/terramar-labs/packages) on GitHub. 12 | 2. Clone your fork. 13 | ```bash 14 | git clone git@github.com:yourname/packages 15 | ``` 16 | 3. Make your modifications, commit your changes, and push to your fork. 17 | ```bash 18 | git add . 19 | git commit -m "A short description about your changes" 20 | git push origin master 21 | ``` 22 | 4. Open a Pull Request on [the terramar-labs/packages GitHub repo](https://github.com/terramar-labs/packages/compare?expand=1). 23 | 5. Be patient, but expect a response. 24 | 6. Work with the project maintainers on any feedback or changes. 25 | 7. Get your changes merged! 26 | 27 | Other considerations 28 | -------------------- 29 | 30 | * The master branch contains active development. 31 | * Create or a feature branch or don't-- whatever you prefer! 32 | * The project follows PSR-1, -2, and -4. 33 | * Consider writing unit tests for your change. 34 | 35 | ### And don't be afraid to ask for help! 36 | 37 | Open an issue if you're not sure about something. We're happy to discuss feature ideas and answer questions. 38 | 39 | > The project maintainers welcome any and all questions and feedback. 40 | > 41 | > Open an [Issue](https://github.com/terramar-labs/packages/issues/new) or email contact@terramarlabs.com to get in touch. 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Terramar Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | boot(); 10 | 11 | $application = new Application($kernel); 12 | $application->run(); 13 | -------------------------------------------------------------------------------- /bin/resque: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 1) { 43 | $count = $COUNT; 44 | } 45 | 46 | $PREFIX = getenv('PREFIX'); 47 | if(!empty($PREFIX)) { 48 | $logger->log(Psr\Log\LogLevel::INFO, 'Prefix set to {prefix}', array('prefix' => $PREFIX)); 49 | Resque_Redis::prefix($PREFIX); 50 | } 51 | 52 | if($count > 1) { 53 | for($i = 0; $i < $count; ++$i) { 54 | $pid = Resque::fork(); 55 | if($pid == -1) { 56 | $logger->log(Psr\Log\LogLevel::EMERGENCY, 'Could not fork worker {count}', array('count' => $i)); 57 | die(); 58 | } 59 | // Child, start the worker 60 | else if(!$pid) { 61 | $queues = explode(',', $QUEUE); 62 | $worker = new Resque_Worker($queues); 63 | $worker->setLogger($logger); 64 | $logger->log(Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', array('worker' => $worker)); 65 | $worker->work($interval, $BLOCKING); 66 | break; 67 | } 68 | } 69 | } 70 | // Start a single worker 71 | else { 72 | $queues = explode(',', $QUEUE); 73 | $worker = new Resque_Worker($queues); 74 | $worker->setLogger($logger); 75 | 76 | $PIDFILE = getenv('PIDFILE'); 77 | if ($PIDFILE) { 78 | file_put_contents($PIDFILE, getmypid()) or 79 | die('Could not write PID information to ' . $PIDFILE); 80 | } 81 | 82 | $logger->log(Psr\Log\LogLevel::NOTICE, 'Starting worker {worker}', array('worker' => $worker)); 83 | $worker->work($interval, $BLOCKING); 84 | } 85 | -------------------------------------------------------------------------------- /cache/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terramar-labs/packages/3f2fb354ddd582d5e4fc68d319287a29e647424f/cache/.gitkeep -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "terramar/packages", 3 | "description": "Packages extends Composer Satis with a management interface and integrations for GitLab and GitHub", 4 | "license": "MIT", 5 | "type": "application", 6 | "require": { 7 | "php": ">=5.6.0", 8 | "ext-pcntl": "*", 9 | "ext-posix": "*", 10 | "ext-json": "*", 11 | "nice/framework": "~1.1", 12 | "nice/security": "~1.0", 13 | "nice/doctrine-orm": "~1.0", 14 | "nice/twig": "2.0.x-dev", 15 | "nice/templating": "1.0.x-dev", 16 | "chrisboulton/php-resque": "dev-master", 17 | "doctrine/migrations": "~1.2", 18 | "symfony/debug": "~2.7", 19 | "symfony/console": "~2.7", 20 | "symfony/process": "~2.7", 21 | "symfony/yaml": "~2.7", 22 | "composer/satis": "^1.0", 23 | "composer/composer": "1.4.3", 24 | "sami/sami": "~1.4", 25 | "m4tthumphrey/php-gitlab-api": "^9.4", 26 | "knplabs/github-api": "~1.4", 27 | "php-http/guzzle6-adapter": "^1.1", 28 | "datatables/datatables": "^1.10", 29 | "twbs/bootstrap": "3.3.7", 30 | "fortawesome/font-awesome": "^4.7", 31 | "components/jquery": "^3.2", 32 | "gentle/bitbucket-api": "^1.1" 33 | }, 34 | "config": { 35 | "platform": { 36 | "php": "5.6" 37 | }, 38 | "component-dir": "vendor" 39 | }, 40 | "require-dev": { 41 | "phpunit/phpunit": "~3.7" 42 | }, 43 | "autoload": { 44 | "psr-4": { 45 | "Terramar\\Packages\\": "src/", 46 | "Composer\\": "lib/Composer/" 47 | } 48 | }, 49 | "extra": { 50 | "branch-alias": { 51 | "dev-master": "3.2-dev" 52 | } 53 | }, 54 | "minimum-stability": "beta", 55 | "prefer-stable": true 56 | } 57 | -------------------------------------------------------------------------------- /config.yml.dist: -------------------------------------------------------------------------------- 1 | security: 2 | # Username and password to access the web management interface 3 | username: somebody 4 | password: password 5 | 6 | doctrine: 7 | mapping: 8 | default: 9 | paths: [ '%app.root_dir%/src/Entity', '%app.root_dir%/src/Plugin' ] 10 | namespace: Terramar 11 | 12 | database: 13 | # Any Doctrine driver 14 | driver: pdo_sqlite 15 | 16 | # Options 17 | path: %app.root_dir%/database.sqlite 18 | # host: 127.0.0.1 19 | # user: root 20 | # password: 21 | # dbname: packages 22 | 23 | packages: 24 | # Defines the name used in the page titles and landing page. 25 | name: 'Terramar Labs' 26 | 27 | # If set, the homepage will be linked to from the landing page. 28 | homepage: 'https://github.com/terramar-labs/packages' 29 | 30 | # If set, the contact email is displayed on the landing page. 31 | contact_email: 'contact@terramarlabs.com' 32 | 33 | # Needs to be set to generate a dist archive 34 | base_path: 'https://localhost' 35 | 36 | # If set, will place a copy of every tagged package version in the web/dist folder 37 | archive: true 38 | 39 | # If set, username and password will be required when attempting to access 40 | # Satis-generated files. 41 | secure_satis: false 42 | 43 | resque: 44 | # Redis server host. 45 | host: 'redis://redis-master' 46 | # Format as either unix:///path/to/socket (note the 3 slashes) or redis://host 47 | #host: 'unix:///var/run/redis.sock' 48 | # If Redis is configured to require a password, you can pass it in the host: 49 | #host: 'redis://ignored:password@host' 50 | # Note that the username portion of the hostname is ignored and can be any value. 51 | 52 | # Redis TCP port. If using a unix socket, this is ignored. 53 | port: ~ 54 | 55 | # Redis database index where jobs will be stored. 56 | database: 4 57 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | web: 4 | image: webdevops/php-nginx:7.1 5 | volumes: 6 | - .:/app 7 | - ./docker/nginx/vhost.common.d/vhost.common.conf:/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf 8 | links: 9 | - redis 10 | environment: 11 | - WEB_DOCUMENT_ROOT=/app/web 12 | ports: 13 | - "127.0.0.1:80:80" # Access Packages in your browser at http://127.0.0.1:80 14 | - "127.0.0.1:443:443" # Access Packages in your browser at https://127.0.0.1:443 15 | redis: 16 | image: redis:3.2 17 | expose: 18 | - "6379" 19 | -------------------------------------------------------------------------------- /docker/nginx/vhost.common.d/vhost.common.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | try_files $uri $uri/ /index_dev.php$is_args$args; 3 | } -------------------------------------------------------------------------------- /lib/Composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /lib/Composer/NOTES.md: -------------------------------------------------------------------------------- 1 | # Explain yourself! 2 | 3 | This "monkey patch" is necessary to allow Packages to use multiple different 4 | GitHub and GitLab auth tokens. Composer and Satis do not allow for this, and 5 | it is not yet clear on how or if it will be implemented upstream. 6 | 7 | > Yes, the warnings after `composer install` and `composer update` are expected. 8 | 9 | The changes to the GitHubDriver and GitLabDriver are very small, so 10 | maintaining these "forked" files shouldn't be that painful. The warning from 11 | composer sure is annoying though. 12 | 13 | 14 | # Details, please 15 | 16 | Packages 3.1 and earlier rely on `git` and having the user's environment 17 | configured. In practice, this means having a valid private SSH key on 18 | your server with access to every repository you need. 19 | 20 | With Packages 3.2, the github or gitlab auth token are loaded from their 21 | respective `RemoteConfiguration` and inserted into the repository options in 22 | the generated Satis configuration. This means that Packages no longer requires 23 | that the user running the Packages application to have a bunch of private keys 24 | different SSH keys configured, and adding a Remote no longer requires logging 25 | in to the server to add such a key. 26 | 27 | It boils down to adding handling for two new keys in a repository: 28 | `github-token` and `gitlab-token`. 29 | 30 | ```json 31 | { 32 | "repositories": [ 33 | { 34 | "type": "vcs", 35 | "url": "git@github.com:somereally/neatproject.git", 36 | "github-token": "123abcdef456", 37 | }, 38 | { 39 | "type": "vcs", 40 | "url": "git@gitlab.example.com:another/awesomeproject.git", 41 | "gitlab-token": "xyz123", 42 | } 43 | ] 44 | } 45 | ``` 46 | 47 | If these values exist, the modified `GitHubDriver` or `GitLabDriver` sets the 48 | token on the Composer IO so the respective API can be used. And since this 49 | is done for every repository, multiple different users on the same GitLab 50 | instance can now easily share a Packages instance. 51 | 52 | Three lines in each file were all that were necessary to accomplish the task: 53 | 54 | ```php 55 | repoConfig['github-token'])) { 69 | $this->io->setAuthentication("github.com", $this->repoConfig['github-token']); 70 | } 71 | 72 | // ... 73 | } 74 | 75 | // ... 76 | } 77 | ``` 78 | 79 | ```php 80 | repoConfig['gitlab-token'])) { 94 | $this->io->setAuthentication($this->originUrl, $this->repoConfig['gitlab-token'], 'private-token'); 95 | } 96 | 97 | // ... 98 | } 99 | 100 | // ... 101 | } 102 | ``` 103 | 104 | The final piece of the puzzle is setting up a new PSR-0 root in `composer.json`. 105 | 106 | ```json 107 | // ... 108 | "autoload": { 109 | // ... 110 | "psr-0": { 111 | "Composer\\": "lib/Composer/" 112 | } 113 | }, 114 | // ... 115 | } 116 | ``` -------------------------------------------------------------------------------- /logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terramar-labs/packages/3f2fb354ddd582d5e4fc68d319287a29e647424f/logs/.gitkeep -------------------------------------------------------------------------------- /migrations.yml: -------------------------------------------------------------------------------- 1 | name: Terramar Labs Packages 2 | migrations_namespace: Terramar\Packages\Migration 3 | migrations_directory: src/Migration 4 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests/ 6 | 7 | 8 | -------------------------------------------------------------------------------- /satis/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terramar-labs/packages/3f2fb354ddd582d5e4fc68d319287a29e647424f/satis/.gitkeep -------------------------------------------------------------------------------- /src/Application.php: -------------------------------------------------------------------------------- 1 | registerDefaultPlugins(); 43 | 44 | $config = Yaml::parse(file_get_contents($this->getRootDir() . '/config.yml')); 45 | $security = isset($config['security']) ? $config['security'] : []; 46 | $doctrine = isset($config['doctrine']) ? $config['doctrine'] : []; 47 | $packages = isset($config['packages']) ? $config['packages'] : []; 48 | if (!isset($packages['resque'])) { 49 | $packages['resque'] = []; 50 | } 51 | 52 | $this->appendExtension(new PackagesExtension($this->plugins, $packages)); 53 | $this->appendExtension(new DoctrineOrmExtension($doctrine)); 54 | $this->appendExtension(new SessionExtension()); 55 | $this->appendExtension(new TemplatingExtension()); 56 | $this->appendExtension(new TwigExtension()); 57 | $this->appendExtension(new SecurityExtension([ 58 | 'authenticator' => [ 59 | 'type' => 'username', 60 | 'username' => isset($security['username']) ? $security['username'] : null, 61 | 'password' => isset($security['password']) 62 | ? password_hash($security['password'], PASSWORD_DEFAULT) 63 | : null, 64 | ], 65 | 'firewall' => '^/manage', 66 | 'success_path' => '/manage', 67 | ])); 68 | } 69 | 70 | /** 71 | * Register default plugins. 72 | */ 73 | protected function registerDefaultPlugins() 74 | { 75 | $this->registerPlugin(new GitLabPlugin()); 76 | $this->registerPlugin(new GitHubPlugin()); 77 | $this->registerPlugin(new BitbucketPlugin()); 78 | $this->registerPlugin(new CloneProjectPlugin()); 79 | $this->registerPlugin(new SamiPlugin()); 80 | $this->registerPlugin(new SatisPlugin()); 81 | } 82 | 83 | /** 84 | * Register a Plugin with the Application. 85 | * 86 | * @param PluginInterface $plugin 87 | */ 88 | public function registerPlugin(PluginInterface $plugin) 89 | { 90 | $this->plugins[$plugin->getName()] = $plugin; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Console/Command/ContainerAwareCommand.php: -------------------------------------------------------------------------------- 1 | container = $container; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Console/Command/Queue/ClearCommand.php: -------------------------------------------------------------------------------- 1 | setName('resque:queue:clear') 23 | ->setDescription('Clear a resque queue') 24 | ->addArgument('queue', InputArgument::REQUIRED, 'Queue name'); 25 | } 26 | 27 | protected function execute(InputInterface $input, OutputInterface $output) 28 | { 29 | ResqueHelper::autoConfigure($this->container); 30 | 31 | /** @var \Terramar\Packages\Helper\ResqueHelper $helper */ 32 | $helper = $this->container->get('packages.helper.resque'); 33 | $queue = $input->getArgument('queue'); 34 | $jobs = $helper->clearQueue($queue); 35 | if ($jobs <= 0) { 36 | $output->writeln(sprintf('Queue "%s" is empty', $queue)); 37 | } else { 38 | $output->writeln(sprintf('Removed %d %s from queue "%s"', $jobs, count($jobs) !== 1 ? 'jobs' : 'job', 39 | $queue)); 40 | } 41 | 42 | $output->writeln(''); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Console/Command/Queue/ListCommand.php: -------------------------------------------------------------------------------- 1 | setName('resque:queue:list') 23 | ->setDescription('List jobs in a resque queue') 24 | ->addArgument('queue', InputArgument::OPTIONAL, 'Queue name', '*'); 25 | } 26 | 27 | protected function execute(InputInterface $input, OutputInterface $output) 28 | { 29 | ResqueHelper::autoConfigure($this->container); 30 | 31 | /** @var \Terramar\Packages\Helper\ResqueHelper $helper */ 32 | $helper = $this->container->get('packages.helper.resque'); 33 | $queue = $input->getArgument('queue'); 34 | $jobs = $helper->getJobs($queue); 35 | if (count($jobs) <= 0) { 36 | if ($queue === '*') { 37 | $output->writeln(sprintf('All queues empty', $queue)); 38 | } else { 39 | $output->writeln(sprintf('Queue "%s" is empty', $queue)); 40 | } 41 | 42 | $output->writeln(''); 43 | 44 | return; 45 | } 46 | 47 | $count = count($jobs); 48 | $output->writeln(sprintf('Queue %s contains %d %s:', $queue, $count, $count !== 1 ? 'entries' : 'entry')); 49 | foreach ($jobs as $job) { 50 | $output->writeln(sprintf('%s', $job)); 51 | } 52 | 53 | $output->writeln(''); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Console/Command/Worker/ListCommand.php: -------------------------------------------------------------------------------- 1 | setName('resque:worker:list') 23 | ->setDescription('List running resque workers') 24 | ->addArgument('queue', InputArgument::OPTIONAL, 'Queue name', '*'); 25 | } 26 | 27 | protected function execute(InputInterface $input, OutputInterface $output) 28 | { 29 | ResqueHelper::autoConfigure($this->container); 30 | 31 | $workers = \Resque_Worker::all(); 32 | 33 | if (count($workers) <= 0) { 34 | $output->writeln([ 35 | 'No workers running', 36 | '', 37 | ]); 38 | 39 | return 0; 40 | } 41 | 42 | $queueFilter = $input->getArgument('queue'); 43 | if ('*' === $queueFilter) { 44 | $queueFilter = false; 45 | } 46 | 47 | $workerOutput = []; 48 | $longestName = 0; 49 | foreach ($workers as $worker) { 50 | $queues = ($worker->queues(true) ?: ['*']); 51 | if ($queueFilter) { 52 | if (!in_array('*', $queues) && !in_array($queueFilter, $queues)) { 53 | continue; 54 | } 55 | } 56 | 57 | $name = (string)$worker; 58 | $job = ($job = $worker->job()) 59 | ? 'Processing ' . json_encode($job) 60 | : 'Waiting for job'; 61 | 62 | if (strlen($job) > 20) { 63 | $job = substr($job, 0, 20) . '...'; 64 | } 65 | 66 | $workerOutput[] = [$name, $job]; 67 | 68 | if (($thisLength = strlen($name)) > $longestName) { 69 | $longestName = $thisLength; 70 | } 71 | } 72 | 73 | $output->writeln(sprintf('%-' . $longestName . "s\t%s", 'Worker ID', 'Current Job')); 74 | $loopFormat = '%-' . $longestName . "s\t%s"; 75 | foreach ($workerOutput as $worker) { 76 | $output->writeln(sprintf($loopFormat, $worker[0], $worker[1])); 77 | } 78 | 79 | $output->writeln(''); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Console/Command/Worker/StopCommand.php: -------------------------------------------------------------------------------- 1 | setName('resque:worker:stop') 24 | ->setDescription('Stop a resque worker') 25 | ->addArgument('id', InputArgument::OPTIONAL, 'Worker id') 26 | ->addOption('all', 'a', InputOption::VALUE_NONE, 'Should kill all workers') 27 | ->addOption('force', 'f', InputOption::VALUE_NONE, 'Force kill all workers, immediately'); 28 | } 29 | 30 | protected function execute(InputInterface $input, OutputInterface $output) 31 | { 32 | ResqueHelper::autoConfigure($this->container); 33 | 34 | if ($input->getOption('all')) { 35 | $workers = \Resque_Worker::all(); 36 | } else { 37 | $worker = \Resque_Worker::find($input->getArgument('id')); 38 | 39 | if (!$worker) { 40 | $availableWorkers = \Resque_Worker::all(); 41 | if (!empty($availableWorkers)) { 42 | throw new \RuntimeException('A running worker must be specified'); 43 | } 44 | } 45 | 46 | $workers = $worker ? [$worker] : []; 47 | } 48 | 49 | if (count($workers) <= 0) { 50 | $output->writeln([ 51 | 'No workers running', 52 | '', 53 | ]); 54 | 55 | return; 56 | } 57 | 58 | $signal = $input->getOption('force') ? SIGTERM : SIGQUIT; 59 | foreach ($workers as $worker) { 60 | $output->writeln(sprintf('%s %s...', $signal === SIGTERM ? 'Force stopping' : 'Stopping', $worker)); 61 | list(, $pid) = explode(':', (string)$worker); 62 | 63 | posix_kill($pid, $signal); 64 | } 65 | 66 | $output->writeln(''); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Console/CommandRegistry.php: -------------------------------------------------------------------------------- 1 | commands[] = $className; 19 | } 20 | 21 | public function getCommands() 22 | { 23 | return $this->commands; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Controller/ContainerAwareController.php: -------------------------------------------------------------------------------- 1 | container = $container; 28 | } 29 | } -------------------------------------------------------------------------------- /src/Controller/DefaultController.php: -------------------------------------------------------------------------------- 1 | getRootDir(); 22 | $packagesJson = $rootDir . '/web/packages.json'; 23 | $mtime = null; 24 | if (file_exists($packagesJson)) { 25 | $mtime = new \DateTime('@' . filemtime($packagesJson)); 26 | } 27 | 28 | return new Response( 29 | $app->get('templating')->render('Default/index.html.twig', [ 30 | 'updatedAt' => $mtime, 31 | ])); 32 | } 33 | 34 | public function loginAction(Application $app, Request $request) 35 | { 36 | $error = false; 37 | $session = $request->getSession(); 38 | if ($session->get(AuthenticationFailureSubscriber::AUTHENTICATION_ERROR)) { 39 | $error = true; 40 | $session->remove(AuthenticationFailureSubscriber::AUTHENTICATION_ERROR); 41 | } 42 | 43 | return new Response($app->get('templating')->render('Default/login.html.twig', ['error' => $error])); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Controller/ManageController.php: -------------------------------------------------------------------------------- 1 | get('doctrine.orm.entity_manager'); 22 | $packages = $entityManager->getRepository('Terramar\Packages\Entity\Package')->createQueryBuilder('p') 23 | ->select('COUNT(p)') 24 | ->where('p.enabled = true') 25 | ->getQuery()->getSingleScalarResult(); 26 | 27 | $remotes = $entityManager->getRepository('Terramar\Packages\Entity\Remote')->createQueryBuilder('c') 28 | ->select('COUNT(c)') 29 | ->where('c.enabled = true') 30 | ->getQuery()->getSingleScalarResult(); 31 | 32 | return new Response($app->get('templating')->render('Manage/index.html.twig', [ 33 | 'packages' => $packages, 34 | 'remotes' => $remotes, 35 | ])); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Controller/WebHookController.php: -------------------------------------------------------------------------------- 1 | container); 24 | 25 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 26 | $entityManager = $app->get('doctrine.orm.entity_manager'); 27 | $package = $entityManager->getRepository('Terramar\Packages\Entity\Package')->findOneBy([ 28 | 'id' => $id, 29 | 'enabled' => true, 30 | ]); 31 | if (!$package || !$package->isEnabled() || !$package->getRemote()->isEnabled()) { 32 | return new Response('Project not found', 404); 33 | } 34 | 35 | $receivedData = json_decode($request->getContent()); 36 | $event = new PackageUpdateEvent($package, $receivedData); 37 | 38 | /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ 39 | $dispatcher = $app->get('event_dispatcher'); 40 | $dispatcher->dispatch(Events::PACKAGE_UPDATE, $event); 41 | 42 | // GitLab 8.3 accepts only "200" as a successful receipt. 43 | return new Response('OK', 200); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/DependencyInjection/Compiler/OverrideServicesCompilerPass.php: -------------------------------------------------------------------------------- 1 | getDefinition('security.security_subscriber') 26 | ->setClass('Terramar\Packages\Security\FirewallSubscriber'); 27 | } 28 | } -------------------------------------------------------------------------------- /src/DependencyInjection/PackagesConfiguration.php: -------------------------------------------------------------------------------- 1 | root('packages'); 26 | 27 | $rootNode 28 | ->children() 29 | ->scalarNode('site_name')->defaultValue('Private Composer Repository')->end() 30 | ->scalarNode('name')->defaultNull()->end() 31 | ->scalarNode('homepage')->defaultValue('')->end() 32 | ->scalarNode('base_path')->defaultValue('')->end() 33 | ->scalarNode('archive')->defaultValue(false)->end() 34 | ->scalarNode('contact_email')->defaultValue('')->end() 35 | ->scalarNode('secure_satis')->defaultFalse()->end() 36 | ->scalarNode('output_dir')->defaultValue('%app.root_dir%/satis')->end() 37 | ->arrayNode('resque') 38 | ->addDefaultsIfNotSet() 39 | ->children() 40 | ->scalarNode('host')->defaultValue('localhost')->end() 41 | ->scalarNode('port')->defaultValue('6379')->end() 42 | ->scalarNode('database')->defaultNull()->end() 43 | ->end() 44 | ->end(); 45 | 46 | return $treeBuilder; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Entity/Remote.php: -------------------------------------------------------------------------------- 1 | enabled; 48 | } 49 | 50 | /** 51 | * @param bool $enabled 52 | */ 53 | public function setEnabled($enabled) 54 | { 55 | $this->enabled = (bool)$enabled; 56 | } 57 | 58 | /** 59 | * @return mixed 60 | */ 61 | public function getId() 62 | { 63 | return $this->id; 64 | } 65 | 66 | /** 67 | * @return mixed 68 | */ 69 | public function getName() 70 | { 71 | return $this->name; 72 | } 73 | 74 | /** 75 | * @param mixed $name 76 | */ 77 | public function setName($name) 78 | { 79 | $this->name = (string)$name; 80 | } 81 | 82 | /** 83 | * @return string 84 | */ 85 | public function getAdapter() 86 | { 87 | return $this->adapter; 88 | } 89 | 90 | /** 91 | * @param string $adapter 92 | */ 93 | public function setAdapter($adapter) 94 | { 95 | $this->adapter = (string)$adapter; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Event/PackageEvent.php: -------------------------------------------------------------------------------- 1 | package = $package; 30 | } 31 | 32 | /** 33 | * @return Package 34 | */ 35 | public function getPackage() 36 | { 37 | return $this->package; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Event/PackageUpdateEvent.php: -------------------------------------------------------------------------------- 1 | payload = $payload; 30 | 31 | parent::__construct($package); 32 | } 33 | 34 | /** 35 | * @return mixed 36 | */ 37 | public function getPayload() 38 | { 39 | return $this->payload; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Event/RemoteEvent.php: -------------------------------------------------------------------------------- 1 | remote = $remote; 30 | } 31 | 32 | /** 33 | * @return Remote 34 | */ 35 | public function getRemote() 36 | { 37 | return $this->remote; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Events.php: -------------------------------------------------------------------------------- 1 | manager = $manager; 43 | $this->handler = $handler; 44 | } 45 | 46 | /** 47 | * @param Request $request 48 | */ 49 | public function setRequest(Request $request = null) 50 | { 51 | $this->request = $request; 52 | } 53 | 54 | /** 55 | * Invoke the given action using the given Request. 56 | * 57 | * @param Request $request 58 | * @param string $action 59 | */ 60 | public function invokeAction(Request $request, $action, $params = []) 61 | { 62 | $controllers = $this->getControllers($action, $params, 63 | array_merge($request->query->all(), $request->request->all())); 64 | 65 | foreach ($controllers as $controller) { 66 | $this->handler->render($controller); 67 | } 68 | } 69 | 70 | /** 71 | * @param $action 72 | * 73 | * @return array|ControllerReference[] 74 | */ 75 | private function getControllers($action, $params = [], $query = []) 76 | { 77 | $params['app'] = $this->request->get('app'); 78 | 79 | return array_map(function ($controller) use ($params, $query) { 80 | return new ControllerReference($controller, $params, $query); 81 | }, $this->manager->getControllers($action)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Helper/ResqueHelper.php: -------------------------------------------------------------------------------- 1 | getParameter('packages.resque.host'); 25 | $redisPort = $container->getParameter('packages.resque.port'); 26 | $redisDatabase = $container->getParameter('packages.resque.database'); 27 | 28 | if (!isset($redisDatabase)) { 29 | $redisDatabase = 0; 30 | } 31 | 32 | $backend = strpos($redisHost, 'unix:') === false ? $redisHost . ':' . $redisPort : $redisHost; 33 | 34 | \Resque::setBackend($backend, $redisDatabase); 35 | 36 | return [ 37 | 'backend' => $backend, 38 | 'database' => $redisDatabase, 39 | ]; 40 | } 41 | 42 | /** 43 | * Clear the given queue. 44 | * 45 | * @param string $queue The name of the queue 46 | * 47 | * @return int The number of removed items 48 | */ 49 | public function clearQueue($queue) 50 | { 51 | $length = \Resque::redis()->llen('queue:' . $queue); 52 | \Resque::redis()->del('queue:' . $queue); 53 | 54 | return $length; 55 | } 56 | 57 | /** 58 | * Enqueue a job, but only if it is not already in the queue. 59 | * 60 | * @param string $queue 61 | * @param string $class 62 | * @param array $args 63 | * @param bool $trackStatus 64 | * 65 | * @return string The enqueued job ID 66 | */ 67 | public function enqueueOnce($queue, $class, $args = null, $trackStatus = false) 68 | { 69 | foreach ($this->getJobs($queue) as $job) { 70 | if ($job->payload['class'] === $class) { 71 | return $job->payload['id']; 72 | } 73 | } 74 | 75 | return $this->enqueue($queue, $class, $args, $trackStatus); 76 | } 77 | 78 | /** 79 | * Get jobs for the given queue. 80 | * 81 | * @param string $queue The name of the queue or "*" for all queues 82 | * 83 | * @return array|\Resque_Job[] 84 | */ 85 | public function getJobs($queue = null) 86 | { 87 | if (!$queue || $queue === '*') { 88 | $queues = \Resque::queues(); 89 | $jobs = []; 90 | foreach ($queues as $queue) { 91 | $jobs = array_merge($jobs, $this->getJobs($queue)); 92 | } 93 | 94 | return $jobs; 95 | } 96 | 97 | return array_map(function ($job) use ($queue) { 98 | return new \Resque_Job($queue, json_decode($job, true)); 99 | }, \Resque::redis()->lrange('queue:' . $queue, 0, -1)); 100 | } 101 | 102 | /** 103 | * Enqueue a job. 104 | * 105 | * @param string $queue 106 | * @param string $class 107 | * @param array $args 108 | * @param bool $trackStatus 109 | * 110 | * @return string The enqueued job ID 111 | */ 112 | public function enqueue($queue, $class, $args = null, $trackStatus = false) 113 | { 114 | return \Resque::enqueue($queue, $class, $args, $trackStatus); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/Helper/SyncAdapterInterface.php: -------------------------------------------------------------------------------- 1 | eventDispatcher = $eventDispatcher; 37 | } 38 | 39 | /** 40 | * Register an adapter with the helper. 41 | * 42 | * @param SyncAdapterInterface $adapter 43 | */ 44 | public function registerAdapter(SyncAdapterInterface $adapter) 45 | { 46 | $this->adapters[$adapter->getName()] = $adapter; 47 | } 48 | 49 | /** 50 | * Synchronize packages in the given configuration. 51 | * 52 | * @param Remote $configuration 53 | * 54 | * @return \Terramar\Packages\Entity\Package[] 55 | */ 56 | public function synchronizePackages(Remote $configuration) 57 | { 58 | $adapter = $this->getAdapter($configuration); 59 | 60 | $packages = $adapter->synchronizePackages($configuration); 61 | 62 | foreach ($packages as $package) { 63 | $event = new PackageEvent($package); 64 | $this->eventDispatcher->dispatch(Events::PACKAGE_CREATE, $event); 65 | } 66 | 67 | return $packages; 68 | } 69 | 70 | private function getAdapter(Remote $configuration) 71 | { 72 | foreach ($this->adapters as $adapter) { 73 | if ($adapter->supports($configuration)) { 74 | return $adapter; 75 | } 76 | } 77 | 78 | throw new \RuntimeException('No adapter registered supports the given configuration'); 79 | } 80 | 81 | /** 82 | * @return array|SyncAdapterInterface[] 83 | */ 84 | public function getAdapters() 85 | { 86 | return array_values($this->adapters); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Job/ContainerAwareJob.php: -------------------------------------------------------------------------------- 1 | run($this->args); 43 | } 44 | 45 | abstract protected function run($args); 46 | 47 | /** 48 | * @return ContainerInterface 49 | */ 50 | protected function getContainer() 51 | { 52 | if ($this->app === null) { 53 | $this->app = $this->createApplication(); 54 | $this->app->boot(); 55 | } 56 | 57 | return $this->app->getContainer(); 58 | } 59 | 60 | /** 61 | * @return Application 62 | */ 63 | protected function createApplication() 64 | { 65 | return new Application( 66 | isset($this->args['app.environment']) ? $this->args['app.environment'] : 'dev', 67 | isset($this->args['app.debug']) ? $this->args['app.debug'] : true, 68 | isset($this->args['app.cache']) ? $this->args['app.cache'] : true 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Migration/Version3100.php: -------------------------------------------------------------------------------- 1 | 3.1. 17 | * 18 | * Only necessary if upgrading from 3.0 to 3.1. 19 | * 20 | * @version 3.1.0 21 | */ 22 | class Version3100 extends AbstractMigration 23 | { 24 | public function up(Schema $schema) 25 | { 26 | $table = $schema->createTable('packages_sami_configurations'); 27 | $table->addColumn('id', 'integer'); 28 | $table->setPrimaryKey(['id']); 29 | $table->addColumn('enabled', 'boolean'); 30 | $table->addColumn('package_id', 'integer'); 31 | $table->addColumn('docs_path', 'string'); 32 | $table->addColumn('repo_path', 'string'); 33 | $table->addColumn('remote_repo_path', 'string'); 34 | $table->addColumn('title', 'string'); 35 | $table->addColumn('theme', 'string'); 36 | $table->addColumn('tags', 'string'); 37 | $table->addColumn('refs', 'string'); 38 | $table->addColumn('templates_dir', 'string'); 39 | $table->addForeignKeyConstraint('packages', ['package_id'], ['id']); 40 | 41 | $table = $schema->createTable('packages_cloneproject_configurations'); 42 | $table->addColumn('id', 'integer'); 43 | $table->setPrimaryKey(['id']); 44 | $table->addColumn('enabled', 'boolean'); 45 | $table->addColumn('package_id', 'integer'); 46 | $table->addForeignKeyConstraint('packages', ['package_id'], ['id']); 47 | } 48 | 49 | public function postUp(Schema $schema) 50 | { 51 | $this->connection->executeQuery('INSERT INTO packages_sami_configurations (package_id, enabled, docs_path, repo_path, remote_repo_path, title, theme, tags, refs, templates_dir) SELECT id, 0, "", "", "", "", "", "", "", "" FROM packages'); 52 | $this->connection->executeQuery('INSERT INTO packages_cloneproject_configurations (package_id, enabled) SELECT id, 0 FROM packages'); 53 | } 54 | 55 | public function down(Schema $schema) 56 | { 57 | $schema->dropTable('packages_sami_configurations'); 58 | $schema->dropTable('packages_cloneproject_configurations'); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Migration/Version3300.php: -------------------------------------------------------------------------------- 1 | 3.3. 17 | * 18 | * Only necessary if upgrading to 3.3. 19 | * 20 | * @version 3.3.0 21 | */ 22 | class Version3300 extends AbstractMigration 23 | { 24 | public function up(Schema $schema) 25 | { 26 | $table = $schema->createTable('packages_bitbucket_remotes'); 27 | $table->addColumn('id', 'integer'); 28 | $table->setPrimaryKey(['id']); 29 | $table->addColumn('enabled', 'boolean'); 30 | $table->addColumn('remote_id', 'integer'); 31 | $table->addColumn('token', 'string'); 32 | $table->addColumn('username', 'string'); 33 | $table->addColumn('account', 'string'); 34 | $table->addForeignKeyConstraint('remotes', ['remote_id'], ['id']); 35 | 36 | $table = $schema->createTable('packages_bitbucket_configurations'); 37 | $table->addColumn('id', 'integer'); 38 | $table->setPrimaryKey(['id']); 39 | $table->addColumn('enabled', 'boolean'); 40 | $table->addColumn('package_id', 'integer'); 41 | $table->addForeignKeyConstraint('packages', ['package_id'], ['id']); 42 | } 43 | 44 | public function postUp(Schema $schema) 45 | { 46 | $this->connection->executeQuery('INSERT INTO packages_bitbucket_remotes (remote_id, enabled, token, username, account) SELECT id, 0, "", "", "" FROM remotes'); 47 | $this->connection->executeQuery('INSERT INTO packages_bitbucket_configurations (package_id, enabled) SELECT id, 0 FROM packages'); 48 | } 49 | 50 | public function down(Schema $schema) 51 | { 52 | $schema->dropTable('packages_bitbucket_remotes'); 53 | $schema->dropTable('packages_bitbucket_configurations'); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Plugin/Actions.php: -------------------------------------------------------------------------------- 1 | get('twig')->render('Plugin/Bitbucket/new.html.twig')); 21 | } 22 | 23 | public function createAction(Application $app, Request $request) 24 | { 25 | $remote = $request->get('remote'); 26 | if ($remote->getAdapter() !== 'Bitbucket') { 27 | return new Response(); 28 | } 29 | 30 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 31 | $entityManager = $app->get('doctrine.orm.entity_manager'); 32 | $config = new RemoteConfiguration(); 33 | $config->setRemote($remote); 34 | $config->setToken($request->get('bitbucket_token')); 35 | $config->setUsername($request->get('bitbucket_username')); 36 | $config->setAccount($request->get('bitbucket_account')); 37 | $config->setEnabled($remote->isEnabled()); 38 | 39 | $entityManager->persist($config); 40 | 41 | return new Response(); 42 | } 43 | 44 | public function editAction(Application $app, Request $request, $id) 45 | { 46 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 47 | $entityManager = $app->get('doctrine.orm.entity_manager'); 48 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\Bitbucket\RemoteConfiguration')->findOneBy([ 49 | 'remote' => $id, 50 | ]); 51 | 52 | return new Response($app->get('twig')->render('Plugin/Bitbucket/edit.html.twig', [ 53 | 'config' => $config ?: new RemoteConfiguration(), 54 | ])); 55 | } 56 | 57 | public function updateAction(Application $app, Request $request, $id) 58 | { 59 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 60 | $entityManager = $app->get('doctrine.orm.entity_manager'); 61 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\Bitbucket\RemoteConfiguration')->findOneBy([ 62 | 'remote' => $id, 63 | ]); 64 | 65 | if (!$config) { 66 | return new Response(); 67 | } 68 | 69 | $config->setToken($request->get('bitbucket_token')); 70 | $config->setUsername($request->get('bitbucket_username')); 71 | $config->setAccount($request->get('bitbucket_account')); 72 | $config->setEnabled($config->getRemote()->isEnabled()); 73 | 74 | $entityManager->persist($config); 75 | 76 | return new Response(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Plugin/Bitbucket/PackageConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 45 | } 46 | 47 | /** 48 | * @return bool 49 | */ 50 | public function isEnabled() 51 | { 52 | return $this->enabled; 53 | } 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getId() 59 | { 60 | return $this->id; 61 | } 62 | 63 | /** 64 | * @return Package 65 | */ 66 | public function getPackage() 67 | { 68 | return $this->package; 69 | } 70 | 71 | /** 72 | * @param Package $package 73 | */ 74 | public function setPackage(Package $package) 75 | { 76 | $this->package = $package; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Plugin/Bitbucket/PackageSubscriber.php: -------------------------------------------------------------------------------- 1 | adapter = $adapter; 38 | $this->entityManager = $entityManager; 39 | } 40 | 41 | /** 42 | * @return array 43 | */ 44 | public static function getSubscribedEvents() 45 | { 46 | return [ 47 | Events::PACKAGE_CREATE => ['onCreatePackage', 255], 48 | Events::PACKAGE_ENABLE => ['onEnablePackage', 255], 49 | Events::PACKAGE_DISABLE => ['onDisablePackage', 255], 50 | ]; 51 | } 52 | 53 | /** 54 | * @param PackageEvent $event 55 | */ 56 | public function onCreatePackage(PackageEvent $event) 57 | { 58 | $package = $event->getPackage(); 59 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\Bitbucket\PackageConfiguration') 60 | ->findOneBy(['package' => $package]); 61 | 62 | if (!$config) { 63 | $config = new PackageConfiguration(); 64 | $config->setPackage($package); 65 | } 66 | 67 | $this->entityManager->persist($config); 68 | } 69 | 70 | /** 71 | * @param PackageEvent $event 72 | */ 73 | public function onEnablePackage(PackageEvent $event) 74 | { 75 | $package = $event->getPackage(); 76 | if ($package->getRemote()->getAdapter() !== 'Bitbucket') { 77 | return; 78 | } 79 | 80 | $this->adapter->enableHook($package); 81 | } 82 | 83 | /** 84 | * @param PackageEvent $event 85 | */ 86 | public function onDisablePackage(PackageEvent $event) 87 | { 88 | $package = $event->getPackage(); 89 | if ($package->getRemote()->getAdapter() !== 'Bitbucket') { 90 | return; 91 | } 92 | 93 | $this->adapter->disableHook($package); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Plugin/Bitbucket/Plugin.php: -------------------------------------------------------------------------------- 1 | register('packages.plugin.bitbucket.adapter', 'Terramar\Packages\Plugin\Bitbucket\SyncAdapter') 30 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 31 | ->addArgument(new Reference('router.url_generator')); 32 | 33 | $container->getDefinition('packages.helper.sync') 34 | ->addMethodCall('registerAdapter', [new Reference('packages.plugin.Bitbucket.adapter')]); 35 | 36 | $container->register('packages.plugin.bitbucket.package_subscriber', 37 | 'Terramar\Packages\Plugin\Bitbucket\PackageSubscriber') 38 | ->addArgument(new Reference('packages.plugin.bitbucket.adapter')) 39 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 40 | ->addTag('kernel.event_subscriber'); 41 | 42 | $container->register('packages.plugin.bitbucket.remote_subscriber', 43 | 'Terramar\Packages\Plugin\Bitbucket\RemoteSubscriber') 44 | ->addArgument(new Reference('packages.plugin.bitbucket.adapter')) 45 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 46 | ->addTag('kernel.event_subscriber'); 47 | 48 | $container->getDefinition('packages.controller_manager') 49 | ->addMethodCall('registerController', 50 | [Actions::REMOTE_NEW, 'Terramar\Packages\Plugin\Bitbucket\Controller::newAction']) 51 | ->addMethodCall('registerController', 52 | [Actions::REMOTE_CREATE, 'Terramar\Packages\Plugin\Bitbucket\Controller::createAction']) 53 | ->addMethodCall('registerController', 54 | [Actions::REMOTE_EDIT, 'Terramar\Packages\Plugin\Bitbucket\Controller::editAction']) 55 | ->addMethodCall('registerController', 56 | [Actions::REMOTE_UPDATE, 'Terramar\Packages\Plugin\Bitbucket\Controller::updateAction']); 57 | } 58 | 59 | /** 60 | * Get the plugin name. 61 | * 62 | * @return string 63 | */ 64 | public function getName() 65 | { 66 | return 'Bitbucket'; 67 | } 68 | 69 | /** 70 | */ 71 | public function getVersion() 72 | { 73 | return; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Plugin/Bitbucket/RemoteConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 60 | } 61 | 62 | /** 63 | * @return bool 64 | */ 65 | public function isEnabled() 66 | { 67 | return $this->enabled; 68 | } 69 | 70 | /** 71 | * @return mixed 72 | */ 73 | public function getId() 74 | { 75 | return $this->id; 76 | } 77 | 78 | /** 79 | * @return Remote 80 | */ 81 | public function getRemote() 82 | { 83 | return $this->remote; 84 | } 85 | 86 | /** 87 | * @param Remote $remote 88 | */ 89 | public function setRemote(Remote $remote) 90 | { 91 | $this->remote = $remote; 92 | } 93 | 94 | /** 95 | * @return mixed 96 | */ 97 | public function getUsername() 98 | { 99 | return $this->username; 100 | } 101 | 102 | /** 103 | * @param mixed $username 104 | */ 105 | public function setUsername($username) 106 | { 107 | $this->username = (string)$username; 108 | } 109 | 110 | /** 111 | * @return mixed 112 | */ 113 | public function getToken() 114 | { 115 | return $this->token; 116 | } 117 | 118 | /** 119 | * @param mixed $token 120 | */ 121 | public function setToken($token) 122 | { 123 | $this->token = (string)$token; 124 | } 125 | 126 | /** 127 | * @param $account 128 | */ 129 | public function setAccount($account) 130 | { 131 | $this->account = $account; 132 | } 133 | 134 | /** 135 | * @return mixed 136 | */ 137 | public function getAccount() 138 | { 139 | return $this->account; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/Plugin/Bitbucket/RemoteSubscriber.php: -------------------------------------------------------------------------------- 1 | adapter = $adapter; 38 | $this->entityManager = $entityManager; 39 | } 40 | 41 | /** 42 | * @return array 43 | */ 44 | public static function getSubscribedEvents() 45 | { 46 | return [ 47 | Events::REMOTE_DISABLE => ['onDisableRemote', 255], 48 | ]; 49 | } 50 | 51 | /** 52 | * @param RemoteEvent $event 53 | */ 54 | public function onDisableRemote(RemoteEvent $event) 55 | { 56 | $remote = $event->getRemote(); 57 | if ($remote->getAdapter() !== 'Bitbucket') { 58 | return; 59 | } 60 | 61 | $packages = $this->entityManager->getRepository('Terramar\Packages\Entity\Package') 62 | ->findBy(['remote' => $remote]); 63 | 64 | foreach ($packages as $package) { 65 | $this->adapter->disableHook($package); 66 | $package->setEnabled(false); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Plugin/CloneProject/CloneProjectJob.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->find('Terramar\Packages\Entity\Package', $args['id']); 23 | if (!$package) { 24 | throw new \RuntimeException('Invalid project'); 25 | } 26 | 27 | $directory = $this->getCacheDir($package); 28 | 29 | if (file_exists($directory) || is_dir($directory)) { 30 | $this->emptyAndRemoveDirectory($directory); 31 | } 32 | 33 | mkdir($directory, 0777, true); 34 | 35 | $builder = new ProcessBuilder(['clone', $package->getSshUrl(), $directory]); 36 | $builder->setPrefix('git'); 37 | 38 | $process = $builder->getProcess(); 39 | $process->run(function ($type, $message) { 40 | echo $message; 41 | }); 42 | 43 | if ($process->isSuccessful()) { 44 | $event = new PackageCloneEvent($package, $directory); 45 | $this->getEventDispatcher()->dispatch(Events::PACKAGE_CLONED, $event); 46 | } 47 | } 48 | 49 | /** 50 | * @return EntityManager 51 | */ 52 | private function getEntityManager() 53 | { 54 | return $this->getContainer()->get('doctrine.orm.entity_manager'); 55 | } 56 | 57 | /** 58 | * @return string 59 | */ 60 | private function getCacheDir(Package $package) 61 | { 62 | return $this->getContainer()->getParameter('app.cache_dir') . '/cloned_project/' . $package->getFqn(); 63 | } 64 | 65 | private function emptyAndRemoveDirectory($directory) 66 | { 67 | $files = array_diff(scandir($directory), ['.', '..']); 68 | foreach ($files as $file) { 69 | (is_dir("$directory/$file")) ? $this->emptyAndRemoveDirectory("$directory/$file") : unlink("$directory/$file"); 70 | } 71 | 72 | return rmdir($directory); 73 | } 74 | 75 | /** 76 | * @return EventDispatcherInterface 77 | */ 78 | private function getEventDispatcher() 79 | { 80 | return $this->getContainer()->get('event_dispatcher'); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Plugin/CloneProject/Controller.php: -------------------------------------------------------------------------------- 1 | get('doctrine.orm.entity_manager'); 22 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\CloneProject\PackageConfiguration')->findOneBy([ 23 | 'package' => $id, 24 | ]); 25 | 26 | return new Response($app->get('twig')->render('Plugin/CloneProject/edit.html.twig', [ 27 | 'config' => $config, 28 | ])); 29 | } 30 | 31 | public function updateAction(Application $app, Request $request, $id) 32 | { 33 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 34 | $entityManager = $app->get('doctrine.orm.entity_manager'); 35 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\CloneProject\PackageConfiguration')->findOneBy([ 36 | 'package' => $id, 37 | ]); 38 | 39 | $config->setEnabled($request->get('cloneproject_enabled') ? true : false); 40 | $entityManager->persist($config); 41 | 42 | return new Response(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Plugin/CloneProject/EventSubscriber.php: -------------------------------------------------------------------------------- 1 | resqueHelper = $resqueHelper; 40 | $this->entityManager = $entityManager; 41 | } 42 | 43 | /** 44 | * @return array 45 | */ 46 | public static function getSubscribedEvents() 47 | { 48 | return [ 49 | Events::PACKAGE_CREATE => ['onCreatePackage', 0], 50 | Events::PACKAGE_UPDATE => ['onUpdatePackage', 0], 51 | ]; 52 | } 53 | 54 | /** 55 | * @param PackageUpdateEvent $event 56 | */ 57 | public function onUpdatePackage(PackageUpdateEvent $event) 58 | { 59 | $package = $event->getPackage(); 60 | /** @var \Terramar\Packages\Plugin\CloneProject\PackageConfiguration $config */ 61 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\CloneProject\PackageConfiguration') 62 | ->findOneBy(['package' => $package]); 63 | 64 | if (!$config || !$config->isEnabled() || !$package->isEnabled()) { 65 | return; 66 | } 67 | 68 | $this->resqueHelper->enqueue('default', 'Terramar\Packages\Plugin\CloneProject\CloneProjectJob', 69 | ['id' => $event->getPackage()->getId()]); 70 | } 71 | 72 | /** 73 | * @param PackageEvent $event 74 | */ 75 | public function onCreatePackage(PackageEvent $event) 76 | { 77 | $package = $event->getPackage(); 78 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\CloneProject\PackageConfiguration') 79 | ->findOneBy(['package' => $package]); 80 | 81 | if (!$config) { 82 | $config = new PackageConfiguration(); 83 | $config->setPackage($package); 84 | } 85 | 86 | $this->entityManager->persist($config); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Plugin/CloneProject/Events.php: -------------------------------------------------------------------------------- 1 | repositoryPath = $repositoryPath; 31 | 32 | parent::__construct($package); 33 | } 34 | 35 | /** 36 | * @return string 37 | */ 38 | public function getRepositoryPath() 39 | { 40 | return $this->repositoryPath; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Plugin/CloneProject/PackageConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 45 | } 46 | 47 | /** 48 | * @return bool 49 | */ 50 | public function isEnabled() 51 | { 52 | return $this->enabled; 53 | } 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getId() 59 | { 60 | return $this->id; 61 | } 62 | 63 | /** 64 | * @return Package 65 | */ 66 | public function getPackage() 67 | { 68 | return $this->package; 69 | } 70 | 71 | /** 72 | * @param Package $package 73 | */ 74 | public function setPackage(Package $package) 75 | { 76 | $this->package = $package; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Plugin/CloneProject/Plugin.php: -------------------------------------------------------------------------------- 1 | register('packages.plugin.clone_project.subscriber', 35 | 'Terramar\Packages\Plugin\CloneProject\EventSubscriber') 36 | ->addArgument(new Reference('packages.helper.resque')) 37 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 38 | ->addTag('kernel.event_subscriber'); 39 | 40 | $container->getDefinition('packages.controller_manager') 41 | ->addMethodCall('registerController', 42 | [Actions::PACKAGE_EDIT, 'Terramar\Packages\Plugin\CloneProject\Controller::editAction']) 43 | ->addMethodCall('registerController', 44 | [Actions::PACKAGE_UPDATE, 'Terramar\Packages\Plugin\CloneProject\Controller::updateAction']); 45 | } 46 | 47 | /** 48 | * Get the plugin name. 49 | * 50 | * @return string 51 | */ 52 | public function getName() 53 | { 54 | return 'git-clone'; 55 | } 56 | 57 | /** 58 | * @return string 59 | */ 60 | public function getVersion() 61 | { 62 | if (!$this->version) { 63 | $matches = []; 64 | preg_match('/version (\d\.\d{1,2}\.\d{1,2})/', exec('git --version'), $matches); 65 | $this->version = $matches[1]; 66 | } 67 | 68 | return $this->version; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Plugin/CompilerAwarePluginInterface.php: -------------------------------------------------------------------------------- 1 | controllers[$action])) { 19 | $this->controllers[$action] = []; 20 | } 21 | 22 | $this->controllers[$action][] = $controller; 23 | } 24 | 25 | public function getControllers($action) 26 | { 27 | return isset($this->controllers[$action]) ? $this->controllers[$action] : []; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Plugin/ControllerManagerInterface.php: -------------------------------------------------------------------------------- 1 | get('twig')->render('Plugin/GitHub/new.html.twig')); 21 | } 22 | 23 | public function createAction(Application $app, Request $request) 24 | { 25 | $remote = $request->get('remote'); 26 | if ($remote->getAdapter() !== 'GitHub') { 27 | return new Response(); 28 | } 29 | 30 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 31 | $entityManager = $app->get('doctrine.orm.entity_manager'); 32 | $config = new RemoteConfiguration(); 33 | $config->setRemote($remote); 34 | $config->setToken($request->get('github_token')); 35 | $config->setUsername($request->get('github_username')); 36 | $config->setEnabled($remote->isEnabled()); 37 | 38 | $entityManager->persist($config); 39 | 40 | return new Response(); 41 | } 42 | 43 | public function editAction(Application $app, Request $request, $id) 44 | { 45 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 46 | $entityManager = $app->get('doctrine.orm.entity_manager'); 47 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\GitHub\RemoteConfiguration')->findOneBy([ 48 | 'remote' => $id, 49 | ]); 50 | 51 | return new Response($app->get('twig')->render('Plugin/GitHub/edit.html.twig', [ 52 | 'config' => $config ?: new RemoteConfiguration(), 53 | ])); 54 | } 55 | 56 | public function updateAction(Application $app, Request $request, $id) 57 | { 58 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 59 | $entityManager = $app->get('doctrine.orm.entity_manager'); 60 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\GitHub\RemoteConfiguration')->findOneBy([ 61 | 'remote' => $id, 62 | ]); 63 | 64 | if (!$config) { 65 | return new Response(); 66 | } 67 | 68 | $config->setToken($request->get('github_token')); 69 | $config->setUsername($request->get('github_username')); 70 | $config->setEnabled($config->getRemote()->isEnabled()); 71 | 72 | $entityManager->persist($config); 73 | 74 | return new Response(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Plugin/GitHub/PackageConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 45 | } 46 | 47 | /** 48 | * @return bool 49 | */ 50 | public function isEnabled() 51 | { 52 | return $this->enabled; 53 | } 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getId() 59 | { 60 | return $this->id; 61 | } 62 | 63 | /** 64 | * @return Package 65 | */ 66 | public function getPackage() 67 | { 68 | return $this->package; 69 | } 70 | 71 | /** 72 | * @param Package $package 73 | */ 74 | public function setPackage(Package $package) 75 | { 76 | $this->package = $package; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Plugin/GitHub/PackageSubscriber.php: -------------------------------------------------------------------------------- 1 | adapter = $adapter; 38 | $this->entityManager = $entityManager; 39 | } 40 | 41 | /** 42 | * @return array 43 | */ 44 | public static function getSubscribedEvents() 45 | { 46 | return [ 47 | Events::PACKAGE_CREATE => ['onCreatePackage', 255], 48 | Events::PACKAGE_ENABLE => ['onEnablePackage', 255], 49 | Events::PACKAGE_DISABLE => ['onDisablePackage', 255], 50 | ]; 51 | } 52 | 53 | /** 54 | * @param PackageEvent $event 55 | */ 56 | public function onCreatePackage(PackageEvent $event) 57 | { 58 | $package = $event->getPackage(); 59 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\GitHub\PackageConfiguration') 60 | ->findOneBy(['package' => $package]); 61 | 62 | if (!$config) { 63 | $config = new PackageConfiguration(); 64 | $config->setPackage($package); 65 | } 66 | 67 | $this->entityManager->persist($config); 68 | } 69 | 70 | /** 71 | * @param PackageEvent $event 72 | */ 73 | public function onEnablePackage(PackageEvent $event) 74 | { 75 | $package = $event->getPackage(); 76 | if ($package->getRemote()->getAdapter() !== 'GitHub') { 77 | return; 78 | } 79 | 80 | $this->adapter->enableHook($package); 81 | } 82 | 83 | /** 84 | * @param PackageEvent $event 85 | */ 86 | public function onDisablePackage(PackageEvent $event) 87 | { 88 | $package = $event->getPackage(); 89 | if ($package->getRemote()->getAdapter() !== 'GitHub') { 90 | return; 91 | } 92 | 93 | $this->adapter->disableHook($package); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Plugin/GitHub/Plugin.php: -------------------------------------------------------------------------------- 1 | register('packages.plugin.github.adapter', 'Terramar\Packages\Plugin\GitHub\SyncAdapter') 30 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 31 | ->addArgument(new Reference('router.url_generator')); 32 | 33 | $container->getDefinition('packages.helper.sync') 34 | ->addMethodCall('registerAdapter', [new Reference('packages.plugin.github.adapter')]); 35 | 36 | $container->register('packages.plugin.github.package_subscriber', 37 | 'Terramar\Packages\Plugin\GitHub\PackageSubscriber') 38 | ->addArgument(new Reference('packages.plugin.github.adapter')) 39 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 40 | ->addTag('kernel.event_subscriber'); 41 | 42 | $container->register('packages.plugin.github.remote_subscriber', 43 | 'Terramar\Packages\Plugin\GitHub\RemoteSubscriber') 44 | ->addArgument(new Reference('packages.plugin.github.adapter')) 45 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 46 | ->addTag('kernel.event_subscriber'); 47 | 48 | $container->getDefinition('packages.controller_manager') 49 | ->addMethodCall('registerController', 50 | [Actions::REMOTE_NEW, 'Terramar\Packages\Plugin\GitHub\Controller::newAction']) 51 | ->addMethodCall('registerController', 52 | [Actions::REMOTE_CREATE, 'Terramar\Packages\Plugin\GitHub\Controller::createAction']) 53 | ->addMethodCall('registerController', 54 | [Actions::REMOTE_EDIT, 'Terramar\Packages\Plugin\GitHub\Controller::editAction']) 55 | ->addMethodCall('registerController', 56 | [Actions::REMOTE_UPDATE, 'Terramar\Packages\Plugin\GitHub\Controller::updateAction']); 57 | } 58 | 59 | /** 60 | * Get the plugin name. 61 | * 62 | * @return string 63 | */ 64 | public function getName() 65 | { 66 | return 'GitHub'; 67 | } 68 | 69 | /** 70 | */ 71 | public function getVersion() 72 | { 73 | return; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Plugin/GitHub/RemoteConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 55 | } 56 | 57 | /** 58 | * @return bool 59 | */ 60 | public function isEnabled() 61 | { 62 | return $this->enabled; 63 | } 64 | 65 | /** 66 | * @return mixed 67 | */ 68 | public function getId() 69 | { 70 | return $this->id; 71 | } 72 | 73 | /** 74 | * @return Remote 75 | */ 76 | public function getRemote() 77 | { 78 | return $this->remote; 79 | } 80 | 81 | /** 82 | * @param Remote $remote 83 | */ 84 | public function setRemote(Remote $remote) 85 | { 86 | $this->remote = $remote; 87 | } 88 | 89 | /** 90 | * @return mixed 91 | */ 92 | public function getUsername() 93 | { 94 | return $this->username; 95 | } 96 | 97 | /** 98 | * @param mixed $username 99 | */ 100 | public function setUsername($username) 101 | { 102 | $this->username = (string)$username; 103 | } 104 | 105 | /** 106 | * @return mixed 107 | */ 108 | public function getToken() 109 | { 110 | return $this->token; 111 | } 112 | 113 | /** 114 | * @param mixed $token 115 | */ 116 | public function setToken($token) 117 | { 118 | $this->token = (string)$token; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Plugin/GitHub/RemoteSubscriber.php: -------------------------------------------------------------------------------- 1 | adapter = $adapter; 38 | $this->entityManager = $entityManager; 39 | } 40 | 41 | /** 42 | * @return array 43 | */ 44 | public static function getSubscribedEvents() 45 | { 46 | return [ 47 | Events::REMOTE_DISABLE => ['onDisableRemote', 255], 48 | ]; 49 | } 50 | 51 | /** 52 | * @param RemoteEvent $event 53 | */ 54 | public function onDisableRemote(RemoteEvent $event) 55 | { 56 | $remote = $event->getRemote(); 57 | if ($remote->getAdapter() !== 'GitHub') { 58 | return; 59 | } 60 | 61 | $packages = $this->entityManager->getRepository('Terramar\Packages\Entity\Package') 62 | ->findBy(['remote' => $remote]); 63 | 64 | foreach ($packages as $package) { 65 | $this->adapter->disableHook($package); 66 | $package->setEnabled(false); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Plugin/GitLab/Controller.php: -------------------------------------------------------------------------------- 1 | get('twig')->render('Plugin/GitLab/new.html.twig')); 21 | } 22 | 23 | public function createAction(Application $app, Request $request) 24 | { 25 | $remote = $request->get('remote'); 26 | if ($remote->getAdapter() !== 'GitLab') { 27 | return new Response(); 28 | } 29 | 30 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 31 | $entityManager = $app->get('doctrine.orm.entity_manager'); 32 | $config = new RemoteConfiguration(); 33 | $config->setRemote($remote); 34 | $config->setToken($request->get('gitlab_token')); 35 | $config->setUrl($request->get('gitlab_url')); 36 | $config->setEnabled($remote->isEnabled()); 37 | $config->setAllowedPaths($request->get('gitlab_allowedPaths')); 38 | 39 | $entityManager->persist($config); 40 | 41 | return new Response(); 42 | } 43 | 44 | public function editAction(Application $app, Request $request, $id) 45 | { 46 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 47 | $entityManager = $app->get('doctrine.orm.entity_manager'); 48 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\GitLab\RemoteConfiguration')->findOneBy([ 49 | 'remote' => $id, 50 | ]); 51 | 52 | return new Response($app->get('twig')->render('Plugin/GitLab/edit.html.twig', [ 53 | 'config' => $config ?: new RemoteConfiguration(), 54 | ])); 55 | } 56 | 57 | public function updateAction(Application $app, Request $request, $id) 58 | { 59 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 60 | $entityManager = $app->get('doctrine.orm.entity_manager'); 61 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\GitLab\RemoteConfiguration')->findOneBy([ 62 | 'remote' => $id, 63 | ]); 64 | 65 | if (!$config) { 66 | return new Response(); 67 | } 68 | 69 | $config->setToken($request->get('gitlab_token')); 70 | $config->setUrl($request->get('gitlab_url')); 71 | $config->setAllowedPaths($request->get('gitlab_allowedPaths')); 72 | $config->setEnabled($config->getRemote()->isEnabled()); 73 | 74 | $entityManager->persist($config); 75 | 76 | return new Response(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Plugin/GitLab/PackageConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 45 | } 46 | 47 | /** 48 | * @return bool 49 | */ 50 | public function isEnabled() 51 | { 52 | return $this->enabled; 53 | } 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getId() 59 | { 60 | return $this->id; 61 | } 62 | 63 | /** 64 | * @return Package 65 | */ 66 | public function getPackage() 67 | { 68 | return $this->package; 69 | } 70 | 71 | /** 72 | * @param Package $package 73 | */ 74 | public function setPackage(Package $package) 75 | { 76 | $this->package = $package; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Plugin/GitLab/PackageSubscriber.php: -------------------------------------------------------------------------------- 1 | adapter = $adapter; 38 | $this->entityManager = $entityManager; 39 | } 40 | 41 | /** 42 | * @return array 43 | */ 44 | public static function getSubscribedEvents() 45 | { 46 | return [ 47 | Events::PACKAGE_CREATE => ['onCreatePackage', 255], 48 | Events::PACKAGE_ENABLE => ['onEnablePackage', 255], 49 | Events::PACKAGE_DISABLE => ['onDisablePackage', 255], 50 | ]; 51 | } 52 | 53 | /** 54 | * @param PackageEvent $event 55 | */ 56 | public function onCreatePackage(PackageEvent $event) 57 | { 58 | $package = $event->getPackage(); 59 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\GitLab\PackageConfiguration') 60 | ->findOneBy(['package' => $package]); 61 | 62 | if (!$config) { 63 | $config = new PackageConfiguration(); 64 | $config->setPackage($package); 65 | } 66 | 67 | $this->entityManager->persist($config); 68 | } 69 | 70 | /** 71 | * @param PackageEvent $event 72 | */ 73 | public function onEnablePackage(PackageEvent $event) 74 | { 75 | $package = $event->getPackage(); 76 | if ($package->getRemote()->getAdapter() !== 'GitLab') { 77 | return; 78 | } 79 | 80 | $this->adapter->enableHook($package); 81 | } 82 | 83 | /** 84 | * @param PackageEvent $event 85 | */ 86 | public function onDisablePackage(PackageEvent $event) 87 | { 88 | $package = $event->getPackage(); 89 | if ($package->getRemote()->getAdapter() !== 'GitLab') { 90 | return; 91 | } 92 | 93 | $this->adapter->disableHook($package); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Plugin/GitLab/Plugin.php: -------------------------------------------------------------------------------- 1 | register('packages.plugin.gitlab.adapter', 'Terramar\Packages\Plugin\GitLab\SyncAdapter') 30 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 31 | ->addArgument(new Reference('router.url_generator')); 32 | 33 | $container->getDefinition('packages.helper.sync') 34 | ->addMethodCall('registerAdapter', [new Reference('packages.plugin.gitlab.adapter')]); 35 | 36 | $container->register('packages.plugin.gitlab.package_subscriber', 37 | 'Terramar\Packages\Plugin\GitLab\PackageSubscriber') 38 | ->addArgument(new Reference('packages.plugin.gitlab.adapter')) 39 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 40 | ->addTag('kernel.event_subscriber'); 41 | 42 | $container->register('packages.plugin.gitlab.remote_subscriber', 43 | 'Terramar\Packages\Plugin\GitLab\RemoteSubscriber') 44 | ->addArgument(new Reference('packages.plugin.gitlab.adapter')) 45 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 46 | ->addTag('kernel.event_subscriber'); 47 | 48 | $container->getDefinition('packages.controller_manager') 49 | ->addMethodCall('registerController', 50 | [Actions::REMOTE_NEW, 'Terramar\Packages\Plugin\GitLab\Controller::newAction']) 51 | ->addMethodCall('registerController', 52 | [Actions::REMOTE_CREATE, 'Terramar\Packages\Plugin\GitLab\Controller::createAction']) 53 | ->addMethodCall('registerController', 54 | [Actions::REMOTE_EDIT, 'Terramar\Packages\Plugin\GitLab\Controller::editAction']) 55 | ->addMethodCall('registerController', 56 | [Actions::REMOTE_UPDATE, 'Terramar\Packages\Plugin\GitLab\Controller::updateAction']); 57 | } 58 | 59 | /** 60 | * Get the plugin name. 61 | * 62 | * @return string 63 | */ 64 | public function getName() 65 | { 66 | return 'GitLab'; 67 | } 68 | 69 | /** 70 | */ 71 | public function getVersion() 72 | { 73 | return; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Plugin/GitLab/RemoteConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 60 | } 61 | 62 | /** 63 | * @return bool 64 | */ 65 | public function isEnabled() 66 | { 67 | return $this->enabled; 68 | } 69 | 70 | /** 71 | * @return mixed 72 | */ 73 | public function getId() 74 | { 75 | return $this->id; 76 | } 77 | 78 | /** 79 | * @return Remote 80 | */ 81 | public function getRemote() 82 | { 83 | return $this->remote; 84 | } 85 | 86 | /** 87 | * @param Remote $remote 88 | */ 89 | public function setRemote(Remote $remote) 90 | { 91 | $this->remote = $remote; 92 | } 93 | 94 | /** 95 | * @return mixed 96 | */ 97 | public function getUrl() 98 | { 99 | return $this->url; 100 | } 101 | 102 | /** 103 | * @param mixed $url 104 | */ 105 | public function setUrl($url) 106 | { 107 | $this->url = (string)$url; 108 | } 109 | 110 | /** 111 | * @return mixed 112 | */ 113 | public function getToken() 114 | { 115 | return $this->token; 116 | } 117 | 118 | /** 119 | * @param mixed $token 120 | */ 121 | public function setToken($token) 122 | { 123 | $this->token = (string)$token; 124 | } 125 | 126 | /** 127 | * @return mixed 128 | */ 129 | public function getAllowedPaths() 130 | { 131 | return $this->allowedPaths; 132 | } 133 | 134 | /** 135 | * @param mixed $allowedPaths 136 | */ 137 | public function setAllowedPaths($allowedPaths) 138 | { 139 | $this->allowedPaths = $allowedPaths; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/Plugin/GitLab/RemoteSubscriber.php: -------------------------------------------------------------------------------- 1 | adapter = $adapter; 38 | $this->entityManager = $entityManager; 39 | } 40 | 41 | /** 42 | * @return array 43 | */ 44 | public static function getSubscribedEvents() 45 | { 46 | return [ 47 | Events::REMOTE_DISABLE => ['onDisableRemote', 255], 48 | ]; 49 | } 50 | 51 | /** 52 | * @param RemoteEvent $event 53 | */ 54 | public function onDisableRemote(RemoteEvent $event) 55 | { 56 | $remote = $event->getRemote(); 57 | if ($remote->getAdapter() !== 'GitLab') { 58 | return; 59 | } 60 | 61 | $packages = $this->entityManager->getRepository('Terramar\Packages\Entity\Package') 62 | ->findBy(['remote' => $remote]); 63 | 64 | foreach ($packages as $package) { 65 | $this->adapter->disableHook($package); 66 | $package->setEnabled(false); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Plugin/PluginInterface.php: -------------------------------------------------------------------------------- 1 | get('doctrine.orm.entity_manager'); 22 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\Sami\PackageConfiguration')->findOneBy([ 23 | 'package' => $id, 24 | ]); 25 | 26 | return new Response($app->get('twig')->render('Plugin/Sami/edit.html.twig', [ 27 | 'config' => $config, 28 | ])); 29 | } 30 | 31 | public function updateAction(Application $app, Request $request, $id) 32 | { 33 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 34 | $entityManager = $app->get('doctrine.orm.entity_manager'); 35 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\Sami\PackageConfiguration')->findOneBy([ 36 | 'package' => $id, 37 | ]); 38 | 39 | $config->setEnabled($request->get('sami_enabled') ? true : false); 40 | $config->setTitle($request->get('sami_title')); 41 | $config->setTheme($request->get('sami_theme')); 42 | $config->setTemplatesDir($request->get('sami_templates_dir')); 43 | $config->setRemoteRepoPath($request->get('sami_remote_repo_path')); 44 | $config->setTags($request->get('sami_tags')); 45 | $config->setRefs($request->get('sami_refs')); 46 | $config->setDocsPath($request->get('sami_docs_path')); 47 | 48 | $entityManager->persist($config); 49 | 50 | return new Response(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Plugin/Sami/EventSubscriber.php: -------------------------------------------------------------------------------- 1 | resqueHelper = $resqueHelper; 41 | $this->entityManager = $entityManager; 42 | } 43 | 44 | /** 45 | * @return array 46 | */ 47 | public static function getSubscribedEvents() 48 | { 49 | return [ 50 | Events::PACKAGE_CREATE => ['onCreatePackage', 0], 51 | CloneProjectEvents::PACKAGE_CLONED => ['onClonePackage', 0], 52 | ]; 53 | } 54 | 55 | /** 56 | * @param PackageCloneEvent $event 57 | */ 58 | public function onClonePackage(PackageCloneEvent $event) 59 | { 60 | $package = $event->getPackage(); 61 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\Sami\PackageConfiguration') 62 | ->findOneBy(['package' => $package]); 63 | 64 | if (!$config || !$config->isEnabled() || !$package->isEnabled()) { 65 | return; 66 | } 67 | 68 | $config->setRepositoryPath($event->getRepositoryPath()); 69 | 70 | $this->entityManager->persist($config); 71 | $this->entityManager->flush($config); 72 | 73 | $this->resqueHelper->enqueue('default', 'Terramar\Packages\Plugin\Sami\UpdateJob', ['id' => $package->getId()]); 74 | } 75 | 76 | /** 77 | * @param PackageEvent $event 78 | */ 79 | public function onCreatePackage(PackageEvent $event) 80 | { 81 | $package = $event->getPackage(); 82 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\Sami\PackageConfiguration') 83 | ->findOneBy(['package' => $package]); 84 | 85 | if (!$config) { 86 | $config = new PackageConfiguration(); 87 | $config->setPackage($package); 88 | } 89 | 90 | $this->entityManager->persist($config); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Plugin/Sami/Plugin.php: -------------------------------------------------------------------------------- 1 | register('packages.plugin.sami.subscriber', 'Terramar\Packages\Plugin\Sami\EventSubscriber') 31 | ->addArgument(new Reference('packages.helper.resque')) 32 | ->addArgument(new Reference('doctrine.orm.entity_manager')) 33 | ->addTag('kernel.event_subscriber'); 34 | 35 | $container->getDefinition('packages.controller_manager') 36 | ->addMethodCall('registerController', 37 | [Actions::PACKAGE_EDIT, 'Terramar\Packages\Plugin\Sami\Controller::editAction']) 38 | ->addMethodCall('registerController', 39 | [Actions::PACKAGE_UPDATE, 'Terramar\Packages\Plugin\Sami\Controller::updateAction']); 40 | } 41 | 42 | /** 43 | * Get the plugin name. 44 | * 45 | * @return string 46 | */ 47 | public function getName() 48 | { 49 | return 'Sami'; 50 | } 51 | 52 | /** 53 | * @return string 54 | */ 55 | public function getVersion() 56 | { 57 | return Sami::VERSION; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Plugin/Satis/Command/BuildCommand.php: -------------------------------------------------------------------------------- 1 | container = $container; 39 | } 40 | 41 | protected function configure() 42 | { 43 | parent::configure(); 44 | 45 | $this->setName('satis:build'); 46 | $def = $this->getDefinition(); 47 | $args = $def->getArguments(); 48 | $args['file'] = new InputArgument('file', InputArgument::OPTIONAL, 49 | 'Satis configuration file. If left blank, one will be generated.'); 50 | $def->setArguments($args); 51 | } 52 | 53 | /** 54 | * @param InputInterface $input The input instance 55 | * @param OutputInterface $output The output instance 56 | */ 57 | protected function execute(InputInterface $input, OutputInterface $output) 58 | { 59 | if (!$input->getArgument('file')) { 60 | $configHelper = $this->container->get('packages.plugin.satis.config_helper'); 61 | $configFile = $configHelper->generateConfiguration(); 62 | $input->setArgument('file', $configFile); 63 | } 64 | 65 | $input->setOption('skip-errors', true); 66 | 67 | $app = $this->getApplication(); 68 | if ($app instanceof Application) { 69 | $this->setIO($app->getIO()); 70 | } 71 | 72 | parent::execute($input, $output); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Plugin/Satis/Command/UpdateCommand.php: -------------------------------------------------------------------------------- 1 | setName('satis:update') 31 | ->setDescription('Updates the project\'s satis.json file') 32 | ->setDefinition([ 33 | new InputArgument('scan-dir', InputArgument::OPTIONAL, 'Directory to look for git repositories'), 34 | new InputOption('build', 'b', InputOption::VALUE_NONE, 'Build packages.json after update'), 35 | new InputOption('skip-errors', null, InputOption::VALUE_NONE, 'Skip Download or Archive errors'), 36 | ]); 37 | } 38 | 39 | /** 40 | * @param InputInterface $input The input instance 41 | * @param OutputInterface $output The output instance 42 | */ 43 | protected function execute(InputInterface $input, OutputInterface $output) 44 | { 45 | $output->writeln([ 46 | 'WARNING: The satis:update command is deprecated. It does not do anything functional but remains for backwards compatibility.', 47 | '', 48 | ]); 49 | 50 | $configHelper = $this->container->get('packages.plugin.satis.config_helper'); 51 | $configFile = $configHelper->generateConfiguration(); 52 | $skipErrors = (bool)$input->getOption('skip-errors'); 53 | 54 | $data = json_decode(file_get_contents($configFile), true); 55 | 56 | foreach ($data['repositories'] as $repository) { 57 | $output->writeln(sprintf('Found repository: %s', $repository['url'])); 58 | } 59 | 60 | $output->writeln([ 61 | 'satis.json updated successfully.', 62 | ]); 63 | 64 | $output->writeln([ 65 | sprintf('Found %s repositories.', count($data['repositories'])), 66 | ]); 67 | 68 | if ($input->getOption('build')) { 69 | $command = $this->getApplication()->find('satis:build'); 70 | $input = new ArrayInput(['file' => $configFile, '--skip-errors' => $skipErrors]); 71 | $command->run($input, $output); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Plugin/Satis/Controller.php: -------------------------------------------------------------------------------- 1 | get('doctrine.orm.entity_manager'); 22 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\Satis\PackageConfiguration')->findOneBy([ 23 | 'package' => $id, 24 | ]); 25 | 26 | return new Response($app->get('twig')->render('Plugin/Satis/edit.html.twig', [ 27 | 'config' => $config, 28 | ])); 29 | } 30 | 31 | public function updateAction(Application $app, Request $request, $id) 32 | { 33 | /** @var \Doctrine\ORM\EntityManager $entityManager */ 34 | $entityManager = $app->get('doctrine.orm.entity_manager'); 35 | $config = $entityManager->getRepository('Terramar\Packages\Plugin\Satis\PackageConfiguration')->findOneBy([ 36 | 'package' => $id, 37 | ]); 38 | 39 | $config->setEnabled($request->get('satis_enabled') ? true : false); 40 | $entityManager->persist($config); 41 | 42 | return new Response(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Plugin/Satis/EventSubscriber.php: -------------------------------------------------------------------------------- 1 | resqueHelper = $resqueHelper; 40 | $this->entityManager = $entityManager; 41 | } 42 | 43 | /** 44 | * @return array 45 | */ 46 | public static function getSubscribedEvents() 47 | { 48 | return [ 49 | Events::PACKAGE_UPDATE => ['onUpdatePackage', 0], 50 | Events::PACKAGE_CREATE => ['onCreatePackage', 0], 51 | ]; 52 | } 53 | 54 | /** 55 | * @param PackageUpdateEvent $event 56 | */ 57 | public function onUpdatePackage(PackageUpdateEvent $event) 58 | { 59 | $package = $event->getPackage(); 60 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\Satis\PackageConfiguration') 61 | ->findOneBy(['package' => $package]); 62 | 63 | if (!$config || !$config->isEnabled() || !$package->isEnabled()) { 64 | return; 65 | } 66 | 67 | $this->resqueHelper->enqueueOnce('default', 'Terramar\Packages\Plugin\Satis\UpdateAndBuildJob', [ 68 | 'package_id' => $package->getId(), 69 | ]); 70 | } 71 | 72 | /** 73 | * @param PackageEvent $event 74 | */ 75 | public function onCreatePackage(PackageEvent $event) 76 | { 77 | $package = $event->getPackage(); 78 | $config = $this->entityManager->getRepository('Terramar\Packages\Plugin\Satis\PackageConfiguration') 79 | ->findOneBy(['package' => $package]); 80 | 81 | if (!$config) { 82 | $config = new PackageConfiguration(); 83 | $config->setPackage($package); 84 | } 85 | 86 | $this->entityManager->persist($config); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Plugin/Satis/FirewallCompilerPass.php: -------------------------------------------------------------------------------- 1 | getParameterBag()->resolveValue('%packages.configuration%'); 25 | if (isset($config['secure_satis']) && $config['secure_satis'] === true) { 26 | $container->getDefinition('security.firewall_matcher') 27 | ->addMethodCall('matchPath', ['^/manage|^/packages(?!\.)']); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Plugin/Satis/FrontendController.php: -------------------------------------------------------------------------------- 1 | secure = isset($config['secure_satis']) ? (bool)$config['secure_satis'] : true; 44 | $this->outputDir = $config['output_dir']; 45 | $this->basePath = $config['base_path']; 46 | $this->authenticator = $authenticator; 47 | } 48 | 49 | /** 50 | * Handles packages.json and include/*.json requests. 51 | * 52 | * If secure_satis is enabled, HTTP Basic authentication will be required. 53 | * The username and password required are those defined in config.yml. 54 | * 55 | * @param Request $request 56 | * @return Response 57 | */ 58 | public function outputAction(Request $request) 59 | { 60 | if ($this->secure) { 61 | $username = $request->getUser(); 62 | $password = $request->getPassword(); 63 | if ( 64 | $this->authenticator->authenticate(new Request(['username' => $username, 'password' => $password])) !== true 65 | ) { 66 | return new Response('', 401, ['WWW-Authenticate' => 'Basic realm="'.$this->basePath.'"']); 67 | } 68 | } 69 | 70 | $path = $this->outputDir.urldecode($request->getPathInfo()); 71 | if (!file_exists($path)) { 72 | return new Response('Not Found', Response::HTTP_NOT_FOUND); 73 | } 74 | 75 | return new Response( 76 | file_get_contents($path), 77 | Response::HTTP_OK, 78 | ['Content-type' => 'application/json']); 79 | } 80 | 81 | /** 82 | * Handles dist/* requests when archive is enabled. 83 | * 84 | * If secure_satis is enabled, HTTP Basic authentication will be required. 85 | * The username and password required are those defined in config.yml. 86 | * 87 | * @param Request $request 88 | * @return Response 89 | */ 90 | public function distAction(Request $request) 91 | { 92 | if ($this->secure) { 93 | $username = $request->getUser(); 94 | $password = $request->getPassword(); 95 | if ( 96 | $this->authenticator->authenticate(new Request(['username' => $username, 'password' => $password])) !== true 97 | ) { 98 | return new Response('', 401, ['WWW-Authenticate' => 'Basic realm="'.$this->basePath.'"']); 99 | } 100 | } 101 | 102 | $path = $this->outputDir.urldecode($request->getPathInfo()); 103 | if (!file_exists($path)) { 104 | return new Response('Not Found', Response::HTTP_NOT_FOUND); 105 | } 106 | 107 | return new Response( 108 | file_get_contents($path), 109 | Response::HTTP_OK, 110 | ['Content-type' => 'application/x-tar', 'Content-disposition' => 'attachment']); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Plugin/Satis/InventoryController.php: -------------------------------------------------------------------------------- 1 | getRepository(); 31 | 32 | $contents = []; 33 | foreach ($repository->getPackages() as $package) { 34 | /* @var \Composer\Package\CompletePackage $package */ 35 | $contents[$package->getName()]['name'] = $package->getName(); 36 | $contents[$package->getName()]['versions'][] = $package->getPrettyVersion(); 37 | } 38 | 39 | return new Response($app->get('templating')->render('Plugin/Satis/Inventory/index.html.twig', [ 40 | 'contents' => $contents, 41 | ])); 42 | } 43 | 44 | /** 45 | * Displays the details for a given package. 46 | */ 47 | public function viewAction(Application $app, $id, $version = null) 48 | { 49 | $repository = $this->getRepository(); 50 | 51 | $id = str_replace('+', '/', $id); 52 | if ($version) { 53 | $version = str_replace('+', '/', $version); 54 | } 55 | 56 | $packages = $repository->findPackages($id); 57 | 58 | usort($packages, function ($a, $b) { 59 | if ($a->getReleaseDate() > $b->getReleaseDate()) { 60 | return -1; 61 | } 62 | 63 | return 1; 64 | }); 65 | 66 | $package = null; 67 | if ($version) { 68 | foreach ($packages as $p) { 69 | if ($p->getPrettyVersion() == $version) { 70 | $package = $p; 71 | } 72 | } 73 | } else { 74 | /* @var \Composer\Package\CompletePackage $package */ 75 | $package = $packages[0]; 76 | } 77 | 78 | return new Response($app->get('templating')->render('Plugin/Satis/Inventory/view.html.twig', [ 79 | 'packages' => $packages, 80 | 'package' => $package, 81 | ])); 82 | } 83 | 84 | /** 85 | * @return \Composer\Repository\ComposerRepository 86 | */ 87 | private function getRepository() 88 | { 89 | $configuration = $this->container->getParameter('packages.configuration'); 90 | 91 | $io = new ConsoleIO(new ArgvInput([]), new ConsoleOutput(), new HelperSet([])); 92 | $config = new Config(); 93 | $config->merge([ 94 | 'config' => [ 95 | 'home' => $this->container->getParameter('app.root_dir'), 96 | ], 97 | ]); 98 | $repository = new ComposerRepository([ 99 | 'url' => 'file://' . $configuration['output_dir'] . '/packages.json', 100 | ], $io, $config); 101 | 102 | return $repository; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Plugin/Satis/PackageConfiguration.php: -------------------------------------------------------------------------------- 1 | enabled = (bool)$enabled; 45 | } 46 | 47 | /** 48 | * @return bool 49 | */ 50 | public function isEnabled() 51 | { 52 | return $this->enabled; 53 | } 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getId() 59 | { 60 | return $this->id; 61 | } 62 | 63 | /** 64 | * @return Package 65 | */ 66 | public function getPackage() 67 | { 68 | return $this->package; 69 | } 70 | 71 | /** 72 | * @param Package $package 73 | */ 74 | public function setPackage(Package $package) 75 | { 76 | $this->package = $package; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Plugin/Satis/UpdateAndBuildJob.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->getRepository(Package::class)->find($args['package_id']); 24 | 25 | $finder = new PhpExecutableFinder(); 26 | $builder = new ProcessBuilder([ 27 | 'bin/console', 28 | 'satis:build', 29 | '--repository-url', 30 | $package->getSshUrl(), 31 | ]); 32 | 33 | $builder->setEnv('HOME', $this->getContainer()->getParameter('app.root_dir')); 34 | $builder->setPrefix($finder->find()); 35 | $builder->setTimeout(null); 36 | 37 | echo $builder->getProcess()->getCommandLine() . "\n"; 38 | 39 | $process = $builder->getProcess(); 40 | $process->run(function ($type, $message) { 41 | echo $message; 42 | }); 43 | } 44 | 45 | /** 46 | * @return EntityManager 47 | */ 48 | private function getEntityManager() 49 | { 50 | return $this->getContainer()->get('doctrine.orm.entity_manager'); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Router/RouteCollector.php: -------------------------------------------------------------------------------- 1 | plugins[$plugin->getName()] = $plugin; 29 | } 30 | 31 | /** 32 | * Perform any collection. 33 | */ 34 | protected function collectRoutes() 35 | { 36 | $this->map('/', 'home', 'Terramar\Packages\Controller\DefaultController::indexAction'); 37 | $this->map('/login', 'login', 'Terramar\Packages\Controller\DefaultController::loginAction'); 38 | $this->map('/logout', 'logout', ''); 39 | 40 | $this->map('/webhook/{id}/receive', 'webhook_receive', 41 | 'Terramar\Packages\Controller\WebHookController::receiveAction', ['POST']); 42 | 43 | $this->map('/manage', 'manage', 'Terramar\Packages\Controller\ManageController::indexAction'); 44 | 45 | $this->map('/manage/packages', 'manage_packages', 46 | 'Terramar\Packages\Controller\PackageController::indexAction'); 47 | $this->map('/manage/package/{id}/edit', 'manage_package_edit', 48 | 'Terramar\Packages\Controller\PackageController::editAction'); 49 | $this->map('/manage/package/{id}/update', 'manage_package_update', 50 | 'Terramar\Packages\Controller\PackageController::updateAction', ['POST']); 51 | $this->map('/manage/package/{id}/toggle', 'manage_package_toggle', 52 | 'Terramar\Packages\Controller\PackageController::toggleAction'); 53 | 54 | $this->map('/manage/remotes', 'manage_remotes', 'Terramar\Packages\Controller\RemoteController::indexAction'); 55 | $this->map('/manage/remote/new', 'manage_remote_new', 56 | 'Terramar\Packages\Controller\RemoteController::newAction'); 57 | $this->map('/manage/remote/create', 'manage_remote_create', 58 | 'Terramar\Packages\Controller\RemoteController::createAction', ['POST']); 59 | $this->map('/manage/remote/{id}/edit', 'manage_remote_edit', 60 | 'Terramar\Packages\Controller\RemoteController::editAction'); 61 | $this->map('/manage/remote/{id}/update', 'manage_remote_update', 62 | 'Terramar\Packages\Controller\RemoteController::updateAction', ['POST']); 63 | $this->map('/manage/remote/{id}/sync', 'manage_remote_sync', 64 | 'Terramar\Packages\Controller\RemoteController::syncAction'); 65 | 66 | foreach ($this->plugins as $plugin) { 67 | $plugin->collect($this); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Twig/PackagesConfigExtension.php: -------------------------------------------------------------------------------- 1 | config = $config; 31 | } 32 | 33 | /** 34 | * @return array 35 | */ 36 | public function getGlobals() 37 | { 38 | return [ 39 | 'packages_conf' => [ 40 | 'name' => $this->config['name'], 41 | 'homepage' => $this->config['homepage'], 42 | 'contact_email' => $this->config['contact_email'], 43 | ], 44 | ]; 45 | } 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getName() 51 | { 52 | return 'packages_conf'; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Twig/PluginControllerExtension.php: -------------------------------------------------------------------------------- 1 | manager = $manager; 46 | $this->handler = $handler; 47 | } 48 | 49 | /** 50 | * @param Request $request 51 | */ 52 | public function setRequest(Request $request = null) 53 | { 54 | $this->request = $request; 55 | } 56 | 57 | /** 58 | * @return array 59 | */ 60 | public function getFunctions() 61 | { 62 | return [ 63 | new \Twig_SimpleFunction('render', [$this, 'render'], ['is_safe' => ['html']]), 64 | new \Twig_SimpleFunction('plugin_controllers', [$this, 'getControllers']), 65 | new \Twig_SimpleFunction('md5', 'md5'), 66 | ]; 67 | } 68 | 69 | /** 70 | * Renders an action. 71 | * 72 | * @param string|ControllerReference $uri 73 | * 74 | * @return string 75 | */ 76 | public function render($uri) 77 | { 78 | return $this->handler->render($uri); 79 | } 80 | 81 | /** 82 | * @param $action 83 | * 84 | * @param array $params 85 | * @return array|ControllerReference 86 | */ 87 | public function getControllers($action, $params = []) 88 | { 89 | $params['app'] = $this->request->get('app'); 90 | 91 | return array_map(function ($controller) use ($params) { 92 | return new ControllerReference($controller, $params); 93 | }, $this->manager->getControllers($action)); 94 | } 95 | 96 | /** 97 | * @return string 98 | */ 99 | public function getName() 100 | { 101 | return 'plugin'; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Twig/SecurityExtension.php: -------------------------------------------------------------------------------- 1 | request !== null) { 33 | return $this->request->getSession()->get('__nice.is_authenticated', false); 34 | } 35 | return false; 36 | }) 37 | ]; 38 | } 39 | 40 | /** 41 | * @return string 42 | */ 43 | public function getName() 44 | { 45 | return 'security'; 46 | } 47 | 48 | /** 49 | * @param Request|null $request 50 | */ 51 | public function setRequest(Request $request = null) 52 | { 53 | $this->request = $request; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Version.php: -------------------------------------------------------------------------------- 1 | sut = new Package(); 23 | } 24 | 25 | public function testGetAndSetId() 26 | { 27 | $this->assertEquals(null, $this->sut->getId()); 28 | 29 | // XXX Doctrine uses reflection, so there's no other way 30 | // to unit test this 31 | $reflProp = new \ReflectionProperty('Terramar\Packages\Entity\Package', 'id'); 32 | $reflProp->setAccessible(true); 33 | $reflProp->setValue($this->sut, 345); 34 | $reflProp->setAccessible(false); 35 | $this->assertEquals(345, $this->sut->getId()); 36 | } 37 | 38 | public function testIsAndSetEnabled() 39 | { 40 | $this->assertEquals(false, $this->sut->isEnabled()); 41 | $this->sut->setEnabled(true); 42 | $this->assertEquals(true, $this->sut->isEnabled()); 43 | } 44 | 45 | public function testGetAndSetDescription() 46 | { 47 | $this->assertEquals(null, $this->sut->getDescription()); 48 | $this->sut->setDescription('foo'); 49 | $this->assertEquals('foo', $this->sut->getDescription()); 50 | } 51 | 52 | public function testGetAndSetName() 53 | { 54 | $this->assertEquals(null, $this->sut->getName()); 55 | $this->sut->setName('bar'); 56 | $this->assertEquals('bar', $this->sut->getName()); 57 | } 58 | 59 | public function testGetAndSetRemote() 60 | { 61 | $this->assertEquals(null, $this->sut->getRemote()); 62 | 63 | $expected = new Remote(); 64 | $this->sut->setRemote($expected); 65 | $this->assertEquals($expected, $this->sut->getRemote()); 66 | } 67 | 68 | public function testGetAndSetExternalId() 69 | { 70 | $this->assertEquals(null, $this->sut->getExternalId()); 71 | $this->sut->setExternalId('1234erty'); 72 | $this->assertEquals('1234erty', $this->sut->getExternalId()); 73 | } 74 | 75 | public function testGetAndSetHookExternalId() 76 | { 77 | $this->assertEquals(null, $this->sut->getHookExternalId()); 78 | $this->sut->setHookExternalId('rewq431'); 79 | $this->assertEquals('rewq431', $this->sut->getHookExternalId()); 80 | } 81 | 82 | public function testGetAndSetFqn() 83 | { 84 | $this->assertEquals(null, $this->sut->getFqn()); 85 | $this->sut->setFqn('My FQN'); 86 | $this->assertEquals('My FQN', $this->sut->getFqn()); 87 | } 88 | 89 | public function testGetAndSetSshUrl() 90 | { 91 | $this->assertEquals(null, $this->sut->getSshUrl()); 92 | $this->sut->setSshUrl('my.ssh.url'); 93 | $this->assertEquals('my.ssh.url', $this->sut->getSshUrl()); 94 | } 95 | 96 | public function testGetAndSetWebUrl() 97 | { 98 | $this->assertEquals(null, $this->sut->getWebUrl()); 99 | $this->sut->setWebUrl('your.web.url'); 100 | $this->assertEquals('your.web.url', $this->sut->getWebUrl()); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /tests/Entity/RemoteTest.php: -------------------------------------------------------------------------------- 1 | sut = new Remote(); 22 | } 23 | 24 | public function testGetAndSetId() 25 | { 26 | $this->assertEquals(null, $this->sut->getId()); 27 | 28 | // XXX Doctrine uses reflection, so there's no other way 29 | // to unit test this 30 | $reflProp = new \ReflectionProperty('Terramar\Packages\Entity\Remote', 'id'); 31 | $reflProp->setAccessible(true); 32 | $reflProp->setValue($this->sut, 345); 33 | $reflProp->setAccessible(false); 34 | $this->assertEquals(345, $this->sut->getId()); 35 | } 36 | 37 | public function testIsAndSetEnabled() 38 | { 39 | $this->assertEquals(true, $this->sut->isEnabled()); 40 | $this->sut->setEnabled(false); 41 | $this->assertEquals(false, $this->sut->isEnabled()); 42 | } 43 | 44 | public function testGetAndSetAdapter() 45 | { 46 | $this->assertEquals(null, $this->sut->getAdapter()); 47 | $this->sut->setAdapter('foo'); 48 | $this->assertEquals('foo', $this->sut->getAdapter()); 49 | } 50 | 51 | public function testGetAndSetName() 52 | { 53 | $this->assertEquals(null, $this->sut->getName()); 54 | $this->sut->setName('bar'); 55 | $this->assertEquals('bar', $this->sut->getName()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/Event/PackageEventTest.php: -------------------------------------------------------------------------------- 1 | package = new Package(); 26 | $this->sut = new PackageEvent($this->package); 27 | } 28 | 29 | public function testGetPackage() 30 | { 31 | $this->assertSame($this->package, $this->sut->getPackage()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/Event/PackageUpdateEventTest.php: -------------------------------------------------------------------------------- 1 | remote = new Remote(); 26 | $this->sut = new RemoteEvent($this->remote); 27 | } 28 | 29 | public function testGetRemote() 30 | { 31 | $this->assertSame($this->remote, $this->sut->getRemote()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/Event/RemoteEventTest.php: -------------------------------------------------------------------------------- 1 | package = new Package(); 26 | $this->sut = new PackageEvent($this->package); 27 | } 28 | 29 | public function testGetPackage() 30 | { 31 | $this->assertSame($this->package, $this->sut->getPackage()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/Helper/PluginHelperTest.php: -------------------------------------------------------------------------------- 1 | controllerManager = $this->getMock('Terramar\Packages\Plugin\ControllerManagerInterface'); 32 | $this->fragmentHandler = $this->getMock('Symfony\Component\HttpKernel\Fragment\FragmentHandler'); 33 | $this->sut = new PluginHelper($this->controllerManager, $this->fragmentHandler); 34 | } 35 | 36 | public function testInvokeAction() 37 | { 38 | $controllerRefCount = 0; 39 | $controllerList = array( 40 | 'C1', 41 | 'B1', 42 | 'A5', 43 | 'D2', 44 | ); 45 | $action = 'awesomeAction'; 46 | $params = array( 47 | 'goo' => 'boo', 48 | ); 49 | 50 | $request = new Request($query = array( 51 | 'foo' => 'bar', 52 | 'baz' => 'shoo', 53 | ), $requestParams = array( 54 | 'a' => 'kaboom', 55 | 'd' => 'achoo', 56 | )); 57 | 58 | $memberRequest = new Request(array(), array(), $attributes = array( 59 | 'app' => 'foobarbaz', 60 | )); 61 | $this->sut->setRequest($memberRequest); 62 | 63 | $mergedParams = array_merge(array(), $params, $attributes); 64 | $mergedQuery = array_merge(array(), $query, $requestParams); 65 | 66 | $this->controllerManager->expects($this->any()) 67 | ->method('getControllers') 68 | ->with($action) 69 | ->will($this->returnValue($controllerList)); 70 | 71 | $controllersAdded = array(); 72 | 73 | $this->fragmentHandler->expects($this->exactly(count($controllerList))) 74 | ->method('render') 75 | ->with($this->logicalAnd($this->isInstanceOf('Symfony\Component\HttpKernel\Controller\ControllerReference'), $this->callback(function (ControllerReference $cr) use (&$controllersAdded, $controllerList, $mergedParams,$mergedQuery) { 76 | $controllersAdded[] = $cr->controller; 77 | // XXX PHPUnit bug prevents us from doing an order-based test here 78 | // TODO upgrade PHPUnit 79 | return in_array($cr->controller, $controllerList) && count(array_diff_assoc($mergedParams, $cr->attributes)) < 1 && count(array_diff_assoc($mergedQuery, $cr->query)) < 1; 80 | }))); 81 | 82 | $this->sut->invokeAction($request, $action, $params); 83 | 84 | $this->assertEmpty(array_diff($controllerList, array_unique($controllersAdded))); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /views/Default/base.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Packages - {{ packages_conf.name }} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 |
20 | 21 |
22 |

23 | Composer Repository 24 | for {{ packages_conf.name }} 25 |

26 | {% block login_link %} 27 | {% if logged_in() %} 28 | 32 | {% else %} 33 | 36 | {% endif %} 37 | {% endblock %} 38 |
39 | 40 |
41 | {% block body %} 42 | {% endblock %} 43 |
44 | {% if packages_conf.homepage is not empty %} 45 | 50 | {% endif %} 51 |
52 |
53 |

Proudly powered by Satis {{ constant('Composer\\Satis\\Satis::VERSION') }} 54 | and Packages {{ constant('Terramar\\Packages\\Version::VERSION') }} 55 | {% if updatedAt %}Last updated: {{ updatedAt|date('Y-m-d H:i:s') }}{% endif %} 56 |

57 |
58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /views/Default/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Default/base.html.twig' %} 2 | 3 | {% block body %} 4 |

This is a private repository.

5 | {% if packages_conf.contact_email is not empty %} 6 |

If you should have access, contact us. 7 | {{ packages_conf.contact_email }} 8 |

9 | {% endif %} 10 | Available Packages 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /views/Default/login.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Default/base.html.twig' %} 2 | 3 | {% block body %} 4 |

Please login.

5 |
6 | {% if error %}
Invalid username or password.
{% endif %} 7 |

8 |

9 |

10 |
11 | {% endblock %} 12 | 13 | {% block login_link %}{% endblock %} 14 | -------------------------------------------------------------------------------- /views/Manage/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'base.html.twig' %} 2 | 3 | {% block title 'Dashboard' %} 4 | 5 | {% block alt_title '' %} 6 | 7 | {% block content %} 8 |
9 |
10 | 11 |
12 |
13 |

14 | {{ packages|number_format }} 15 |

16 |

17 | Package{% if packages != 1 %}s{% endif %} 18 |

19 |
20 |
21 | 22 |
23 | 24 | More info 25 | 26 |
27 |
28 |
29 |
30 | 31 |
32 |
33 |

34 | {{ remotes|number_format }} 35 |

36 |

37 | Remote{% if remotes != 1 %}s{% endif %} 38 |

39 |
40 |
41 | 42 |
43 | 44 | More info 45 | 46 |
47 |
48 |
49 | {% for controller in plugin_controllers(constant('Terramar\\Packages\\Plugin\\Actions::DASHBOARD_INDEX')) %} 50 |
51 | {{ render(controller) }} 52 |
53 | {% endfor %} 54 |
55 | {% endblock %} 56 | -------------------------------------------------------------------------------- /views/Package/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'base.html.twig' %} 2 | 3 | {% block title 'Packages' %} 4 | 5 | {% block alt_title '' %} 6 | 7 | {% block content %} 8 |
9 |
10 |
11 |
12 |

Showing all packages

13 |
14 |
15 | {% if packages|length %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% for package in packages %} 27 | 28 | 29 | 30 | 31 | 41 | 42 | {% endfor %} 43 | 44 |
NameInstanceEnabledActions
{{ package.name }} ({{ package.fqn }}){{ package.remote.name }}{{ package.enabled ? 'Enabled' : 'Disabled' }} 32 |
33 | Edit 34 | {% if package.enabled %} 35 | Disable 36 | {% else %} 37 | Enable 38 | {% endif %} 39 |
40 |
45 | {% else %} 46 |

No packages. Synchronize remote repositories to add packages.

47 | {% endif %} 48 |
49 |
50 |
51 | 52 |
53 | {% endblock %} 54 | 55 | {% block javascripts %} 56 | 66 | {% endblock %} 67 | -------------------------------------------------------------------------------- /views/Plugin/Bitbucket/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% set box_type = 'box-warning' %} 4 | 5 | {% block title %}Bitbucket{% endblock %} 6 | 7 | {% block body %} 8 |
9 | Configure Bitbucket settings for this remote 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | 22 |
23 | {% endblock %} 24 | 25 | {% block javascripts %} 26 | 43 | {% endblock %} 44 | -------------------------------------------------------------------------------- /views/Plugin/Bitbucket/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% set box_type = 'box-warning' %} 4 | 5 | {% block title %}Bitbucket{% endblock %} 6 | 7 | {% block body %} 8 |
9 | Configure Bitbucket settings for this remote 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | 22 |
23 | {% endblock %} 24 | 25 | {% block javascripts %} 26 | 43 | {% endblock %} 44 | -------------------------------------------------------------------------------- /views/Plugin/CloneProject/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% block title %}Clone Project{% endblock %} 4 | 5 | {% block body %} 6 |
7 | Clone this project locally after each code push. 8 |
9 |
10 | 13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /views/Plugin/GitHub/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% set box_type = 'box-warning' %} 4 | 5 | {% block title %}GitHub{% endblock %} 6 | 7 | {% block body %} 8 |
9 | Configure GitHub settings for this remote 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 | {% endblock %} 20 | 21 | {% block javascripts %} 22 | 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /views/Plugin/GitHub/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% set box_type = 'box-warning' %} 4 | 5 | {% block title %}GitHub{% endblock %} 6 | 7 | {% block body %} 8 |
9 | Configure GitHub settings for this remote 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 | {% endblock %} 20 | 21 | {% block javascripts %} 22 | 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /views/Plugin/GitLab/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% set box_type = 'box-warning' %} 4 | 5 | {% block title %}GitLab{% endblock %} 6 | 7 | {% block body %} 8 |
9 | Configure GitLab settings for this remote 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | Enter a comma list of allowed pathes to sync, empty field disable this feature 22 | 23 |
24 | {% endblock %} 25 | 26 | {% block javascripts %} 27 | 44 | {% endblock %} 45 | -------------------------------------------------------------------------------- /views/Plugin/GitLab/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% set box_type = 'box-warning' %} 4 | 5 | {% block title %}GitLab{% endblock %} 6 | 7 | {% block body %} 8 |
9 | Configure GitLab settings for this remote 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | Enter a comma list of allowed pathes to sync, empty field disable this feature 22 | 23 |
24 | {% endblock %} 25 | 26 | {% block javascripts %} 27 | 44 | {% endblock %} 45 | -------------------------------------------------------------------------------- /views/Plugin/Sami/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% block title %}Sami{% endblock %} 4 | 5 | {% block body %} 6 |
7 | Automatically generate documentation for this project using Sami 8 |
9 |
10 | 13 |
14 | 17 | 21 | 25 | 29 | 33 | 37 | 41 | 45 | {% endblock %} 46 | 47 | {% block javascripts %} 48 | 82 | {% endblock %} 83 | -------------------------------------------------------------------------------- /views/Plugin/Satis/Inventory/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Default/base.html.twig' %} 2 | 3 | {% block body %} 4 |

To add the following packages, you'll have to add the following code to the repositories key in composer.json. For more information see composer repositories:

5 |
{
 6 |     "type": "composer",
 7 |     "url": "{{ url('home') }}"
 8 | },
9 |

Available Packages

10 | 11 | 12 | 13 | 14 | 15 | {% for package in contents %} 16 | 17 | {% endfor %} 18 |
NameVersion
{{ package.name }}{{ package.versions|join(' ')|raw }}
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /views/Plugin/Satis/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'Plugin/_box.html.twig' %} 2 | 3 | {% block title %}Composer Satis{% endblock %} 4 | 5 | {% block body %} 6 |
7 | Expose this package via Satis 8 |
9 |
10 | 13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /views/Plugin/_box.html.twig: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{% block title %}{% endblock %}

4 |
5 |
6 | {% block body %}{% endblock %} 7 |
8 | {% block javascripts %}{% endblock %} 9 |
-------------------------------------------------------------------------------- /views/Remote/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'base.html.twig' %} 2 | 3 | {% block title 'Edit Remote' %} 4 | 5 | {% block alt_title 'Edit an existing remote source code host configuration' %} 6 | 7 | {% block content %} 8 |
9 |
10 |
11 |
12 |
13 |

Configure Remote

14 | What's this?   15 |
16 |
17 | 24 |
25 | 26 | 27 |
28 |
29 | 30 | 33 |
34 |
35 | 38 |
39 |
40 | 41 | 44 |
45 |
46 | {% for controller in plugin_controllers(constant('Terramar\\Packages\\Plugin\\Actions::REMOTE_EDIT'), { id: remote.id }) %} 47 | 50 | {% endfor %} 51 |
52 |
53 | {% endblock %} 54 | 55 | {% block javascripts %} 56 | 66 | {% endblock %} -------------------------------------------------------------------------------- /views/Remote/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'base.html.twig' %} 2 | 3 | {% block title 'Remote Code Hosts' %} 4 | 5 | {% block alt_title 'Configure remote code repository hosts' %} 6 | 7 | {% block content %} 8 |
9 |
10 | 11 | {% if last_error %} 12 | {# 13 |
14 |
15 |
An error occurred while syncing.
16 |
17 |
18 |

Packages was unable to load information from the remote code host. Please try again.

19 | Details 20 | 21 |
22 |
#} 23 |
24 |

An error occurred while syncing.

25 |

Packages was unable to load information from the remote code host. Please try again.

26 | Details 27 | 31 |
32 | {% endif %} 33 |
34 |
35 |

Showing all configured remote code hosts

36 |
37 | New Remote 38 |
39 |
40 |
41 | {% if remotes|length %} 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {% for remote in remotes %} 52 | 53 | 54 | 55 | 63 | 64 | {% endfor %} 65 | 66 |
NameEnabledActions
{{ remote.name }}{{ remote.enabled ? 'Enabled' : 'Disabled' }} 56 |
57 | Edit 58 | {% if remote.enabled %} 59 | Sync 60 | {% endif %} 61 |
62 |
67 | {% else %} 68 |

No remote code hosts configured. Add a new remote.

69 | {% endif %} 70 |
71 |
72 |
73 | 74 |
75 | {% endblock %} 76 | 77 | {% block javascripts %} 78 | 97 | {% endblock %} 98 | -------------------------------------------------------------------------------- /views/Remote/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'base.html.twig' %} 2 | 3 | {% block title 'New Remote' %} 4 | 5 | {% block alt_title 'Create a new remote code host configuration' %} 6 | 7 | {% block content %} 8 |
9 |
10 |
11 |
12 |
13 |

Configure Remote

14 | What's this?   15 |
16 | 17 |
18 | 25 |
26 | 27 | 28 |
29 |
30 | 31 | 36 |
37 |
38 | 41 |
42 |
43 | 44 | 47 | 48 |
49 |
50 | {% for controller in plugin_controllers(constant('Terramar\\Packages\\Plugin\\Actions::REMOTE_NEW')) %} 51 | 54 | {% endfor %} 55 |
56 |
57 | {% endblock %} 58 | 59 | {% block javascripts %} 60 | 70 | {% endblock %} -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | DirectoryIndex index.php 2 | 3 | 4 | RewriteEngine On 5 | 6 | RewriteCond %{HTTPS} off 7 | RewriteCond %{HTTP:X-Forwarded-Proto} !https 8 | RewriteCond %{REMOTE_ADDR} !=127.0.0.1 9 | RewriteCond %{REMOTE_ADDR} !=::1 10 | RewriteCond %{REMOTE_ADDR} !=fe80::1 11 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [QSA,L] 12 | 13 | RewriteCond %{ENV:REDIRECT_STATUS} ^$ 14 | RewriteRule ^index\.php(/(.*)|$) %{CONTEXT_PREFIX}/$2 [R=301,L] 15 | 16 | RewriteCond %{REQUEST_FILENAME} -f 17 | RewriteRule .? - [L] 18 | 19 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ 20 | RewriteRule ^(.*) - [E=BASE:%1] 21 | RewriteRule .? %{ENV:BASE}index.php [L] 22 | 23 | -------------------------------------------------------------------------------- /web/css/bootstrap.min.css: -------------------------------------------------------------------------------- 1 | ../../vendor/twbs/bootstrap/dist/css/bootstrap.min.css -------------------------------------------------------------------------------- /web/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | ../../vendor/fortawesome/font-awesome/css/font-awesome.min.css -------------------------------------------------------------------------------- /web/css/jquery.dataTables.min.css: -------------------------------------------------------------------------------- 1 | ../../vendor/datatables/datatables/media/css/jquery.dataTables.min.css -------------------------------------------------------------------------------- /web/css/public.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Source Sans Pro', sans-serif; 3 | -webkit-font-smoothing: antialiased; 4 | min-height: 100%; 5 | background: url('../img/debut_light.png') repeat #f9f9f9; 6 | } 7 | 8 | a { 9 | color: #3c8dbc; 10 | } 11 | 12 | a:hover, 13 | a:active, 14 | a:focus { 15 | outline: none; 16 | text-decoration: none; 17 | color: #72afd2; 18 | } 19 | 20 | h1 { 21 | margin: 0; 22 | display: inline-block; 23 | } 24 | 25 | .login-link { 26 | float: right; 27 | display: inline-block; 28 | text-transform: uppercase; 29 | } 30 | 31 | .wrapper { 32 | margin-top: 40px; 33 | background-color: white; 34 | border: 1px solid #CCCCCC; 35 | height: 100%; 36 | padding: 30px; 37 | border-radius: 4px; 38 | } 39 | 40 | .content { 41 | background-color: transparent; 42 | } 43 | 44 | .content-header { 45 | margin-bottom: 30px; 46 | } 47 | 48 | .content-body { 49 | margin: 30px 0; 50 | } 51 | 52 | .content-footer { 53 | margin-top: 30px; 54 | } 55 | 56 | .contact { 57 | color: #777; 58 | user-select: none; 59 | cursor: default; 60 | } 61 | 62 | .last-update, .contact { 63 | display: block; 64 | } 65 | 66 | .powered-by { 67 | margin-top: 5px; 68 | text-align: center; 69 | color: #777; 70 | } 71 | 72 | @media only screen and (min-width: 480px) { 73 | .last-update:before { 74 | content: "- "; 75 | } 76 | 77 | .last-update, .contact { 78 | display: inline-block; 79 | } 80 | } 81 | 82 | 83 | @media only screen and (max-width: 992px) { 84 | .wrapper { 85 | margin: 15px; 86 | padding: 20px; 87 | } 88 | } 89 | 90 | ul { 91 | padding-left:20px; 92 | } 93 | 94 | .label { 95 | margin-right:3px; 96 | } -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terramar-labs/packages/3f2fb354ddd582d5e4fc68d319287a29e647424f/web/favicon.ico -------------------------------------------------------------------------------- /web/fonts: -------------------------------------------------------------------------------- 1 | ../vendor/fortawesome/font-awesome/fonts -------------------------------------------------------------------------------- /web/images: -------------------------------------------------------------------------------- 1 | ../vendor/datatables/datatables/media/images -------------------------------------------------------------------------------- /web/img/debut_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terramar-labs/packages/3f2fb354ddd582d5e4fc68d319287a29e647424f/web/img/debut_light.png -------------------------------------------------------------------------------- /web/index.php: -------------------------------------------------------------------------------- 1 | run(); 14 | -------------------------------------------------------------------------------- /web/index_dev.php: -------------------------------------------------------------------------------- 1 | run(); 25 | -------------------------------------------------------------------------------- /web/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | ../../vendor/twbs/bootstrap/dist/js/bootstrap.min.js -------------------------------------------------------------------------------- /web/js/jquery.dataTables.min.js: -------------------------------------------------------------------------------- 1 | ../../vendor/datatables/datatables/media/js/jquery.dataTables.min.js -------------------------------------------------------------------------------- /web/js/jquery.min.js: -------------------------------------------------------------------------------- 1 | ../../vendor/components/jquery/jquery.min.js -------------------------------------------------------------------------------- /web/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | --------------------------------------------------------------------------------