/** * Loads a package from a given directory. * * This function returns the string of the primary package class. * * @throws InvalidPathException Thrown when the package directory * does not exist. * @throws NewUpException * @param $directory * @return string */ public function loadPackage($directory) { if (!$this->files->exists($directory)) { throw new InvalidPathException("The directory {$directory} does not exist."); } if (!$this->files->exists($directory . '/composer.json')) { throw new InvalidPathException("There is no composer.json file in {$directory}"); } if (!$this->files->exists($directory . '/_newup')) { throw new InvalidPathException("There is no _newup directory in {$directory}"); } if (!$this->files->exists($directory . '/_newup/Package.php')) { throw new InvalidPathException("A Package.php file must be present in in \"_newup\" directory."); } $package = Package::fromFile($directory . '/composer.json', user_config('configuration.strictComposerValues', true)); $namespace = package_vendor_namespace($package->getVendor(), $package->getPackage(), true); add_psr4($namespace, $directory . '/_newup'); if (!class_exists($namespace . 'Package', true)) { throw new NewUpException("A valid reachable class named 'Package' must be defined."); } if (!is_subclass_of($namespace . 'Package', BasePackageTemplate::class)) { throw new NewUpException("The 'Package' class must extend " . BasePackageTemplate::class); } return $namespace . 'Package'; }
/** * Initializes a package template in the provided directory. * * @throws InvalidPathException * * @param $vendor * @param $package * @param $directory */ public function initialize($vendor, $package, $directory) { if (!$this->files->exists($directory) || !$this->files->isDirectory($directory)) { throw new InvalidPathException("{$directory} does not exist or is not a valid directory."); } $packageComposer = new Package(); $packageComposer->setVendor($vendor); $packageComposer->setPackage($package); $packageComposer->setDescription('Give your package template a good description'); $packageComposer->setLicense(user_config('configuration.license', '')); $packageComposer->setAuthors(user_config('configuration.authors', [])); $writer = new ConfigurationWriter($packageComposer->toArray()); $writer['config'] = (object) ['vendor-dir' => '_newup_vendor']; $writer->save($directory . '/composer.json'); $this->renderer->setData('package', $package); $this->renderer->setData('vendor', $vendor); $packageClass = $this->renderer->render('template'); if (!$this->files->exists($directory . '/_newup/')) { $this->files->makeDirectory($directory . '/_newup/'); } if ($this->shouldCreateTemplateDirectory && $this->files->exists($directory . '/_template') == false) { $this->files->makeDirectory($directory . '/_template'); } $this->files->put($directory . '/_newup/Package.php', $packageClass); }
/** * Gets the vendor directory location if it exists. * * Returns false if the vendor directory does not exist. * * @param $directory * @return bool|string */ private function findVendor($directory) { $vendorDirectory = $this->normalizePath($directory . '/_newup_vendor'); if ($this->files->exists($vendorDirectory) && $this->files->isDirectory($vendorDirectory)) { return $vendorDirectory; } return false; }
/** * Returns the common template directory. * * @return null|string */ private function getCommonTemplateDirectory() { $commonDirectory = realpath($this->templateDirectory . '/_newup/common'); if ($this->files->exists($commonDirectory) && $this->files->isDirectory($commonDirectory)) { return $commonDirectory; } return null; }
/** * Creates the file tree in the given directory. * * @param $destinationDirectory * @return array */ public function generate($destinationDirectory) { $destinationDirectory = $destinationDirectory; $generatedPaths = []; $this->resolveAutomaticallyIgnoredPaths($destinationDirectory); foreach ($this->getPaths() as $pathKey => $path) { $fullPath = $destinationDirectory . DIRECTORY_SEPARATOR . $path['path']; if (!$this->shouldBeIgnored($path['path'])) { if ($path['type'] == 'dir') { $this->fileSystem->makeDirectory($fullPath, 0755, true, true); } else { // There are two steps here: // 1st: Recursively create the directory structure for the file (it might not exist) // 2nd: Create an empty file using `touch()` since we are guaranteed the directory structure exists. $this->fileSystem->makeDirectory(dirname($fullPath), 0755, true, true); touch($fullPath); } $generatedPaths[$pathKey] = $path + ['full' => $fullPath]; } } $this->removeFilesAndDirectories($destinationDirectory); return $generatedPaths; }
/** * Execute the console command. * * @return mixed */ public function handle() { if (!$this->confirm("Are you sure you want to run the analysis tool? This tool will make modifications to the template storage." . PHP_EOL . "While it is intended to clean up the template storage, it could potentially fail. [yes|no]", false)) { $this->comment('Analysis aborted by user'); return; } $this->info('Starting analysis of template store...'); $this->line('Store located at ' . $this->templateStorageEngine->getStoragePath()); $vendors = $this->templateStorageEngine->getInstalledVendors(); $packages = $this->templateStorageEngine->getInstalledPackages(true); $packageCount = 0; foreach ($packages as $package) { $packageCount += count($package['packages']); } $this->line('Found ' . count($vendors) . ' vendors and ' . $packageCount . ' packages...'); $this->comment(PHP_EOL . 'Searching for failed update processes...'); $failedUpdateProcesses = []; $garbagePackageDirectories = []; foreach ($packages as $vp) { foreach ($vp['packages'] as $package) { if (Str::endsWith($package['path'], '_{updating_in_progress}')) { $garbagePackageDirectories[] = $package; $this->line('Identified package as possible garbage ' . $package['path']); } else { if ($this->files->exists($package['path'] . DIRECTORY_SEPARATOR . '_newup_update_initiated')) { $failedUpdateProcesses[] = $package; $this->line('Identified failed package update process ' . $package['path']); } } } } $this->line('Found ' . count($failedUpdateProcesses) . ' failed update processes'); $this->line('Found ' . count($garbagePackageDirectories) . ' update directories ready for cleanup'); $this->comment(PHP_EOL . 'Analyzing search results...'); $recoverablePackages = []; $nonRecoverablePackages = []; foreach ($failedUpdateProcesses as $failedUpdate) { if ($this->files->exists($failedUpdate['path'] . '_{updating_in_progress}')) { $this->line('Identified package as recoverable ' . $failedUpdate['path']); $recoverablePackages[] = $failedUpdate; } else { $this->line('Identified a non-recoverable package ' . $failedUpdate['path']); $nonRecoverablePackages[] = $failedUpdate; } } $this->line('Found ' . count($recoverablePackages) . ' recoverable failed update processes'); $this->line('Found ' . count($nonRecoverablePackages) . ' non-recoverable failed update processes'); $this->comment(PHP_EOL . 'Cleaning up non-recoverable update processes...'); if (count($nonRecoverablePackages) > 0) { foreach ($nonRecoverablePackages as $nonRecoverablePackage) { $this->files->deleteDirectory($nonRecoverablePackage['path'], false); $this->line('Cleaning up directory ' . $nonRecoverablePackage['path']); } } else { $this->line('Nothing to clean up'); } $this->comment(PHP_EOL . 'Cleaning up failed update processes...'); if (count($garbagePackageDirectories) > 0) { foreach ($garbagePackageDirectories as $garbage) { $originalPackagePath = $garbage['path']; $originalPackagePath = str_replace('_{updating_in_progress}', '', $originalPackagePath); if ($this->files->exists($originalPackagePath)) { if ($this->files->exists($originalPackagePath . DIRECTORY_SEPARATOR . '_newup_update_initiated')) { $this->comment('Recovering failed update process for ' . $originalPackagePath); $this->line('Removing failed update files at ' . $originalPackagePath); $this->files->deleteDirectory($originalPackagePath); $this->line('Recovering files...'); $this->files->copyDirectory($garbage['path'], $originalPackagePath); if ($this->files->exists($originalPackagePath)) { $this->info('Recovered files at ' . $originalPackagePath); } else { $this->error('Could not recover files at ' . $originalPackagePath); } $this->line('Cleaning up garbage files at ' . $garbage['path']); $this->files->deleteDirectory($garbage['path']); } else { // Original package path does not exist, remove trash. $this->line('Removing garbage ' . $garbage['path'] . ' because ' . $originalPackagePath . ' no longer exists'); $this->files->deleteDirectory($garbage['path']); } } else { // Original package path does not exist, remove trash. $this->line('Removing garbage ' . $garbage['path'] . ' because ' . $originalPackagePath . ' no longer exists'); $this->files->deleteDirectory($garbage['path']); } } } else { $this->line('Nothing to clean up'); } $this->comment(PHP_EOL . 'Analysis complete'); }
/** * Resets the storage engine. * * @return mixed */ public function reset() { foreach ($this->getInstalledVendors() as $vendor) { $this->files->deleteDirectory($vendor['directory']); } }