#!/usr/bin/env python3
# vim:ts=4:sw=4:expandtab:
"""A script to get the list of installed atom packages, match it to the list of
expected packages, and install any that are missing."""

import subprocess
import argparse
# pylint: disable=invalid-name

# a dict of packages installed because they are dependencies of a package in my-packages.txt
# better but difficult: get deps from package.json files
DEPENDENCIES = {"nuclide-installer":
                ("nuclide-clang-atom", "nuclide-blame-ui", "nuclide-diagnostics-ui",
                 "nuclide-debugger-atom", "nuclide-debugger-hhvm", "nuclide-arcanist",
                 "nuclide-diagnostics-store", "nuclide-debugger-lldb", "nuclide-blame-provider-hg",
                 "nuclide-diff-view", "nuclide-blame", "nuclide-code-format", "nuclide-buck-files")}


def get_args():
    """Parses command-line arguments, returns namespace with values."""
    parser = argparse.ArgumentParser(
        description="Report or install apm packages according to my-packages.txt")
    parser.add_argument('--install', action='store_true',
                        help="Actually install missing packages (default: report only).")
    return parser.parse_args()


def get_installed_pkgs():
    apm_list = subprocess.Popen(['apm', 'list', '-ib'], stdout=subprocess.PIPE, bufsize=-1)
    results, _ = apm_list.communicate()

    installed = set()
    for spec in results.split(b'\n'):
        parts = spec.split(b"@")
        if parts[0]:
            installed.add(parts[0].decode('utf-8'))
    return installed


def get_wanted_packages():
    wanted = set()
    with open('my-packages.txt', 'r') as myin:
        for line in myin:
            wanted.add(line[:-1])
    for key in DEPENDENCIES:
        if key in wanted:
            for pkg_name in DEPENDENCIES[key]:
                wanted.add(pkg_name)
    return wanted


def install_missing(wanted, installed):
    to_install = wanted - installed
    if to_install:
        print("Installing {} missing packages.".format(len(to_install)))
        for pkg in wanted - installed:
            subprocess.call(['apm', 'install', pkg])
    else:
        print("nothing to do!")


def report_missing_packages(wanted, installed):
    missing = wanted - installed
    if missing:
        print("Expected packages not installed:")
        for missed in missing:
            print(missed)


def report_extra_packages(wanted, installed):
    extras = installed - wanted
    if extras:
        print("\nExtra packages installed locally:")
        for extra in extras:
            print(extra)


def main():
    args = get_args()
    installed = get_installed_pkgs()
    wanted = get_wanted_packages()
    report_missing_packages(wanted, installed)
    report_extra_packages(wanted, installed)
    if args.install:
        install_missing(wanted, installed)


if __name__ == '__main__':
    main()

@@ -26,15 +26,16 @@
 vim:
-ts
+ sw
 =4:
+t
 s
-w
 =4:e
@@ -42,17 +42,16 @@
 xpandtab
-:
 %0A%22%22%22A sc
@@ -803,16 +803,606 @@
 k-files%22
+,%0A                 %22nuclide-hack-symbol-provider%22, %22nuclide-hack%22, %22nuclide-fuzzy-filename-provider%22,%0A                 %22nuclide-file-watcher%22, %22nuclide-test-runner%22, %22nuclide-flow%22, %22nuclide-toolbar%22,%0A                 %22nuclide-file-tree-deux%22, %22nuclide-objc%22, %22nuclide-find-references%22,%0A                 %22nuclide-open-filenames-provider%22, %22nuclide-move-pane%22, %22nuclide-type-hint%22,%0A                 %22nuclide-file-tree%22, %22nuclide-ocaml%22, %22nuclide-hg-repository%22,%0A                 %22nuclide-remote-projects%22, %22nuclide-quick-open%22, %22nuclide-language-hack%22,%0A                 %22nuclide-format-js%22, 
 )%7D%0A%0A%0Adef
@@ -1755,16 +1755,137 @@
 nly).%22)%0A
+    parser.add_argument('--beta', action='store_true',%0A                        help=%22Act on beta-channel atom version.%22)%0A
     retu
@@ -1932,16 +1932,24 @@
 ed_pkgs(
+apm_prog
 ):%0A    a
@@ -1976,21 +1976,24 @@
 .Popen(%5B
-'
 apm
-'
+_prog
 , 'list'
@@ -2245,16 +2245,193 @@
 tf-8'))%0A
+%0A    # remove dependencies from list%0A    for key in DEPENDENCIES:%0A        if key in installed:%0A            for pkg in DEPENDENCIES%5Bkey%5D:%0A                installed.discard(pkg)%0A%0A
     retu
@@ -2602,147 +2602,8 @@
 1%5D)%0A
-    for key in DEPENDENCIES:%0A        if key in wanted:%0A            for pkg_name in DEPENDENCIES%5Bkey%5D:%0A                wanted.add(pkg_name)%0A
     
@@ -2630,32 +2630,42 @@
 install_missing(
+apm_prog, 
 wanted, installe
@@ -2868,13 +2868,16 @@
 ll(%5B
-'
 apm
-'
+_prog
 , 'i
@@ -3373,24 +3373,69 @@
  get_args()%0A
+    apm = 'apm-beta' if args.beta else 'apm'%0A
     installe
@@ -3457,16 +3457,19 @@
 ed_pkgs(
+apm
 )%0A    wa
@@ -3634,16 +3634,21 @@
 missing(
+apm, 
 wanted, 

Add --beta, fix dependcy handling