using System; using System.IO; using NaGet.Packages; using NaGet.Packages.Install; using NaGet.Net; using NaGet.SubCommands; namespace NaGet.SubCommands { public class NaGetUpdate : NaGetTaskSet { private RepositoriesList repoList; private PackageListsManager pkgListMan; private bool downloadPackageLists = false; private bool packageListsDownloaded = true; /// /// ダウンロードに使うダウンローダオブジェクト /// public Downloader Downloader { get { if (downloader == null) { downloader = new Downloader(); downloader.DownloadEventRaised += delegate(object sender, DownloadEventArgs e) { if (e.Type == DownloadEventType.DOWNLOADING && e.TaskProgressPercent > 0) { RaiseTaskSetEvent(NaGetTaskSetEventType.PING, string.Empty, GetProgressPercent(NaGetTaskSetEventType.PING, e.TaskProgressPercent)); } }; } return downloader; } } private Downloader downloader; private int currentTaskSetIndex = -1; private bool done = false; public override int CurrentTaskSetIndex { get { return currentTaskSetIndex; } } public override bool Cancelable { get { return ! packageListsDownloaded; } } public NaGetUpdate(PackageListsManager pkgListMan) : this(pkgListMan, true) { } public NaGetUpdate(PackageListsManager pkgMan, bool downloadPackageListsFlag) { pkgListMan = pkgMan; downloadPackageLists = downloadPackageListsFlag; System.Collections.Generic.List taskSetNames = new System.Collections.Generic.List(); if (downloadPackageLists) { // repos.list.xmlがあるとき、そこからよみとる。 repoList = NaGet.Utils.GetDeserializedObject(NaGet.Env.RepositoriesListFile); foreach (RepositoryInfo repo in repoList.EnabledRepositories) { taskSetNames.Add(string.Format("リスト取得: {0}", repo.Url.Href)); } taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.PackageListFile)); } taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.ArchiveInstalledPackageListFile)); taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.SystemInstalledPackageListFile)); TaskSetNames = taskSetNames.ToArray(); } public override void Run() { currentTaskSetIndex ++; RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED, "リスト更新処理開始"); try { // リストのダウンロード if (downloadPackageLists) { packageListsDownloaded = false; try { runDownloadPackageLists(); } catch (NaGetTaskCanceledException) { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "リストのダウンロード処理がキャンセルされました"); pkgListMan.LoadPackageLists(); } catch (System.Net.WebException e) { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, e.Message); if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続されていません。"); } else { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。"); } pkgListMan.LoadPackageLists(); } finally { int numOfEnabledRepos = NaGet.Utils.IEnumerable2Array(repoList.EnabledRepositories).Length; currentTaskSetIndex = numOfEnabledRepos + 1; } packageListsDownloaded = true; } runLocalUpdate(); } finally { done = true; } RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED, "終了", 100); } private void runDownloadPackageLists() { PackageList avaiablePackageList = new PackageList(); foreach(RepositoryInfo repo in repoList.EnabledRepositories) { RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); if (Uri.IsWellFormedUriString(repo.Url.Href, UriKind.Absolute)) { string tmpfileName = Path.GetTempFileName(); try { Downloader.Download(repo.Url.Href, tmpfileName); if (repo.Type == RepositoryType.APPLISTATION_NATIVE_XML_1_0) { try { PackageList pkgList = NaGet.Utils.GetDeserializedObject>(tmpfileName); pkgList.FixPackageListName(); // PackageListNameとの紐付けを行う // RepositoryReferenceの名前を読み込む // TODO RepositoryReferenceの名前を読み込む処理はここでいいのか? repo.Name = (string.IsNullOrEmpty(pkgList.Name))? repo.Name : pkgList.Name; avaiablePackageList.AddPackages(pkgList); } catch (InvalidOperationException) { RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, string.Format("レポジトリ'{0}'はAppliStation Native XML softlist形式ではありません。", repo.Name ?? repo.Url.Href)); } } else { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, string.Format("レポジトリ'{0}'の設定が不正です。", repo.Name ?? repo.Url.Href)); } } finally { if (File.Exists(tmpfileName)) { File.Delete(tmpfileName); } } } else { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, string.Format("レポジトリ'{0}'のURLが不正なため、ソフトリストは取得できませんでした。", repo.Name ?? repo.Url.Href)); } RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]); currentTaskSetIndex ++; } // TODO 暫定的にかならず常にrepositoryリストに書き込む。 if ( true ) { NaGet.Utils.PutSerializeObject(NaGet.Env.RepositoriesListFile, repoList); } RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); pkgListMan.availablePkgList = avaiablePackageList; // Mediatorのリストを更新 pkgListMan.SaveAvailablePackageList(); RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]); currentTaskSetIndex ++; } private void runLocalUpdate() { // インストールトリストの更新 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); pkgListMan.DetectInstalledPkgs(); pkgListMan.SaveInstalledPackageList(); RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]); currentTaskSetIndex++; // システムにインストールされているリストの更新 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); pkgListMan.DetectSystemInstalledPkgs(); pkgListMan.SaveSystemInstalledPackageList(); RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]); currentTaskSetIndex++; } public override bool Cancel() { return Downloader.Cancel(); } public override bool Done { get { return done; } } } }