1<?php 2/* 3 * Copyright 2020 Google LLC 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 * use this file except in compliance with the License. You may obtain a copy of 7 * the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 * License for the specific language governing permissions and limitations under 15 * the License. 16 */ 17 18namespace Google\Task; 19 20use Composer\Script\Event; 21use Symfony\Component\Filesystem\Filesystem; 22use Symfony\Component\Finder\Finder; 23use InvalidArgumentException; 24 25class Composer 26{ 27 /** 28 * @param Event $event Composer event passed in for any script method 29 * @param Filesystem $filesystem Optional. Used for testing. 30 */ 31 public static function cleanup( 32 Event $event, 33 Filesystem $filesystem = null 34 ) { 35 $composer = $event->getComposer(); 36 $extra = $composer->getPackage()->getExtra(); 37 $servicesToKeep = isset($extra['google/apiclient-services']) ? 38 $extra['google/apiclient-services'] : []; 39 if ($servicesToKeep) { 40 $vendorDir = $composer->getConfig()->get('vendor-dir'); 41 $serviceDir = sprintf( 42 '%s/google/apiclient-services/src/Google/Service', 43 $vendorDir 44 ); 45 if (!is_dir($serviceDir)) { 46 // path for google/apiclient-services >= 0.200.0 47 $serviceDir = sprintf( 48 '%s/google/apiclient-services/src', 49 $vendorDir 50 ); 51 } 52 self::verifyServicesToKeep($serviceDir, $servicesToKeep); 53 $finder = self::getServicesToRemove($serviceDir, $servicesToKeep); 54 $filesystem = $filesystem ?: new Filesystem(); 55 if (0 !== $count = count($finder)) { 56 $event->getIO()->write( 57 sprintf( 58 'Removing %s google services', 59 $count 60 ) 61 ); 62 foreach ($finder as $file) { 63 $realpath = $file->getRealPath(); 64 $filesystem->remove($realpath); 65 $filesystem->remove($realpath . '.php'); 66 } 67 } 68 } 69 } 70 71 /** 72 * @throws InvalidArgumentException when the service doesn't exist 73 */ 74 private static function verifyServicesToKeep( 75 $serviceDir, 76 array $servicesToKeep 77 ) { 78 $finder = (new Finder()) 79 ->directories() 80 ->depth('== 0'); 81 82 foreach ($servicesToKeep as $service) { 83 if (!preg_match('/^[a-zA-Z0-9]*$/', $service)) { 84 throw new InvalidArgumentException( 85 sprintf( 86 'Invalid Google service name "%s"', 87 $service 88 ) 89 ); 90 } 91 try { 92 $finder->in($serviceDir . '/' . $service); 93 } catch (InvalidArgumentException $e) { 94 throw new InvalidArgumentException( 95 sprintf( 96 'Google service "%s" does not exist or was removed previously', 97 $service 98 ) 99 ); 100 } 101 } 102 } 103 104 private static function getServicesToRemove( 105 $serviceDir, 106 array $servicesToKeep 107 ) { 108 // find all files in the current directory 109 return (new Finder()) 110 ->directories() 111 ->depth('== 0') 112 ->in($serviceDir) 113 ->exclude($servicesToKeep); 114 } 115} 116