Skip to content

Commit 0f0ec1f

Browse files
committed
Heavily update the documentation.
1 parent 448755c commit 0f0ec1f

File tree

2 files changed

+62
-17
lines changed

2 files changed

+62
-17
lines changed

README.md

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,74 @@
11
# depub: minimise visibility
22

3+
## Overview
4+
35
When working on medium or large sized Rust code bases, it can be hard to know
46
whether the visibility of functions, structs, and so on are still at the
57
minimum required. For example, sometimes functions that once needed to be `pub`
6-
now only need to be `pub(crate)`.
8+
now only need to be `pub(crate)`, `pub(super)`, or simply private.
9+
10+
`depub` minimises the visibility of such items in files passed to it, using a
11+
user-specified command (e.g. `cargo check`) as an oracle to tell if its
12+
reduction of an item's visibility is valid or not. In essence, `depub` does a
13+
string search for `pub`, replaces it with `pub crate` and sees if a test
14+
command still succeeds. If it does, it keeps that visibility, otherwise it
15+
replaces with the original and tries the next item. Note that `depub` is
16+
inherently destructive: it overwrites files as it operates, so do not run it on
17+
source code that you do not want altered!
18+
19+
The list of visibilities that `depub` considers is, in order: `pub`,
20+
`pub(crate)`, `pub(super)`, and private (i.e. no `pub` keyword at all). `depub`
21+
searches for `pub`/`pub(crate)`/`pub(super)` instances, reduces their
22+
visibility by one level, and tries the oracle command. If it succeeds, it tries
23+
the next lower level until private visibility has been reached.
24+
25+
Since reducing the visibility of one item can enable other items' visibility to
26+
be reduced, `depub` keeps running "rounds" until a fixed point has been
27+
reached. The maximum number of rounds is equal to the number of visible items
28+
in the code base, though in practise 2 or 3 rounds are likely to be all that is
29+
needed.
730

8-
`depub` minimises the visibility of such elements in a code base: in essence,
9-
it does a string search for `pub`, replaces it with `pub crate` and sees if a
10-
test command still succeeds. If it does, it keeps that visibility; otherwise it
11-
tries the next in the list. As this suggests, `depub` is destructive: it
12-
overwrites files, so do not run it on source code that you do not want altered!
1331

14-
For example, if you want to reduce visibility of a normal build, `cd` to your
15-
Rust code base and execute:
32+
## Usage
33+
34+
`depub`'s usage is as follows:
1635

1736
```
18-
$ /path/to/depub -- -c "cargo check"
37+
depub -c <command> file_1 [... file_n]
1938
```
2039

21-
The string specified with `-c` is passed straight to `/bin/sh` so can be any
22-
shell command. If you want to test multiple features you might use:
40+
where `<command>` is a string to be passed to `/bin/sh -c` for execution to
41+
determine whether the altered source code is still valid.
42+
43+
To reduce the visibility of a normal Rust project, `cd` to your Rust code base
44+
and execute:
2345

2446
```
25-
$ /path/to/depub -- -c "cargo check && cargo check --features f1"
47+
$ find . -name "*.rs" | \
48+
xargs /path/to/depub -c "cargo check && cargo check --test"
2649
```
2750

2851
`depub` informs you of its progress. After it is finished, `diff` your code
29-
base, and accept those of its recommendations you think appropriate.
52+
base, and accept those of its recommendations you think appropriate. Note that
53+
`depub` currently uses string search and replace, so it will merrily change the
54+
string `pub` in a command into `pub(crate)` -- you should not expect to accept
55+
its recommendations without at least a cursory check.
56+
57+
58+
## Using with libraries
59+
60+
Running `depub` on a library will tend to reduce all its intentionally `pub`
61+
functions to private visibility. You can weed these out manually after `depub`
62+
has run, but this can be tedious, and may also have reduced the visibility of a
63+
cascade of other items.
64+
65+
To avoid this, use one or more users of the library in the oracle command as part
66+
of your oracle. Temporarily alter their `Cargo.toml` to point to the local
67+
version of your libary and use a command such as:
68+
69+
```
70+
$ find . -name "*.rs" | \
71+
xargs /path/to/depub -c " \
72+
cargo check && cargo check --test && \
73+
cd /path/to/lib && cargo check && cargo check --test"
74+
```

src/main.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ enum PubKind {
1515
Private,
1616
}
1717

18-
fn process(cmd: &str, p: &Path) -> u64 {
18+
fn process(oracle_cmd: &str, p: &Path) -> u64 {
1919
let pub_regex = RegexBuilder::new("pub(?:\\s*\\(\\s*(.*?)\\s*\\))?")
2020
.multi_line(true)
2121
.build()
@@ -61,7 +61,7 @@ fn process(cmd: &str, p: &Path) -> u64 {
6161
write(p, &try_txt).unwrap();
6262
match Command::new("sh")
6363
.arg("-c")
64-
.arg(cmd)
64+
.arg(oracle_cmd)
6565
.stderr(Stdio::null())
6666
.stdout(Stdio::null())
6767
.status()
@@ -115,15 +115,15 @@ fn main() {
115115
usage();
116116
}
117117

118-
let cmd_str = matches.opt_str("c").unwrap();
118+
let oracle_cmd = matches.opt_str("c").unwrap();
119119
let mut round = 1;
120120
loop {
121121
println!("===> Round {}", round);
122122
let mut changed = false;
123123
for p in &matches.free {
124124
print!("{}: ", p);
125125
stdout().flush().ok();
126-
let num_changed = process(cmd_str.as_str(), &Path::new(&p));
126+
let num_changed = process(oracle_cmd.as_str(), &Path::new(&p));
127127
if num_changed > 0 {
128128
print!(" ({} elements depub'ed)", num_changed);
129129
changed = true;

0 commit comments

Comments
 (0)