• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2
3import os, random, sys, time, urllib
4
5#
6# Options
7#
8
9dry_run = len(sys.argv) > 1 and "--dry-run" in set(sys.argv[1:])
10quiet = len(sys.argv) > 1 and "--quiet" in set(sys.argv[1:])
11
12#
13# Functions and constants
14#
15
16def 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
22def 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.
35mirror_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
42package_mirror_url = mirror_servers[random.choice(range(len(mirror_servers)))]
43
44def download_package(package, message):
45        download_url_to_file(package_mirror_url + package["path"], package["path"], message)
46
47required_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
77print "Using Cygwin mirror server " + package_mirror_url + " to download setup.ini..."
78
79urllib.urlretrieve(package_mirror_url + "setup.ini", "setup.ini.orig")
80
81downloaded_packages_file_path = "setup.ini.orig"
82downloaded_packages_file = file(downloaded_packages_file_path, "r")
83if not dry_run:
84    modified_packages_file = file("setup.ini", "w")
85
86packages = {}
87current_package = ''
88for 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
107downloaded_packages_file.close()
108os.remove(downloaded_packages_file_path)
109if not dry_run:
110    modified_packages_file.close()
111
112names_to_download = set()
113package_names = packages.keys()
114package_names.sort()
115
116def 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
126for name in package_names:
127        if packages[name]["needs_download"]:
128                add_package_and_dependencies(name)
129
130downloaded_so_far = 0
131for 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
136download_url_to_file("http://cygwin.com/setup.exe", "setup.exe", "Downloading setup.exe")
137
138seconds_to_sleep = 10
139
140print """
141Finished downloading Cygwin. In %d seconds,
142I will run setup.exe. Select the "Install
143from Local Directory" option and browse to
144"%s"
145when asked for the "Local Package Directory".
146""" % (seconds_to_sleep, os.getcwd())
147
148
149while seconds_to_sleep > 0:
150        print "%d..." % seconds_to_sleep,
151        sys.stdout.flush()
152        time.sleep(1)
153        seconds_to_sleep -= 1
154print
155
156if not dry_run:
157        os.execl("setup.exe")
158