private bool InstallCommands(string packageId, string appPath) { string commandsFolder = Path.Combine(appPath, InstallBuilder.CommandsFolderName); IEnumerable <string> allAppCommandsFiles; if (RuntimeEnvironmentHelper.IsWindows) { allAppCommandsFiles = Directory.EnumerateFiles(commandsFolder, "*.cmd"); } else { // We have cmd files and project.*.json files in the same folder allAppCommandsFiles = Directory.EnumerateFiles(commandsFolder, "*.*") .Where(cmd => !cmd.EndsWith(".cmd") && !cmd.EndsWith(".json")) .ToList(); } var allAppCommands = allAppCommandsFiles .Select(cmd => Path.GetFileNameWithoutExtension(cmd)) .ToList(); IEnumerable <string> conflictingCommands; if (OverwriteCommands) { conflictingCommands = new string[0]; } else { // Conflicting commands are only the commands not owned by this application conflictingCommands = allAppCommands.Where(appCmd => { var commandOwner = _commandsRepository.FindCommandOwner(appCmd); return(commandOwner != null && !packageId.Equals(commandOwner.Id, StringComparison.OrdinalIgnoreCase)); }); } if (conflictingCommands.Any()) { WriteError(string.Format( "The application commands cannot be installed because the following commands already exist: {0}. No changes were made. Rerun the command with the --overwrite switch to replace the existing commands.", string.Join(", ", conflictingCommands))); return(false); } var installPath = Path.GetFullPath(_commandsRepository.Root.Root); foreach (string commandFileFullPath in allAppCommandsFiles) { string commandFileName = RuntimeEnvironmentHelper.IsWindows ? Path.GetFileName(commandFileFullPath) : Path.GetFileNameWithoutExtension(commandFileFullPath); string commandScript; if (RuntimeEnvironmentHelper.IsWindows) { commandScript = string.Format( "@\"%~dp0{0}\" %*", commandFileFullPath.Substring(installPath.Length)); } else { commandScript = string.Format( "\"$(dirname $0){0}\" $@", commandFileFullPath.Substring(installPath.Length)); } string scriptFilePath = Path.Combine(installPath, commandFileName); File.WriteAllText(scriptFilePath, commandScript); if (!RuntimeEnvironmentHelper.IsWindows) { FileOperationUtils.MarkExecutable(commandFileFullPath); FileOperationUtils.MarkExecutable(scriptFilePath); } } var installedCommands = allAppCommandsFiles.Select(cmd => Path.GetFileNameWithoutExtension(cmd)); WriteInfo("The following commands were installed: " + string.Join(", ", installedCommands)); return(true); }
private void PurgeOrphanPackages() { _reports.Verbose.WriteLine("Removing orphaned packages..."); // Find the packages still used by the command scripts var applicationPackagesStillUsed = _commandsRepo.Commands .Select(cmd => _commandsRepo.FindCommandOwner(cmd)) .Distinct(); // Get all the installed packages var packagesRepo = new PackageRepository( _commandsRepo.PackagesRoot, caseSensitivePackagesName: false); // Key = package<id, version>, Value = bool (true if used, false otherwise) var usedPackages = packagesRepo .GetAllPackages() .SelectMany(pack => pack.Value) .ToDictionary( pack => pack, _ => false); var lockFileFormat = new LockFileFormat(); // Mark all the packages still in used by using the dependencies in the lock file foreach (var applicationPackage in applicationPackagesStillUsed) { var appLockFileFullPath = Path.Combine( _commandsRepo.PackagesRoot.Root, _commandsRepo.PathResolver.GetPackageDirectory(applicationPackage.Id, applicationPackage.Version), InstallBuilder.CommandsFolderName, LockFileFormat.LockFileName); if (!File.Exists(appLockFileFullPath)) { _reports.Verbose.WriteLine("Lock file {0} not found. This package will be removed if it is not used by another application", appLockFileFullPath); // The lock file is missing, probably the app is not installed correctly // unless someone else is using it, we'll remove it continue; } var lockFile = lockFileFormat.Read(appLockFileFullPath); foreach (var dependency in lockFile.Libraries) { var dependencyPackage = new NuGet.PackageInfo( _commandsRepo.PackagesRoot, dependency.Name, dependency.Version, null, null); if (usedPackages.ContainsKey(dependencyPackage)) { // Mark the dependency as used usedPackages[dependencyPackage] = true; } } } // Now it's time to remove those unused packages var unusedPackages = usedPackages .Where(pack => !pack.Value) .Select(pack => pack.Key); foreach (var package in unusedPackages) { packagesRepo.RemovePackage(package); _reports.Verbose.WriteLine("Removed orphaned package: {0} {1}", package.Id, package.Version); } }