diff --git a/cli50 b/cli50 index 24c0d0f..fddc08a 100755 --- a/cli50 +++ b/cli50 @@ -34,7 +34,8 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument("-f", "--fast", action="store_true", help="skip autoupdate") parser.add_argument("-g", "--git", action="store_true", help="mount .gitconfig") - parser.add_argument("-l", "--login", help="log into container", metavar="CONTAINER") + parser.add_argument("-l", "--login", const=True, default=False, help="log into container", + metavar="CONTAINER", nargs="?") parser.add_argument("-p", "--publish", action="append", help="publish port(s) to ports on host", metavar="LIST", nargs="?") parser.add_argument("-P", "--publish-all", action="store_true", @@ -79,46 +80,52 @@ def main(): # Log into container if args["login"]: + + # If container specified + if isinstance(args["login"], str): + try: + login(args["login"]) + except: + sys.exit(1) + else: + sys.exit(0) + + # Check for running containers try: - login(args["login"]) - except: + stdout = subprocess.check_output([ + "docker", "ps", + "--all", + "--filter", "status=running", + "--format", "{{.ID}}\t{{.Image}}\t{{.RunningFor}}\t{{.Mounts}}", + "--no-trunc" + ]).decode("utf-8") + except subprocess.CalledProcessError: sys.exit(1) else: - sys.exit(0) - - # Check for running containers - try: - stdout = subprocess.check_output([ - "docker", "ps", - "--all", - "--filter", - f"volume={directory}", - "--format", "{{.ID}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}" - ]).decode("utf-8") - except subprocess.CalledProcessError: - sys.exit(1) - else: - containers = [] - for line in stdout.rstrip().splitlines(): - ID, Image, RunningFor, Status = line.split("\t") - if Image == image and Status.startswith("Up"): - containers.append((ID, RunningFor.lower())) - - # Ask whether to use a running container - if containers: - print(f"{directory} is already mounted in {len(containers)} {inflect.engine().plural('container', len(containers))}.") - for ID, RunningFor in containers: - while True: - stdin = input(f"New shell in {ID}, running for {RunningFor}? [Y] ") - if re.match("^\s*(?:y|yes)?\s*$", stdin, re.I): - try: - login(ID) - except: - sys.exit(1) + containers = [] + for line in stdout.rstrip().splitlines(): + ID, Image, RunningFor, *Mounts = line.split("\t") + Mounts = Mounts[0].split(",") if Mounts else [] + Mounts = [Mount for Mount in Mounts if not re.match(r"^[0-9a-fA-F]{64}$", Mount)] # Ignore hashes + containers.append((ID, Image, RunningFor.lower(), Mounts)) + + # Ask whether to use a running container + for ID, Image, RunningFor, Mounts in containers: + while True: + prompt = f"Log into {Image}, started {RunningFor}" + if Mounts: + prompt += " with " + inflect.engine().join(Mounts) + " mounted" + prompt += "? [Y] " + stdin = input(prompt) + if re.match("^\s*(?:y|yes)?\s*$", stdin, re.I): + try: + login(ID) + except: + sys.exit(1) + else: + sys.exit(0) else: - sys.exit(0) - else: - break + break # Update image if not args["fast"]: diff --git a/setup.py b/setup.py index c93ab38..e396e11 100644 --- a/setup.py +++ b/setup.py @@ -16,5 +16,5 @@ python_requires=">=3.6", scripts=["cli50"], url="https://github.com/cs50/cli50", - version="2.2.1" + version="2.3.0" )