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(); } 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) { if ((! File.Exists(NaGet.Env.RepositoriesListFile)) && File.Exists(NaGet.Env.ProviderListFile)) { // repos.list.xmlがなくてprovider.list.txtがあるとき、マイグレートする。 repoList = RepositoriesList.MigrateFromProviderListTxt(NaGet.Env.ProviderListFile); NaGet.Utils.PutSerializeObject(NaGet.Env.RepositoriesListFile, repoList); } else { // 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 { runDownloadPackages(); } catch (NaGetTaskCanceledException) { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "リストのダウンロード処理がキャンセルされました"); } catch (System.Net.WebException e) { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, e.Message); if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続されていません。"); } else { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。"); } } finally { int numOfEnabledRepos = NaGet.Utils.IEnumerable2Array(repoList.EnabledRepositories).Length; currentTaskSetIndex = numOfEnabledRepos + 1; } packageListsDownloaded = true; } runLocalUpdate(); } finally { done = true; } RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED, "終了", 100); } private void runDownloadPackages() { PackageList avaiablePackageList = new PackageList(); foreach(RepositoryInfo repo in repoList.EnabledRepositories) { RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); 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.Packages); } catch (InvalidOperationException) { RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, string.Format("Repository {0} does not have a AppliStation Native XML softlist.", repo.Name ?? repo.Url.Href)); } } else { RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, string.Format("Repository {0} is illegal type.", repo.Name ?? repo.Url.Href)); } } finally { if (File.Exists(tmpfileName)) { File.Delete(tmpfileName); } } currentTaskSetIndex ++; RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); } // TODO 暫定的にかならず常にrepositoryリストに書き込む。 if ( true ) { NaGet.Utils.PutSerializeObject(NaGet.Env.RepositoriesListFile, repoList); } RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); pkgListMan.availablePkgList = avaiablePackageList; // Mediatorのリストを更新 pkgListMan.SaveAvailablePackageList(); currentTaskSetIndex ++; RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); } private void runLocalUpdate() { // インストールトリストの更新 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); pkgListMan.DetectInstalledPkgs(); pkgListMan.SaveInstalledPackageList(); currentTaskSetIndex++; RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); // システムにインストールされているリストの更新 RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]); pkgListMan.DetectSystemInstalledPkgs(); pkgListMan.SaveSystemInstalledPackageList(); currentTaskSetIndex++; RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex-1]); } public override bool Cancel() { return Downloader.Cancel(); } public override bool Done { get { return done; } } } }