OSDN Git Service

na-get-lib,タスクセットの改修(NaGetTaskSet2)および、そのUnitTestを追加
[applistation/AppliStation.git] / na-get-lib / NaGet.SubCommands / NaGetUpdate.cs
1 using System;\r
2 using System.IO;\r
3 using NaGet.Packages;\r
4 using NaGet.Packages.Install;\r
5 using NaGet.Net;\r
6 using NaGet.SubCommands;\r
7 using NaGet.Tasks;\r
8 \r
9 namespace NaGet.SubCommands\r
10 {\r
11         public class NaGetUpdate : NaGetTaskSet\r
12         {\r
13                 private RepositoriesList repoList;\r
14                 \r
15                 private PackageListsManager pkgListMan;\r
16                 \r
17                 private bool downloadPackageLists = false;\r
18                 \r
19                 private bool packageListsDownloaded = true;\r
20                 \r
21                 \r
22                 /// <summary>\r
23                 /// ダウンロードに使うダウンローダオブジェクト\r
24                 /// </summary>\r
25                 public Downloader Downloader {\r
26                         get {\r
27                                 if (downloader == null) {\r
28                                         downloader = new Downloader();\r
29                                         downloader.DownloadEventRaised += delegate(object sender, DownloadEventArgs e) {\r
30                                                 if (e.DownloadTaskType == DownloadEventType.DOWNLOADING && e.ProgressPercent > 0) {\r
31                                                         RaiseTaskSetEvent(TaskEventType.PING, string.Empty, GetProgressPercent(TaskEventType.PING, e.ProgressPercent));\r
32                                                 }\r
33                                         };\r
34                                 }\r
35                                 return downloader;\r
36                         }\r
37                 }\r
38                 \r
39                 private Downloader downloader;\r
40                 \r
41                 private int currentTaskSetIndex = -1;\r
42                 \r
43                 private bool done = false;\r
44                 \r
45                 public override int CurrentTaskSetIndex {\r
46                         get { return currentTaskSetIndex; }\r
47                 }\r
48                 \r
49                 public override bool Cancelable {\r
50                         get { return ! packageListsDownloaded; }\r
51                 }\r
52                 \r
53                 public NaGetUpdate(PackageListsManager pkgListMan)\r
54                         : this(pkgListMan, true)\r
55                 {\r
56                 }\r
57                 \r
58                 public NaGetUpdate(PackageListsManager pkgMan, bool downloadPackageListsFlag)\r
59                 {\r
60                         pkgListMan = pkgMan;\r
61                         downloadPackageLists = downloadPackageListsFlag;\r
62                         \r
63                         taskSetNames = new System.Collections.Generic.List<string>();\r
64                         if (downloadPackageLists) {\r
65                                 // repos.list.xmlがあるとき、そこからよみとる。\r
66                                 repoList = NaGet.Utils.GetDeserializedObject<RepositoriesList>(NaGet.Env.RepositoriesListFile);\r
67                                 \r
68                                 foreach (RepositoryInfo repo in repoList.EnabledRepositories) {\r
69                                         taskSetNames.Add(string.Format("リスト取得: {0}", repo.Url.Href));\r
70                                 }\r
71                                 taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.PackageListFile));\r
72                         }\r
73                         taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.ArchiveInstalledPackageListFile));\r
74                         taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.SystemInstalledPackageListFile));\r
75                 }\r
76 \r
77                 public override void Run()\r
78                 {\r
79                         currentTaskSetIndex ++;\r
80                         RaiseTaskSetEvent(TaskEventType.STARTED, "リスト更新処理開始");\r
81                         \r
82                         try {\r
83                                 // リストのダウンロード\r
84                                 if (downloadPackageLists) {\r
85                                         packageListsDownloaded = false;\r
86                                         try {\r
87                                                 runDownloadPackageLists();\r
88                                         } catch (TaskCanceledException) {\r
89                                                 RaiseTaskSetEvent(TaskEventType.WARNING, "リストのダウンロード処理がキャンセルされました");\r
90                                                 pkgListMan.LoadPackageLists();\r
91                                         } catch (System.Net.WebException e) {\r
92                                                 RaiseTaskSetEvent(TaskEventType.WARNING, e.Message);\r
93                                                 if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) {\r
94                                                         RaiseTaskSetEvent(TaskEventType.WARNING, "ネットワークに接続されていません。");\r
95                                                 } else {\r
96                                                         RaiseTaskSetEvent(TaskEventType.WARNING, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。");\r
97                                                 }\r
98                                                 pkgListMan.LoadPackageLists();\r
99                                         } finally {\r
100                                                 int numOfEnabledRepos = NaGet.Utils.IEnumerable2Array(repoList.EnabledRepositories).Length;\r
101                                                 currentTaskSetIndex = numOfEnabledRepos + 1;\r
102                                         }\r
103                                         packageListsDownloaded = true;\r
104                                 }\r
105                                 \r
106                                 runLocalUpdate();\r
107                         } finally {\r
108                                 done = true;\r
109                         }\r
110                         \r
111                         RaiseTaskSetEvent(TaskEventType.COMPLETED, "終了", 100);\r
112                 }\r
113                 \r
114                 private void runDownloadPackageLists()\r
115                 {\r
116                         PackageList<Package> avaiablePackageList = new PackageList<Package>();\r
117                         foreach(RepositoryInfo repo in repoList.EnabledRepositories) {\r
118                                 RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);\r
119                                 \r
120                                 if (Uri.IsWellFormedUriString(repo.Url.Href, UriKind.Absolute)) {\r
121                                         string tmpfileName = Path.GetTempFileName();\r
122                                         try {\r
123                                                 Downloader.Download(repo.Url.Href, tmpfileName);\r
124                                                 if (repo.Type == RepositoryType.APPLISTATION_NATIVE_XML_1_0) {\r
125                                                         try {\r
126                                                                 PackageList<Package> pkgList = NaGet.Utils.GetDeserializedObject<PackageList<Package>>(tmpfileName);\r
127                                                                 pkgList.FixPackageListName(); // PackageListNameとの紐付けを行う\r
128                                                                 \r
129                                                                 // RepositoryReferenceの名前を読み込む // TODO RepositoryReferenceの名前を読み込む処理はここでいいのか?\r
130                                                                 repo.Name = (string.IsNullOrEmpty(pkgList.Name))? repo.Name : pkgList.Name;\r
131                                                                 \r
132                                                                 avaiablePackageList.AddPackages(pkgList);\r
133                                                         } catch (InvalidOperationException) {\r
134                                                                 RaiseTaskSetEvent(TaskEventType.ERROR, string.Format("レポジトリ'{0}'はAppliStation Native XML softlist形式ではありません。", repo.Name ?? repo.Url.Href));\r
135                                                         }\r
136                                                 } else {\r
137                                                         RaiseTaskSetEvent(TaskEventType.WARNING, string.Format("レポジトリ'{0}'の設定が不正です。", repo.Name ?? repo.Url.Href));\r
138                                                 }\r
139                                         } finally {\r
140                                                 if (File.Exists(tmpfileName)) {\r
141                                                         File.Delete(tmpfileName);\r
142                                                 }\r
143                                         }\r
144                                 } else {\r
145                                         RaiseTaskSetEvent(TaskEventType.WARNING, string.Format("レポジトリ'{0}'のURLが不正なため、ソフトリストは取得できませんでした。", repo.Name ?? repo.Url.Href));\r
146                                 }\r
147                                 \r
148                                 RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);\r
149                                 currentTaskSetIndex ++;\r
150                         }\r
151                         \r
152                         // TODO 暫定的にかならず常にrepositoryリストに書き込む。\r
153                         if ( true ) {\r
154                                 NaGet.Utils.PutSerializeObject(NaGet.Env.RepositoriesListFile, repoList);\r
155                         }\r
156                         \r
157                         RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);\r
158                         pkgListMan.availablePkgList = avaiablePackageList; // Mediatorのリストを更新\r
159                         pkgListMan.SaveAvailablePackageList();\r
160                         RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, taskSetNames[currentTaskSetIndex]);\r
161                         currentTaskSetIndex ++;\r
162                 }\r
163                 \r
164                 private void runLocalUpdate()\r
165                 {\r
166                         // インストールトリストの更新\r
167                         RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, taskSetNames[currentTaskSetIndex]);\r
168                         pkgListMan.DetectInstalledPkgs();\r
169                         pkgListMan.SaveInstalledPackageList();\r
170                         RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, TaskSetNames[currentTaskSetIndex]);\r
171                         currentTaskSetIndex++;\r
172                 \r
173                         // システムにインストールされているリストの更新\r
174                         RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, TaskSetNames[currentTaskSetIndex]);\r
175                         pkgListMan.DetectSystemInstalledPkgs();\r
176                         pkgListMan.SaveSystemInstalledPackageList();\r
177                         RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, TaskSetNames[currentTaskSetIndex]);\r
178                         currentTaskSetIndex++;\r
179                 }\r
180                 \r
181                 public override bool Cancel()\r
182                 {\r
183                         return Downloader.Cancel();\r
184                 }\r
185 \r
186                 public override bool Done {\r
187                         get { return done; }\r
188                 }\r
189         }\r
190 }\r