/**
  * Removes a given module version
  *
  * @param  io.Folder $cwd The working directory
  * @param  io.collections.FileCollection $version The version
  * @return bool whether the module was active
  */
 protected function remove($cwd, FileCollection $version)
 {
     $versioned = basename($version->getURI());
     $vendor = basename($version->getOrigin()->getURI());
     Console::writeLine('Removing ', $vendor, '/', $versioned, ' -> ', $version);
     // Remove corresponding .pth file
     $pth = new File($cwd, '.' . $vendor . '.' . $versioned . '.pth');
     if ($pth->exists()) {
         $active = true;
         $pth->unlink();
     } else {
         $active = false;
     }
     // Remove folder
     $fld = new Folder($version->getURI());
     $fld->unlink();
     return $active;
 }
 /**
  * Execute this action
  *
  * @param  string[] $args command line args
  * @return int exit code
  */
 public function perform($args)
 {
     $cwd = new FileCollection('.');
     $isModule = new ExtensionEqualsFilter('.json');
     // If an argument is given, search only that vendor
     if (isset($args[0])) {
         $find = $cwd->getCollection($args[0]);
     } else {
         $find = $cwd;
     }
     $total = 0;
     Console::writeLine('@', $cwd->getURI());
     foreach (new FilteredIOCollectionIterator($find, $isModule, true) as $module) {
         $result = self::$json->decodeFrom($module->getInputStream());
         Console::writeLine(new Module($result['vendor'], $result['module']), ': ', $result['info']);
         $total++;
     }
     Console::writeLine();
     Console::writeLine($total, ' module(s) installed');
     return 0;
 }
 /**
  * Execute this action
  *
  * @param  string[] $args command line args
  * @return int exit code
  */
 public function perform($args)
 {
     $cwd = new FileCollection('.');
     // Parse args
     $i = 1;
     if ('-r' === $args[0]) {
         $remote = true;
         array_shift($args);
         $i++;
     } else {
         if ('-i' === $args[0]) {
             $remote = false;
             array_shift($args);
             $i++;
             $installed = new File($args[0] . '.json');
         } else {
             $installed = new File($args[0] . '.json');
             $remote = !$installed->exists();
         }
     }
     if (empty($args)) {
         Console::$err->writeLine('*** Missing argument #', $i, ': Module name');
         return 2;
     }
     sscanf(rtrim($args[0], '/'), '%[^@]@%s', $name, $version);
     $module = Module::valueOf($name);
     // Search for module
     if ($remote) {
         Console::writeLine('@', $this->api->getBase()->getURL());
         $request = create(new RestRequest('/vendors/{vendor}/modules/{module}'))->withSegment('vendor', $module->vendor)->withSegment('module', $module->name);
         try {
             $result = $this->api->execute($request)->data();
         } catch (RestException $e) {
             Console::$err->writeLine('*** Cannot find remote module ', $module, ': ', $e->getMessage());
             return 3;
         }
         $releases = $result['releases'];
     } else {
         Console::writeLine('@', $cwd->getURI());
         try {
             $result = self::$json->decodeFrom($installed->getInputStream());
         } catch (IOException $e) {
             Console::$err->writeLine('*** Cannot find installed module ', $module, ': ', $e->getMessage());
             return 3;
         }
         $releases = $this->installedReleases($cwd, $module);
     }
     Console::writeLine(new Module($result['vendor'], $result['module']), ': ', $result['info']);
     Console::writeLine($result['link']['url']);
     uksort($releases, function ($a, $b) {
         return version_compare($a, $b, '<');
     });
     Console::writeLine('Releases: ', sizeof($releases), ', list {');
     foreach ($releases as $version => $release) {
         $s = '';
         foreach ($release as $key => $value) {
             $s .= ', ' . $key . '= ' . \xp::stringOf($value);
         }
         Console::writeLine('  ', $version, ' (', substr($s, 2), ')');
     }
     Console::writeLine('}');
     // List active releases for local queries
     if (!$remote) {
         foreach (new FilteredIOCollectionIterator($cwd, new NameMatchesFilter('#^\\.' . $module->vendor . '\\.' . $module->name . '.*\\.pth#')) as $found) {
             $r = new StringReader($found->getInputStream());
             Console::writeLine('Selected: ', basename($found->getURI()), ', class path {');
             while (null !== ($line = $r->readLine())) {
                 $resolved = realpath($cwd->getURI() . ltrim($line, '!'));
                 if (is_dir($resolved)) {
                     $cl = \lang\FileSystemClassLoader::instanceFor($resolved, false);
                 } else {
                     if (is_file($resolved)) {
                         $cl = \lang\archive\ArchiveClassLoader::instanceFor($resolved, false);
                     }
                 }
                 Console::writeLine('  ', $cl);
             }
             Console::writeLine('}');
         }
         return 0;
     }
 }