|
1 #!/usr/bin/env python |
|
2 |
|
3 import os, random, sys, time, urllib |
|
4 |
|
5 # |
|
6 # Options |
|
7 # |
|
8 |
|
9 dry_run = len(sys.argv) > 1 and "--dry-run" in set(sys.argv[1:]) |
|
10 quiet = len(sys.argv) > 1 and "--quiet" in set(sys.argv[1:]) |
|
11 |
|
12 # |
|
13 # Functions and constants |
|
14 # |
|
15 |
|
16 def download_progress_hook(block_count, block_size, total_blocks): |
|
17 if quiet or random.random() > 0.5: |
|
18 return |
|
19 sys.stdout.write(".") |
|
20 sys.stdout.flush() |
|
21 |
|
22 def download_url_to_file(url, file, message): |
|
23 if not quiet: |
|
24 print message + " ", |
|
25 if not dry_run: |
|
26 dir = os.path.dirname(file) |
|
27 if len(dir) and not os.path.exists(dir): |
|
28 os.makedirs(dir) |
|
29 urllib.urlretrieve(url, file, download_progress_hook) |
|
30 if not quiet: |
|
31 print |
|
32 |
|
33 # This is mostly just the list of North America http mirrors from http://cygwin.com/mirrors.html, |
|
34 # but a few have been removed that seemed unresponsive from Cupertino. |
|
35 mirror_servers = ["http://cygwin.elite-systems.org/", |
|
36 "http://mirror.mcs.anl.gov/cygwin/", |
|
37 "http://cygwin.osuosl.org/", |
|
38 "http://mirrors.kernel.org/sourceware/cygwin/", |
|
39 "http://mirrors.xmission.com/cygwin/", |
|
40 "http://sourceware.mirrors.tds.net/pub/sourceware.org/cygwin/"] |
|
41 |
|
42 package_mirror_url = mirror_servers[random.choice(range(len(mirror_servers)))] |
|
43 |
|
44 def download_package(package, message): |
|
45 download_url_to_file(package_mirror_url + package["path"], package["path"], message) |
|
46 |
|
47 required_packages = frozenset(["apache", |
|
48 "bc", |
|
49 "bison", |
|
50 "curl", |
|
51 "diffutils", |
|
52 "e2fsprogs", |
|
53 "emacs", |
|
54 "flex", |
|
55 "gcc", |
|
56 "gperf", |
|
57 "keychain", |
|
58 "make", |
|
59 "nano", |
|
60 "openssh", |
|
61 "patch", |
|
62 "perl", |
|
63 "perl-libwin32", |
|
64 "python", |
|
65 "rebase", |
|
66 "rsync", |
|
67 "ruby", |
|
68 "subversion", |
|
69 "unzip", |
|
70 "vim", |
|
71 "zip"]) |
|
72 |
|
73 # |
|
74 # Main |
|
75 # |
|
76 |
|
77 print "Using Cygwin mirror server " + package_mirror_url + " to download setup.ini..." |
|
78 |
|
79 urllib.urlretrieve(package_mirror_url + "setup.ini", "setup.ini.orig") |
|
80 |
|
81 downloaded_packages_file_path = "setup.ini.orig" |
|
82 downloaded_packages_file = file(downloaded_packages_file_path, "r") |
|
83 if not dry_run: |
|
84 modified_packages_file = file("setup.ini", "w") |
|
85 |
|
86 packages = {} |
|
87 current_package = '' |
|
88 for line in downloaded_packages_file.readlines(): |
|
89 if line[0] == "@": |
|
90 current_package = line[2:-1] |
|
91 packages[current_package] = {"name": current_package, "needs_download": False, "requires": [], "path": ""} |
|
92 elif line[:10] == "category: ": |
|
93 if current_package in required_packages: |
|
94 line = "category: Base\n" |
|
95 if "Base" in set(line[10:-1].split()): |
|
96 packages[current_package]["needs_download"] = True |
|
97 elif line[:10] == "requires: ": |
|
98 packages[current_package]["requires"] = line[10:].split() |
|
99 packages[current_package]["requires"].sort() |
|
100 elif line[:9] == "install: " and not len(packages[current_package]["path"]): |
|
101 end_of_path = line.find(" ", 9) |
|
102 if end_of_path != -1: |
|
103 packages[current_package]["path"] = line[9:end_of_path] |
|
104 if not dry_run: |
|
105 modified_packages_file.write(line) |
|
106 |
|
107 downloaded_packages_file.close() |
|
108 os.remove(downloaded_packages_file_path) |
|
109 if not dry_run: |
|
110 modified_packages_file.close() |
|
111 |
|
112 names_to_download = set() |
|
113 package_names = packages.keys() |
|
114 package_names.sort() |
|
115 |
|
116 def add_package_and_dependencies(name): |
|
117 if name in names_to_download: |
|
118 return |
|
119 if not name in packages: |
|
120 return |
|
121 packages[name]["needs_download"] = True |
|
122 names_to_download.add(name) |
|
123 for dep in packages[name]["requires"]: |
|
124 add_package_and_dependencies(dep) |
|
125 |
|
126 for name in package_names: |
|
127 if packages[name]["needs_download"]: |
|
128 add_package_and_dependencies(name) |
|
129 |
|
130 downloaded_so_far = 0 |
|
131 for name in package_names: |
|
132 if packages[name]["needs_download"]: |
|
133 downloaded_so_far += 1 |
|
134 download_package(packages[name], "Downloading package %3d of %3d (%s)" % (downloaded_so_far, len(names_to_download), name)) |
|
135 |
|
136 download_url_to_file("http://cygwin.com/setup.exe", "setup.exe", "Downloading setup.exe") |
|
137 |
|
138 seconds_to_sleep = 10 |
|
139 |
|
140 print """ |
|
141 Finished downloading Cygwin. In %d seconds, |
|
142 I will run setup.exe. Select the "Install |
|
143 from Local Directory" option and browse to |
|
144 "%s" |
|
145 when asked for the "Local Package Directory". |
|
146 """ % (seconds_to_sleep, os.getcwd()) |
|
147 |
|
148 |
|
149 while seconds_to_sleep > 0: |
|
150 print "%d..." % seconds_to_sleep, |
|
151 sys.stdout.flush() |
|
152 time.sleep(1) |
|
153 seconds_to_sleep -= 1 |
|
154 print |
|
155 |
|
156 if not dry_run: |
|
157 os.execl("setup.exe") |