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