1 #!/usr/bin/env nix-shell
2 #!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ ])" nix
4 A program to remove old aliases or convert old aliases to throws
6 ./maintainers/scripts/remove-old-aliases.py --year 2018 --file ./pkgs/top-level/aliases.nix
8 Check this file with mypy after every change!
9 $ mypy --strict maintainers/scripts/remove-old-aliases.py
14 from datetime
import date
as datetimedate
15 from datetime
import datetime
16 from pathlib
import Path
19 def process_args() -> argparse
.Namespace
:
21 arg_parser
= argparse
.ArgumentParser()
22 arg_parser
.add_argument(
23 "--year", required
=True, type=int, help="operate on aliases older than $year"
25 arg_parser
.add_argument(
29 help="operate on aliases older than $year-$month",
31 arg_parser
.add_argument(
34 help="only operate on throws. e.g remove throws older than $date",
36 arg_parser
.add_argument("--file", required
=True, type=Path
, help="alias file")
37 arg_parser
.add_argument(
38 "--dry-run", action
="store_true", help="don't modify files, only print results"
40 return arg_parser
.parse_args()
44 txt
: list[str], cutoffdate
: datetimedate
, only_throws
: bool
45 ) -> tuple[list[str], list[str], list[str]]:
46 """get a list of lines in which the date is older than $cutoffdate"""
47 date_older_list
: list[str] = []
48 date_older_throw_list
: list[str] = []
49 date_sep_line_list
: list[str] = []
51 for lineno
, line
in enumerate(txt
, start
=1):
54 for string
in line
.split():
55 string
= string
.strip(":")
57 # strip ':' incase there is a string like 2019-11-01:
58 my_date
= datetime
.strptime(string
, "%Y-%m-%d").date()
61 my_date
= datetime
.strptime(string
, "%Y-%m").date()
67 or my_date
> cutoffdate
68 or "preserve, reason:" in line
.lower()
73 date_sep_line_list
.append(f
"{lineno} {line}")
74 # 'if' lines could be complicated
75 elif "if " in line
and "if =" not in line
:
76 print(f
"RESOLVE MANUALLY {line}")
78 date_older_throw_list
.append(line
)
80 date_older_list
.append(line
)
85 date_older_throw_list
,
89 def convert_to_throw(date_older_list
: list[str]) -> list[tuple[str, str]]:
90 """convert a list of lines to throws"""
92 for line
in date_older_list
.copy():
93 indent
: str = " " * (len(line
) - len(line
.lstrip()))
97 before_equal
, after_equal
= (x
.strip() for x
in line
.split("=", maxsplit
=2))
98 except ValueError as err
:
99 print(err
, line
, "\n")
100 date_older_list
.remove(line
)
104 alias_unquoted
= before_equal
.strip('"')
105 replacement
= next(x
.strip(";:") for x
in after_equal
.split())
106 replacement
= replacement
.removeprefix("pkgs.")
109 f
"{indent}{alias} = throw \"'{alias_unquoted}' has been"
110 f
" renamed to/replaced by '{replacement}'\";"
111 f
" # Converted to throw {datetime.today().strftime('%Y-%m-%d')}"
113 converted_list
.append((line
, converted
))
115 return converted_list
118 def generate_text_to_write(
120 date_older_list
: list[str],
121 converted_to_throw
: list[tuple[str, str]],
122 date_older_throw_list
: list[str],
124 """generate a list of text to be written to the aliasfile"""
125 text_to_write
: list[str] = []
127 text_to_append
: str = ""
128 if converted_to_throw
:
129 for tupl
in converted_to_throw
:
131 text_to_append
= f
"{tupl[1]}\n"
132 if line
not in date_older_list
and line
not in date_older_throw_list
:
133 text_to_append
= f
"{line}\n"
135 text_to_write
.append(text_to_append
)
142 text_to_write
: list[str],
145 temp_aliasfile
= Path(f
"{aliasfile}.raliases")
146 with
open(temp_aliasfile
, "w", encoding
="utf-8") as far
:
147 for line
in text_to_write
:
149 print("\nChecking the syntax of the new aliasfile")
152 ["nix-instantiate", "--eval", temp_aliasfile
],
154 stdout
=subprocess
.DEVNULL
,
156 except subprocess
.CalledProcessError
:
158 "\nSyntax check failed,",
159 "there may have been a line which only has\n"
160 'aliasname = "reason why";\n'
161 "when it should have been\n"
162 'aliasname = throw "reason why";',
164 temp_aliasfile
.unlink()
166 shutil
.move(f
"{aliasfile}.raliases", aliasfile
)
167 print(f
"{aliasfile} modified! please verify with 'git diff'.")
172 args
= process_args()
174 only_throws
= args
.only_throws
175 aliasfile
= Path(args
.file).absolute()
176 cutoffdate
= (datetime
.strptime(f
"{args.year}-{args.month}-01", "%Y-%m-%d")).date()
178 txt
: list[str] = (aliasfile
.read_text(encoding
="utf-8")).splitlines()
180 date_older_list
: list[str] = []
181 date_sep_line_list
: list[str] = []
182 date_older_throw_list
: list[str] = []
184 date_older_list
, date_sep_line_list
, date_older_throw_list
= get_date_lists(
185 txt
, cutoffdate
, only_throws
188 converted_to_throw
: list[tuple[str, str]] = []
190 converted_to_throw
= convert_to_throw(date_older_list
)
191 print(" Will be converted to throws. ".center(100, "-"))
192 for l_n
in date_older_list
:
195 if date_older_throw_list
:
196 print(" Will be removed. ".center(100, "-"))
197 for l_n
in date_older_throw_list
:
200 if date_sep_line_list
:
201 print(" On separate line, resolve manually. ".center(100, "-"))
202 for l_n
in date_sep_line_list
:
206 text_to_write
= generate_text_to_write(
207 txt
, date_older_list
, converted_to_throw
, date_older_throw_list
209 write_file(aliasfile
, text_to_write
)
212 if __name__
== "__main__":