cygwin-downloader.py 5.4 KB

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