1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! This file contains individual, totally independent regression tests for very
//! specific scenarios each.
use cargo_bin_cmd;
/// If this test fails, brew build process will fail:
///
/// <https://github.com/Homebrew/homebrew-core/blob/a13b8b53c3902e3e18b6c839f3188cc37d529e6f/Formula/s/srgn.rb#L26-L31>
///
/// These were copied from the README by brew maintainers, so are also present there,
/// but repeated here *again* to have properly breaking tests in a way they cannot be
/// missed or forgotten.
///
/// Would be nice for brew to just run `cargo test`?
/// Check we don't break what I commented about [on
/// HN](https://news.ycombinator.com/item?id=41675384):
///
/// > These sorts of cases are why I wrote srgn [0]. It's based on tree-sitter too. Calling it as
/// > cat file.py | srgn --py def --py identifiers 'database' 'db'
/// >
/// > will replace all mentions of `database` inside identifiers inside (only!) function definitions (`def`) with `db`.
/// >
/// > An input like
/// >
/// > import database
/// > import pytest
/// >
/// >
/// > @pytest.fixture()
/// > def test_a(database):
/// > return database
/// >
/// >
/// > def test_b(database):
/// > return database
/// >
/// >
/// > database = "database"
/// >
/// >
/// > class database:
/// > pass
/// >
/// > is turned into
/// >
/// > import database
/// > import pytest
/// >
/// >
/// > @pytest.fixture()
/// > def test_a(db):
/// > return db
/// >
/// >
/// > def test_b(db):
/// > return db
/// >
/// >
/// > database = "database"
/// >
/// >
/// > class database:
/// > pass
/// >
/// > which seems roughly like what the author is after. Mentions of "database" outside function definitions are not modified. That sort of logic I always found hard to replicate in basic GNU-like tools. If run without stdin, the above command runs recursively, in-place (careful with that one!).
/// >
/// > Note: I just wrote this, and version 0.13.2 is required for the above to work.
/// >
/// > [0]: https://github.com/alexpovel/srgn