11"""Docker module."""
2+ import argparse
23import json
34from pathlib import Path
5+ from subprocess import PIPE
46from typing import List
57
6- from clit .files import shell
8+ from clit .config import JsonConfig
9+ from clit .files import existing_directory_type , shell , shell_find
710from clit .types import JsonDict
811
12+ YML_DIRS = JsonConfig ("docker-find-yml-dirs.json" )
13+ YML_FILES = JsonConfig ("docker-find-yml-files.json" )
14+
915
1016class DockerContainer :
1117 """A helper for Docker containers."""
@@ -31,3 +37,103 @@ def replace_mount_dir(self, path: Path) -> Path:
3137 new_path = str (path ).replace (source , mount ["Destination" ])
3238 return Path (new_path )
3339 return path
40+
41+
42+ def rescan_files (dirs ):
43+ """Rescan all directories and save the yml files that were found."""
44+ sorted_dirs = sorted (dirs )
45+ YML_DIRS .dump (sorted_dirs )
46+
47+ files = set ()
48+ for dir in sorted_dirs :
49+ print (f"Files on { dir } " )
50+ for file in shell_find (f"{ dir } -name docker-compose.yml" ):
51+ print (f" { file } " )
52+ files .add (str (file ))
53+ sorted_files = sorted (files )
54+ YML_FILES .dump (sorted_files )
55+
56+
57+ def scan_command (parser , args ):
58+ """Scan directories and add them to the list."""
59+ dirs = YML_DIRS .load_set ()
60+ if not args .dir :
61+ print (f"Rescanning existing directories" )
62+ for dir in args .dir :
63+ dirs .add (str (dir ))
64+ print (f"Directory added: { dir } " )
65+ rescan_files (dirs )
66+
67+
68+ def rm_command (parser , args ):
69+ """Remove directories from the list."""
70+ dirs = YML_DIRS .load_set ()
71+ for one_dir in args .dir :
72+ str_dir = str (one_dir )
73+ if str_dir in dirs :
74+ dirs .remove (str_dir )
75+ print (f"Directory removed: { one_dir } " )
76+ else :
77+ print (f"Directory was not configured: { one_dir } " )
78+ rescan_files (dirs )
79+
80+
81+ def ls_command (parser , args ):
82+ """List registered yml files."""
83+ for yml_file in sorted (YML_FILES .load_set ()):
84+ print (yml_file )
85+
86+
87+ def yml_command (parser , args ):
88+ """Run a docker-compose command on one of the yml files."""
89+ found = set ()
90+ partial_name = args .yml_file
91+
92+ for file in YML_FILES .load_set ():
93+ if partial_name in file :
94+ found .add (file )
95+ if not found :
96+ print (f"No .yml file was found with the string '{ partial_name } '" )
97+ exit (1 )
98+
99+ sorted_found = sorted (found )
100+ if len (sorted_found ) > 1 :
101+ choices = "\n " .join (sorted_found )
102+ chosen_yml = shell (f"echo '{ choices } ' | fzf --cycle --tac" , quiet = True , stdout = PIPE ).stdout .strip ()
103+ if not chosen_yml :
104+ print ("No .yml file was chosen" )
105+ exit (2 )
106+ else :
107+ chosen_yml = sorted_found [0 ]
108+ shell (f"docker-compose -f { chosen_yml } { ' ' .join (args .docker_compose_arg )} " )
109+
110+
111+ # TODO: Convert to click
112+ def docker_find ():
113+ """Find docker.compose.yml files."""
114+ parser = argparse .ArgumentParser (description = "find docker.compose.yml files" )
115+ parser .set_defaults (chosen_function = None )
116+ subparsers = parser .add_subparsers (title = "commands" )
117+
118+ parser_scan = subparsers .add_parser ("scan" , help = "scan directories and add them to the list" )
119+ parser_scan .add_argument ("dir" , nargs = "*" , help = "directory to scan" , type = existing_directory_type )
120+ parser_scan .set_defaults (chosen_function = scan_command )
121+
122+ parser_rm = subparsers .add_parser ("rm" , help = "remove directories from the list" )
123+ parser_rm .add_argument ("dir" , nargs = "+" , help = "directory to remove" , type = existing_directory_type )
124+ parser_rm .set_defaults (chosen_function = rm_command )
125+
126+ parser_ls = subparsers .add_parser ("ls" , help = "list yml files" )
127+ parser_ls .set_defaults (chosen_function = ls_command )
128+
129+ parser_yml = subparsers .add_parser ("yml" , help = "choose one of the yml files to call docker-compose on" )
130+ parser_yml .add_argument ("yml_file" , help = "partial name of the desired .yml file" )
131+ parser_yml .add_argument ("docker_compose_arg" , nargs = argparse .REMAINDER , help = "docker-compose arguments" )
132+ parser_yml .set_defaults (chosen_function = yml_command )
133+
134+ args = parser .parse_args ()
135+ if not args .chosen_function :
136+ parser .print_help ()
137+ return
138+ args .chosen_function (parser , args )
139+ return
0 commit comments