/// <summary> /// Executes this action. /// </summary> /// <param name="pkgmgr">package manager instance</param> public void Execute(IPackageManager pkgmgr) { MergeWorker mw = new MergeWorker(pkgmgr); AbstractTree tree = LocalRepository.Read(); List<IDistribution> mergeset = new List<IDistribution>(); List<Atom> atomset = new List<Atom>(); _numpkgs = 0; _dloadsz = 0; _hardmask = new List<Atom>(); _kwmask = new List<Tuple<Atom, string[]>>(); try { /* expand world */ if (_atomlst.Contains("world")) { atomset.AddRange(pkgmgr.WorldSet); _atomlst.Remove("world"); } atomset.AddRange(Atom.ParseAll(_atomlst.ToArray())); foreach (Atom atom in atomset) { /* first find all installed packages matching the given atom */ Atom[] instarr = pkgmgr.FindPackages(atom).ToArray(); /* then find unique installed packages, and slotted packages with the highest version number */ Atom[] latestinst = instarr .Where(i => instarr.Where(n => n.PackageName == i.PackageName).Count() == 1 || instarr.Where(n => n.PackageName == i.PackageName) .Max(n => n.Version.ToString()) == i.Version.ToString()) .ToArray(); if (latestinst.Length > 1) throw new AmbiguousMatchException(atom.ToString()); try { /* if we're not updating, no version or slot was specified, and there's a version * already installed then select the installed version */ IDistribution dist = (!_options.update && !atom.HasVersion && atom.Slot == 0 && latestinst.Length > 0) ? tree.Lookup(latestinst[0]) : tree.Lookup(atom); mergeset.Add(dist); } catch (PackageNotFoundException ex) { /* we can ignore this exception if we're updating */ if (!_options.update) throw ex; } } } catch (AmbiguousMatchException ex) { SearchAction sa = new SearchAction(ex.Atom); sa.Options = new Options() { exact = true }; sa.Execute(pkgmgr); throw ex; } MergeOptions mopts = 0; if (_options.pretend) mopts |= MergeOptions.Pretend; if (_options.oneshot) mopts |= MergeOptions.OneShot; if (_options.noreplace || _options.update) mopts |= MergeOptions.NoReplace; if (_options.emptytree) mopts |= MergeOptions.EmptyTree; if (_options.fetchonly) mopts |= MergeOptions.FetchOnly; if (_options.deep) mopts |= MergeOptions.Deep; try { if (mopts.HasFlag(MergeOptions.Pretend)) { mw.OnPretendMerge += this.MergeWorker_OnPretendMerge; Console.WriteLine("\nThese are the packages that would be merged, in order:\n"); } else { mw.OnRealMerge += this.MergeWorker_OnRealMerge; mw.OnParallelFetch += this.MergeWorker_OnParallelFetch; mw.OnInstall += this.MergeWorker_OnInstall; mw.OnAutoClean += this.MergeWorker_OnAutoClean; Security.DemandNTAdmin(); } mw.Merge(mergeset.ToArray(), mopts); if (mopts.HasFlag(MergeOptions.Pretend)) { if (_repolst.Count > 0) { Console.WriteLine("\nRepositories:"); for (int i = 0; i < _repolst.Count; i++) { Console.ForegroundColor = ConsoleColor.Cyan; Console.Write(" [{0}] ", i); Console.ResetColor(); Console.Write("{0}\n", _repolst[i]); } Console.Write("\n"); } StringBuilder sb = new StringBuilder(11); Win32.StrFormatByteSize(_dloadsz, sb, sb.Capacity); Console.WriteLine( "Total: {0} package(s), Size of download(s): {1}", _numpkgs, sb.ToString()); if (_hardmask.Count > 0) { Console.Write("\nThe following packages must be "); Console.ForegroundColor = ConsoleColor.Red; Console.Write("unmasked"); Console.ResetColor(); Console.WriteLine(" before continuing:"); Console.ForegroundColor = ConsoleColor.Green; foreach (Atom a in _hardmask) Console.WriteLine("={0}", a.ToString()); Console.ResetColor(); } if (_kwmask.Count > 0) { Console.Write("\nThe following "); Console.ForegroundColor = ConsoleColor.Red; Console.Write("keyword changes"); Console.ResetColor(); Console.WriteLine(" are necessary to proceed:"); Console.ForegroundColor = ConsoleColor.Green; foreach (var t in _kwmask) Console.WriteLine("={0} {1}", t.Item1.ToString(), String.Join(" ", t.Item2)); Console.ResetColor(); } } else Console.Write("\n"); } catch (MaskedPackageException ex) { Program.error_msg("\n!!! All packages that could satisfy '{0}' have been masked.", ex.Package); } catch (SlotConflictException ex) { Console.Write("\n"); foreach (DependencyGraph.Conflict c in ex.Conflicts) { Console.WriteLine(Atom.FormatPackageVersion(c.Package.FullName, c.Slot)); foreach (IDistribution dist in c.Distributions) { string[] pulledinby = c.ReverseMap[dist] .Select(i => i.ToString()) .ToArray(); Console.WriteLine( " {0} (pulled in by: {1})", dist.ToString(), String.Join(", ", pulledinby)); } Console.Write("\n"); } throw ex; } }
/// <summary> /// Executes this action. /// </summary> /// <param name="pkgmgr">package manager instance</param> public void Execute(IPackageManager pkgmgr) { Security.DemandNTAdmin(); List<Atom> atomlst = Atom.ParseAll(_atomlst.ToArray()).ToList(); List<Atom> allselected = new List<Atom>(); List<Atom> allprotected = new List<Atom>(); List<Atom> allomitted = new List<Atom>(); foreach (Atom atom in atomlst) { Atom[] instatoms = pkgmgr.FindPackages(atom); if (instatoms.Length == 0) throw new PackageNotFoundException(atom.ToString()); allselected.AddRange(instatoms); } allprotected = allselected .Where(i => pkgmgr.IsProtected(i)) .ToList(); foreach (Atom a in allprotected) allselected.Remove(a); allomitted = pkgmgr.GetInstalledPackages() .Where(i => allselected.Where( s => s.PackageName == i.PackageName).Count() > 0) .Where(i => allselected.Where( s => s.PackageName == i.PackageName && s.Version == i.Version).Count() == 0) .ToList(); string[] allpackages = allselected .Select(i => i.PackageName) .Union(allprotected.Select(i => i.PackageName)) .Union(allomitted.Select(i => i.PackageName)) .OrderBy(i => i) .ToArray(); foreach (string pkg in allpackages) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("\n {0}", pkg); Console.ResetColor(); string[] pkgselected = allselected .Where(i => i.PackageName == pkg) .OrderBy(i => i.Version) .Select(i => i.Version.ToString()) .ToArray(); string[] pkgprotected = allprotected .Where(i => i.PackageName == pkg) .OrderBy(i => i.Version) .Select(i => i.Version.ToString()) .ToArray(); string[] pkgomitted = allomitted .Where(i => i.PackageName == pkg) .OrderBy(i => i.Version) .Select(i => i.Version.ToString()) .ToArray(); Console.Write(" selected: "); if (pkgselected.Length > 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(String.Join(" ", pkgselected)); Console.ResetColor(); } else Console.WriteLine("none"); Console.Write(" protected: "); if (pkgprotected.Length > 0) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(String.Join(" ", pkgprotected)); Console.ResetColor(); } else Console.WriteLine("none"); Console.Write(" omitted: "); if (pkgomitted.Length > 0) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(String.Join(" ", pkgomitted)); Console.ResetColor(); } else Console.WriteLine("none"); } Console.WriteLine( "\nAll selected packages: {0}", String.Join(" ", allselected.Select(i => i.ToString()))); Console.Write("\n>>> "); Console.ForegroundColor = ConsoleColor.Red; Console.Write("Selected"); Console.ResetColor(); Console.WriteLine(" packages are scheduled for removal."); Console.Write(">>> "); Console.ForegroundColor = ConsoleColor.Green; Console.Write("Protected"); Console.ResetColor(); Console.Write(" and "); Console.ForegroundColor = ConsoleColor.Green; Console.Write("omitted"); Console.ResetColor(); Console.WriteLine(" packages will not be removed."); if (_options.pretend || allselected.Count == 0) return; Console.WriteLine( "\n>>> Waiting {0} {1} before starting...", _delay, _delay == 1 ? "second" : "seconds"); Console.WriteLine(">>> Press Control-C to abort"); Console.Write(">>> Unmerging in "); for (uint i = _delay; i > 0; i--) { Console.ForegroundColor = ConsoleColor.Red; Console.Write("{0} ", i); Console.ResetColor(); Console.Beep(); System.Threading.Thread.Sleep(1000); } Console.Write("\n"); MergeWorker mw = new MergeWorker(pkgmgr); mw.OnUnmerge += this.MergeWorker_OnUnmerge; mw.Unmerge(allselected.ToArray()); }