/// <summary> /// The (non-static) startup method /// </summary> /// <param name="args">The command line arguments.</param> /// <returns>Process return code.</returns> /// <remarks></remarks> protected override int Main(IEnumerable<string> args) { _messages = new PackageManagerMessages { UnexpectedFailure = UnexpectedFailure, NoPackagesFound = NoPackagesFound, PermissionRequired = OperationRequiresPermission, Error = MessageArgumentError, RequireRemoteFile = (canonicalName, remoteLocations, localFolder, force ) => Downloader.GetRemoteFile(canonicalName, remoteLocations, localFolder, force, new RemoteFileMessages { Progress = (itemUri, percent) => { "Downloading {0}".format(itemUri.AbsoluteUri).PrintProgressBar(percent); }, Completed = (itemUri) => { Console.WriteLine(); } } ,_messages), OperationCancelled = CancellationRequested, PackageSatisfiedBy = (original, satisfiedBy) => { original.SatisfiedBy = satisfiedBy; }, PackageBlocked = BlockedPackage, UnknownPackage = UnknownPackage, }; try { #region command line parsing var options = args.Where(each => each.StartsWith("--")).Switches(); var parameters = args.Where(each => !each.StartsWith("--")).Parameters(); foreach (var arg in options.Keys) { var argumentParameters = options[arg]; var last = argumentParameters.LastOrDefault(); var lastAsBool = string.IsNullOrEmpty(last) || last.IsTrue(); switch (arg) { /* options */ case "min-version": _minVersion = last.VersionStringToUInt64(); break; case "max-version": _maxVersion = last.VersionStringToUInt64(); break; case "installed": _installed = lastAsBool; break; case "active": _active = lastAsBool; break; case "required": _required = lastAsBool; break; case "blocked": _blocked = lastAsBool; break; case "latest": _latest = lastAsBool; break; case "force": _force = lastAsBool; break; case "force-scan": _forceScan = lastAsBool; break; case "download": _download = lastAsBool; break; case "pretend": _pretend= lastAsBool; break; case "auto-upgrade": _autoUpgrade = lastAsBool; break; case "use-feed": _location = last; break; case "pause": _pause = lastAsBool; break; case "verbose": _verbose = lastAsBool; Logger.Errors = true; Logger.Messages = true; Logger.Warnings = true; break; case "dependencies": case "deps": _dependencies = lastAsBool; break; /* global switches */ case "load-config": // all ready done, but don't get too picky. break; case "nologo": this.Assembly().SetLogo(string.Empty); break; case "terse": this.Assembly().SetLogo(string.Empty); _terse = true; _verbose = false; break; case "help": return Help(); default: throw new ConsoleException(Resources.UnknownParameter, arg); } } Logo(); if (parameters.Count() < 1) { throw new ConsoleException(Resources.MissingCommand); } #endregion Task task = null; var command = parameters.FirstOrDefault(); parameters = parameters.Skip(1); if (ConsoleExtensions.InputRedirected) { // grab the contents of the input stream and use that as parameters var lines = Console.In.ReadToEnd().Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(each => each.Split(new[] { '#' }, StringSplitOptions.RemoveEmptyEntries)[0]).Select(each => each.Trim()); parameters = parameters.Union(lines.Where(each => !each.StartsWith("#"))).ToArray(); } if (ConsoleExtensions.OutputRedirected) { this.Assembly().SetLogo(string.Empty); _terse = true; _verbose = false; } if (command.IsNullOrEmpty()) { return Help(); } Verbose("# Connecting to Service..."); _pm.ConnectAndWait("coapp-cli-client", null, 5000); Verbose("# Connected to Service..."); if( _verbose) { _pm.SetLogging(true, true, true); } if (command.EndsWith(".msi") && File.Exists(command) && parameters.IsNullOrEmpty()) { // assume install if the only thing given is a filename. task = _pm.GetPackages(command, _minVersion, _maxVersion, _dependencies , _installed, _active, _required, _blocked, _latest, _location, _forceScan, messages: _messages). ContinueWith(antecedent => Install(antecedent.Result)); return 0; } if (!command.StartsWith("-")) { command = command.ToLower(); } switch (command) { #if FALSE case "download": var remoteFileUri = new Uri(parameters.First()); // create the remote file reference var remoteFile = new RemoteFile(remoteFileUri, CancellationTokenSource.Token); var previewTask = remoteFile.Preview(); previewTask.Wait(); // Tell it to download it var getTask = remoteFile.Get(); // monitor the progress. remoteFile.DownloadProgress.Notification += progress => { // this executes when the download progress value changes. Console.Write(progress <= 100 ? "..{0}% " : "bytes: [{0}]", progress); }; // when it's done, do this: getTask.ContinueWith(t => { // this executes when the Get() operation completes. Console.WriteLine("File {0} has finished downloading", remoteFile.LocalFullPath); },TaskContinuationOptions.AttachedToParent); break; case "verify-package": var r = Verifier.HasValidSignature(parameters.First()); Console.WriteLine("Has Valid Signature: {0}", r); Console.WriteLine("Name: {0}", Verifier.GetPublisherInformation(parameters.First())["PublisherName"]); break; #endif case "-?": return Help(); case "-l": case "list": case "list-package": case "list-packages": task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, _installed, _active, _required, _blocked, _latest, _location,_forceScan, messages: _messages).ContinueWith(antecedent => ListPackages(antecedent.Result)); break; case "-i": case "install": case "install-package": case "install-packages": if (parameters.Count() < 1) { throw new ConsoleException(Resources.InstallRequiresPackageName); } // if you haven't specified this, we're gonna assume that you want the latest version // this is overridden if the user specifies a version tho' if( _latest == null ) { _latest = true; } task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, _installed, _active, _required, _blocked, _latest, _location, _forceScan, messages: _messages). ContinueWith(antecedent => Install(antecedent.Result)); break; case "-r": case "remove": case "uninstall": case "remove-package": case "remove-packages": case "uninstall-package": case "uninstall-packages": if (parameters.Count() < 1) { throw new ConsoleException(Resources.RemoveRequiresPackageName); } task = _pm.GetPackages(parameters, _minVersion, _maxVersion,_dependencies, true, _active, _required, _blocked, _latest,_location,_forceScan, messages: _messages). ContinueWith(antecedent => Remove(antecedent.Result)); break; case "-L": case "feed": case "feeds": case "list-feed": case "list-feeds": task = ListFeeds(); break; case "-u": case "upgrade": case "upgrade-package": case "upgrade-packages": case "update": case "update-package": case "update-packages": if (parameters.Count() != 1) { throw new ConsoleException(Resources.MissingParameterForUpgrade); } // if they didn't say to rescan (one way or the other), we're defaulting to yeah, // because we really should force a rescan if we're updating if( _forceScan == null ) { _forceScan = true; } // should get all packages that are installed (using criteria), // and then see if each one of those can be upgraded. task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, true, _active, _required, false, _latest ,_location,_forceScan, messages: _messages). ContinueWith(antecedent => Upgrade(antecedent.Result)); break; case "-A": case "add-feed": case "add-feeds": case "add": if (parameters.Count() < 1) { throw new ConsoleException(Resources.AddFeedRequiresLocation); } task = AddFeed(parameters); break; case "-R": case "remove-feed": case "remove-feeds": if (parameters.Count() < 1) { throw new ConsoleException(Resources.DeleteFeedRequiresLocation); } task = DeleteFeed(parameters); break; case "-t": case "trim-packages": case "trim-package": case "trim": if (parameters.Count() != 0) { throw new ConsoleException(Resources.TrimErrorMessage); } task = _pm.GetPackages("*", _minVersion, _maxVersion, _dependencies, true, false, false, _blocked, _latest, _location, _forceScan, messages: _messages).ContinueWith(antecedent => Remove(antecedent.Result)); break; case "-a": case "activate": case "activate-package": case "activate-packages": task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, true, _active, _required, _blocked, _latest, _location,_forceScan, messages: _messages). ContinueWith(antecedent => Activate(antecedent.Result)); break; case "-g": case "get-packageinfo": case "info": task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, _installed, _active, _required, _blocked, _latest, _location,_forceScan, messages: _messages).ContinueWith(antecedent => GetPackageInfo(antecedent.Result)); break; case "-b": case "block-packages": case "block-package": case "block": task =_pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, true, _active, _required, _blocked, _latest, _location,_forceScan, messages: _messages). ContinueWith(antecedent => Block(antecedent.Result)); break; case "-B": case "unblock-packages": case "unblock-package": case "unblock": task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, true, _active, _required, _blocked, _latest, _location,_forceScan, messages: _messages).ContinueWith(antecedent => UnBlock(antecedent.Result)); break; case "-m": case "mark-packages": case "mark-package": case "mark": task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, true, _active, _required, _blocked, _latest, _location,_forceScan, messages: _messages). ContinueWith(antecedent => Mark(antecedent.Result)); break; case "-M": case "unmark-packages": case "unmark-package": case "unmark": task = _pm.GetPackages(parameters, _minVersion, _maxVersion, _dependencies, true, _active, _required, _blocked, _latest, _location,_forceScan, messages: _messages). ContinueWith(antecedent => UnMark(antecedent.Result)); break; case "create-symlink": if (parameters.Count() != 2) { throw new ConsoleException("Create-symlink requires two parameters: existing-location and new-link"); } task = _pm.CreateSymlink(parameters.First().GetFullPath(), parameters.Last().GetFullPath(), LinkType.Symlink); break; case "create-hardlink": if (parameters.Count() != 2) { throw new ConsoleException("Create-hardlink requires two parameters: existing-location and new-link"); } task = _pm.CreateSymlink(parameters.First().GetFullPath(), parameters.Last().GetFullPath(), LinkType.Hardlink); break; case "create-shortcut": if (parameters.Count() != 2) { throw new ConsoleException("Create-shortcut requires two parameters: existing-location and new-link"); } task = _pm.CreateSymlink(parameters.First().GetFullPath(), parameters.Last().GetFullPath(), LinkType.Shortcut); break; case "-p" : case "list-policies": case "list-policy": case "policies": ListPolicies(); break; case "add-to-policy": { if (parameters.Count() != 2) { throw new ConsoleException("Add-to-policy requires at two parameters (policy name and account)"); } var policyName = parameters.First(); var account = parameters.Last(); task = _pm.AddToPolicy(policyName, account, _messages).ContinueWith(antecedent => { if( antecedent.IsFaulted ) { throw antecedent.Exception; } _pm.GetPolicy(policyName, new PackageManagerMessages { PolicyInformation = (polName, description, accounts) => { Console.WriteLine("Policy: {0} -- {1} ", polName, description); foreach (var acct in accounts) { Console.WriteLine(" {0}", acct); } } }.Extend(_messages)).Wait(); }); } break; case "remove-from-policy": { if (parameters.Count() != 2) { throw new ConsoleException("Remove-to-policy requires at two parameters (policy name and account)"); } var policyName = parameters.First(); var account = parameters.Last(); task = _pm.RemoveFromPolicy(policyName, account, _messages).ContinueWith(antecedent => { if (antecedent.IsFaulted) { throw antecedent.Exception; } _pm.GetPolicy(policyName, new PackageManagerMessages { PolicyInformation = (polName, description, accounts) => { Console.WriteLine("Policy: {0} -- {1}", polName, description); foreach (var acct in accounts) { Console.WriteLine(" {0}", acct); } } }.Extend(_messages)).Wait(); }); } break; default: throw new ConsoleException(Resources.UnknownCommand, command); } if (task != null) { task.ContinueWith(antecedent => { if (!(antecedent.IsFaulted || antecedent.IsCanceled)) { WaitForPackageManagerToComplete(); } }).Wait(); } if( _pause == true ) { Console.ReadLine(); } _pm.Disconnect(); if (_pause == true) { Console.ReadLine(); } } catch (ConsoleException failure) { Fail("{0}\r\n\r\n {1}", failure.Message, Resources.ForCommandLineHelp); CancellationTokenSource.Cancel(); _pm.Disconnect(); } return 0; }
/// <summary> /// The (non-static) startup method /// </summary> /// <param name = "args"> /// The command line arguments. /// </param> /// <returns> /// Process return code. /// </returns> protected override int Main(IEnumerable<string> args) { try { _pkgManager = new PackageManager(); bool waitforbreak = false; #region commane line parsing // default: _pkgManager.SessionFeedLocations = new[] {Environment.CurrentDirectory}; var options = args.Switches(); var parameters = args.Parameters(); foreach (var arg in options.Keys) { var argumentParameters = options[arg]; switch (arg) { /* options */ case "pretend": _pkgManager.Pretend = true; break; case "wait-for-break": waitforbreak = true; break; case "maximum": _pkgManager.MaximumPackagesToProcess = argumentParameters.Last().ToInt32(10); break; case "as-specified": _pkgManager.PackagesAsSpecified = string.IsNullOrEmpty(argumentParameters.FirstOrDefault()) ? new[] {"*"} : argumentParameters; break; case "upgrade": _pkgManager.PackagesAreUpgradable = string.IsNullOrEmpty(argumentParameters.FirstOrDefault()) ? new[] {"*"} : argumentParameters; break; case "no-scan": _pkgManager.DoNotScanLocations = string.IsNullOrEmpty(argumentParameters.FirstOrDefault()) ? new[] {"*"} : argumentParameters; break; case "no-network": _pkgManager.DoNotScanLocations = new[] {"*://*"}; break; case "scan": if (string.IsNullOrEmpty(argumentParameters.FirstOrDefault())) { throw new ConsoleException(Resources.OptionRequiresLocation.format("--scan")); } _pkgManager.SessionFeedLocations = argumentParameters; break; case "flush-cache": _pkgManager.FlushCache(); break; /* global switches */ case "load-config": // all ready done, but don't get too picky. break; case "nologo": this.Assembly().SetLogo(string.Empty); break; case "feed-output-file": _feedOutputFile = argumentParameters.LastOrDefault(); break; case "feed-root-url": _feedRootUrl = argumentParameters.LastOrDefault(); break; case "feed-actual-url": _feedActualUrl = argumentParameters.LastOrDefault(); break; case "feed-package-source": _feedPackageSource = argumentParameters.LastOrDefault(); break; case "feed-recursive": _feedRecursive = true; break; case "feed-package-url": _feedPackageUrl = argumentParameters.LastOrDefault(); break; case "feed-title": _feedTitle = argumentParameters.LastOrDefault(); break; case "help": return Help(); default: throw new ConsoleException(Resources.UnknownParameter, arg); } } Logo(); if (parameters.Count() < 1) { throw new ConsoleException(Resources.MissingCommand); } #endregion // GS01: I'm putting this in here so that feed resoltion happens before we actually get around to doing something. // Look into the necessity later. Tasklet.WaitforCurrentChildTasks(); var command = parameters.FirstOrDefault().ToLower(); parameters = parameters.Skip(1); if (File.Exists(command)) { // assume install if the only thing given is a filename. Install(command.SingleItemAsEnumerable()); } else { switch (command) { case "download": var remoteFileUri = new Uri(parameters.First()); // create the remote file reference var remoteFile = new RemoteFile(remoteFileUri, CancellationTokenSource.Token); var previewTask = remoteFile.Preview(); previewTask.Wait(); // Tell it to download it var getTask = remoteFile.Get(); // monitor the progress. remoteFile.DownloadProgress.Notification += progress => { // this executes when the download progress value changes. Console.Write(progress <= 100 ? "..{0}% " : "bytes: [{0}]", progress); }; // when it's done, do this: getTask.ContinueWithParent(t => { // this executes when the Get() operation completes. Console.WriteLine("File {0} has finished downloading", remoteFile.LocalFullPath); }); break; case "verify-package": var r = Verifier.HasValidSignature(parameters.First()); Console.WriteLine("Has Valid Signature: {0}", r); Console.WriteLine("Name: {0}", Verifier.GetPublisherInformation(parameters.First())["PublisherName"]); break; case "install": if (parameters.Count() < 1) { throw new ConsoleException(Resources.InstallRequiresPackageName); } Tasklet.WaitforCurrentChildTasks(); // HACK HACK HACK ??? Install(parameters); break; case "remove": if (parameters.Count() < 1) { throw new ConsoleException(Resources.RemoveRequiresPackageName); } Remove(parameters); break; case "list": if (parameters.Count() != 1) { throw new ConsoleException(Resources.MissingParameterForList); } switch (parameters.FirstOrDefault().ToLower()) { case "packages": case "package": ListPackages(parameters); break; case "feed": case "feeds": case "repo": case "repos": case "repositories": case "repository": ListFeeds(parameters); break; } break; case "upgrade": if (parameters.Count() != 1) { throw new ConsoleException(Resources.MissingParameterForUpgrade); } Upgrade(parameters); break; case "add": if (parameters.Count() < 1) { throw new ConsoleException(Resources.AddFeedRequiresLocation); } CoTask.Factory.StartNew(() => AddFeed(parameters)); break; case "delete": if (parameters.Count() < 1) { throw new ConsoleException(Resources.DeleteFeedRequiresLocation); } CoTask.Factory.StartNew(() => DeleteFeed(parameters)); break; case "trim": if (parameters.Count() != 0) { throw new ConsoleException(Resources.TrimErrorMessage); } CoTask.Factory.StartNew(() => Trim(parameters)); break; case "generate-feed": CoTask.Factory.StartNew(() => GenerateFeed(parameters)); break; default: throw new ConsoleException(Resources.UnknownCommand, command); } } while (waitforbreak && !CancellationTokenSource.IsCancellationRequested) { Thread.Sleep(100); } } catch (ConsoleException failure) { CancellationTokenSource.Cancel(); Fail("{0}\r\n\r\n {1}", failure.Message, Resources.ForCommandLineHelp); } return 0; }