# `VirtualTimeMigrate.Project`
[🔗](https://github.com/d-led/gen_server_virtual_time/blob/v1.1.1/packages/gen_server_virtual_time_migrate/lib/virtual_time_migrate/project.ex#L1)

The part of both rewrite tasks that is the same: walk a tree, plan each file,
report, and write only what still parses.

`virtual_time.migrate` (GenServer → virtual-time GenServer) and
`virtual_time.upgrade` (deprecated module names → their replacements) differ
only in their planner, so the walking and the writing live here once.

# `path`

```elixir
@type path() :: String.t()
```

# `paths`

```elixir
@spec paths([String.t()]) :: [path()]
```

The paths to plan, from the `--paths` flags or the defaults.

# `pending`

```elixir
@spec pending([{path(), term()}]) :: [{path(), VirtualTimeMigrate.Edits.plan()}]
```

The files whose plan would change something.

# `plan`

```elixir
@spec plan([path()], (String.t(), MapSet.t(String.t()) -&gt;
                  {:ok, VirtualTimeMigrate.Edits.plan()} | {:error, term()})) ::
  [
    {path(),
     VirtualTimeMigrate.Edits.plan() | :unparsable | {:unreadable, term()}}
  ]
```

Plans every `.ex`/`.exs` file under `paths`.

`planner.(source, converted)` returns `{:ok, plan}` or `{:error, reason}`; the
second argument is the set of module names the whole tree converts, which only
the GenServer rewrite needs.

Returns `[{file, plan}]`, `[{file, :unparsable}]` or `[{file, {:unreadable, reason}}]`.

# `report`

```elixir
@spec report([{path(), term()}]) :: :ok
```

Prints one section per file that has something to say.

# `write`

```elixir
@spec write([{path(), VirtualTimeMigrate.Edits.plan()}]) :: :ok
```

Writes every pending plan, refusing to write one that would not parse.

A rewrite that breaks the syntax is a bug in the planner; aborting the whole
run keeps the tree compilable and makes the bug visible.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
