1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-09-19 16:38:51 +02:00
Commit graph

2103 commits

Author SHA1 Message Date
epriestley
5a4c489916 [Wilds] Use "random_bytes()" if it is available (after PHP7)
Summary:
Ref T13209. In PHP7 and newer, the function `random_bytes()` gives us simple access to cryptographic randomness across platforms. Prefer it if it's available.

Notably, the other sources often aren't available on Windows, and particularly aren't available on a clean/default install with modern software versions. So the major motivation is to make things work better out-of-the-box on Windows.

Test Plan: On Windows, saw Filesystem unit tests which call `readRandomBytes()` now pass.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13209

Differential Revision: https://secure.phabricator.com/D19726
2018-10-03 07:48:44 -07:00
epriestley
9ac0b69798 [Wilds] Sanitize UTF8 output in tsprintf(...) under Windows
Summary:
Ref T13209. In PHP, when you `echo` or `print` certain invalid sequences to the `cmd.exe` terminal under Windows 10, the entire string just vanishes into the ether.

I ran into this because `arc unit` was reporting "1 failing test" but not actually printing a test failure. That's because the failing test was the surrogate filtering test, and the test failure contained a reserved UTF16 surrogate sequence ("Expected: <filtered result>; Actual: <unfiltered result>"). See D19724.

To try to limit the damage this can cause, explicitly `phutil_utf8ize(...)` the output under Windows. When we don't //need// to do this I think it's slightly better not to (occasionally, the raw input might be useful in debugging or understanding something) which is why I'm not just doing it unconditionally.

Test Plan:
  - Wrote a script which did `echo tsprintf("%s", "<invalid surrogate sequence>");`.
  - On Windows 10 in `cmd.exe`, saw it print something instead of printing nothing.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13209

Differential Revision: https://secure.phabricator.com/D19725
2018-10-03 07:48:43 -07:00
epriestley
b192185045 [Wilds] Fix phutil_is_utf8_slowly() to reject reserved UTF16 surrogate character ranges
Summary:
Ref T13209. See T11525. We want to reject certain 3-byte characters as "invalid" unicode, primarily because `json_decode()` does not accept them.

We currently reject them correctly if we go down the fast path in `phutil_is_utf8()` via `mb_check_encoding()`, but incorrectly accept them if we go down the slow path.

Add test coverage that the slow path has the same behavior as the fast path, and then make the slow path reject these byte sequences.

Test Plan:
- Added failing tests.
- Made them pass on OSX and Windows 10.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13209

Differential Revision: https://secure.phabricator.com/D19724
2018-10-03 07:48:31 -07:00
epriestley
ee756592af [Wilds] Make "arc" survive all tests with no failures
Summary:
Ref T13098. The lint part of this barely gets all the pieces cobbled together, but all the tests do actually run now, minus a handful of skipped tests. Major ideas here:

Lint, Unit and (soon) Build are becoming "Operations" where an "Overseer" manages a list of "Engines" that read configuration from a ".arc<operation>" file, operate on a working copy, may operate on a subset of files (possibly selected by examining recent changes in the working copy), produce some kind of result (test outcomes, lint messages, build artifacts) and then the results are sent to a list of one or more "Sinks" (console display, files, Harbormaster, patchers). All three workflows share a meaningful amount of code in terms of doing most of these things in roughly the same way.

A lot of Lint logic is currently based around passing paths around as strings, then calling a lot of `$thing->getParentObject()->getInformationForPath($path_as_string)`. This tends to be pretty bulky and somewhat fragile. I'm moving toward passing an `ArcanistWorkingCopyPath $path` around instead, which has methods with a better defined scope like `$path->getData()`, `$path->getMimeType()`, `$path->isBinary()`, and so on. This requires us to build fewer objects to run tests.

`arc lint` itself won't run yet, and I don't plan to make it run for a bit (I have //some// of a patch, but it's not really there yet). Instead, I want to focus on getting coverage for existing flows (particularly `alias`) and then getting Windows support online now that it can have test coverage.

This change is less about any of what it actually does and more about powering through to make `arc unit` a useful tool for building other changes.

Test Plan:
Flawless!

{F5910428}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19716
2018-10-01 16:39:03 -07:00
epriestley
529b21844b [Wilds] Remove all linters and test cases not used by Arcanist
Summary: Ref T13098. I may restore some of these later, but this was a big obvious step in getting `arc unit` passing. I'd generally like these to live in third party libraries some day, if not immediately.

Test Plan: No failing tests after D19716.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19717
2018-10-01 16:38:20 -07:00
epriestley
22cf774ae1 [Wilds] Fix the last set of failing non-linter test cases
Summary: Ref T13098. Everything except the linter test cases now passes.

Test Plan: Ran `arc unit`, got fewer test failures.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19715
2018-10-01 16:37:00 -07:00
epriestley
a3e29773df [Wilds] Make more test cases (mostly related to the phutil -> arcanist move) pass
Summary:
Ref T13098. Makes some tests pass by updating `'phutil'` to `'arcanist'`. Skips some tests which won't pass for a while.

Also removes external test engines for now since they aren't realistically going to run for a while and they significantly complicate bootstrapping a set of passing tests out of `arc unit`.

Test Plan: Ran `arc unit`, saw fewer failures.

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: aurelijus

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19714
2018-10-01 16:36:12 -07:00
epriestley
fe8f0aea9c [Wilds] Make "Bundle" test cases pass
Summary:
Ref T13098. Continue to chip away at unit tests.

I stubbed out the read of configuration directly from `RepositoryAPI` and would like to remove it later. This is the only configuration value that `RepositoryAPI` reads directly. Instead, I suspect this will be cleaner if higher-level callers are responsible for reading and applying commit range rules and the actual `RepositorAPI` object does not know about them.

(In this particular case it's pretty moot anyway since unit tests shouldn't depend on `.arcconfig` settings.)

Test Plan: Ran unit tests, got slightly fewer failures.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19713
2018-10-01 16:35:29 -07:00
epriestley
964707ffdf [Wilds] Make "Base Commit" parser test cases pass
Summary: Ref T13098. Chip away at test cases: update the tests for `base` rule parsing for the new WorkingCopy objects.

Test Plan: Ran `arc unit`, saw fewer test failures.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19712
2018-10-01 16:34:20 -07:00
epriestley
59ef02d263 [Wilds] Rename "formatters" to "sinks" and restore the console output sufficiently to see which tests are failing
Summary:
Ref T13098. Since I plan to implement "send the results to Harbormaster" as another type of formatter/output/sink, just rename the objects which receive unit test results and print/write/transmit them into "Sinks" (in the sense of  Source/Sink).

Get the default console sink working well enough to see what's failing. As with all other changes in this series this is very rough, but the general idea is that I want to:

  - Let sinks stream both ongoing status information and final results.
  - For the console output, try to increase the signal-to-noise ratio of the output stream. Today, it's too easy to lose a failed test in the results. I want to improve this by outputting less frequently and summarizing passes ("93 tests passed.") so that the streaming output mostly shows failures and it's easier to make a decision to `^C` and revise if you see something you don't like.
  - Also, add a summary mode at the end which makes sure failures show up on the console and aren't scrolled up 30 pages. For now, this is quite rough.

Test Plan:
```
373 PASSED * 16 SKIPPED * 162 FAILED/BROKEN/UNSTABLE
```

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19711
2018-10-01 16:33:22 -07:00
epriestley
493a5d1cc7 [Wilds] Make "arc unit" run again, with many caveats
Summary:
Ref T13098. I made this change with a machete and a hacksaw. Major ideas:

The `--json`, `--ugly`, and `--output` flags are a new `--format <json|default>` flag instead. Formatters (JSON, Console) are modularized instead of being hard-coded. In a future diff, I will probably modularize this more into a general "sink/output" object and implement `--target X` ("send results to harbormaster build target X") as an output/sink, too, and then when you run `--format json --target X` we just send all the results to two outputs, and one sends them to the console while the other one uploads them.

The `--everything`, `arc unit path path path ...`, and `--rev` flags don't work yet, and `arc unit` always behaves like `arc unit --everything`. This is fine for `arcanist/` since the whole test suite currently runs in 5 seconds. I expect to restore these more or less as they previously existed later, once the working copy / repository stuff is in better shape.

The `--engine` flag is gone. This is an old flag and obsolete with `.arcunit`. `arc unit` now requires `.arcunit` to exist.

Some other flags are gone but I expect to restore them, at least in some form, later on.

Much of this barely works, but it //appears// that all the tests run, so we can start putting coverage on `arc alias`, Windows shell escaping, etc.

Test Plan: Ran `arc unit`, got something that looks like unit test results. When some of them didn't work, got failures.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19710
2018-10-01 16:29:44 -07:00
epriestley
9d66610027 (Arcanist wilds) Add setHint/getHint to PhutilLockException for recent lock changes
Summary: Ref T13202. See PHI889. See D19702. A small part of that change affected libphutil, but got lost in the shuffle with all the Arcanist/wilds stuff in my local workspace.

Test Plan: See D19702.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13202

Differential Revision: https://secure.phabricator.com/D19720
2018-10-01 10:29:09 -07:00
epriestley
12722b9ea9 [Wilds] Tailor the behavior of some unit tests which print_r($the_entire_world, true)
Summary:
Ref T13098. I've eventually made `arc unit` at least sort of run, but a few unit tests have an issue under the new code.

We have a couple of cases where we `print_r($stack, true)` or `print_r($exception, true)`, which is effectively the same because exceptions include a stack. In one case, we search in the stack for values to make sure `PhutilOpaqueEnvelope` is really masking secrets. In another case, we just use `print_r(...)` to label test cases, but some test data is exceptions.

Under the new code, the `arc unit` stack has access to a much larger "world" via variables reachable in stack frames, since it's connected to all toolsets/workflows and those objects are more deeply interconnected. This makes the output from `print_r($stack)` enormous and slow (20+ seconds) because of all the recursive referencing of complex variables.

In the case where we're looking at the stack, just print the last couple frames. Also add some positive code that searches for a known value in the stack.

In the case where we're describing variables, just drop the code. We don't really need to label these test cases, the "expect" value is sufficiently clear on its own.

Test Plan: Later, ran `arc unit` and saw it finish in a reasonable amount of time instead of hanging forever on these tests.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19709
2018-09-26 14:15:18 -07:00
epriestley
97651311bd [Wilds] Fix some minor classtree issues identified by unit tests
Summary: Ref T13098. I eventually got unit tests sort-of-almost running and they caught these two issues. Since the tests don't get very far with these classtree problems, just fix them up now so when `arc unit` actually runs later on it can meaningfully run tests.

Test Plan: Ran `arc unit`, after other changes let it run, and saw fewer "class doesn't implement every abstract method" issues.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19708
2018-09-26 14:12:42 -07:00
epriestley
4c4fd6fd23 [Wilds] Refine the working copy selection algorithm for Subversion vs Git/Mercurial
Summary:
Ref T13098. I didn't fully capture all the nuances of the old algorithm, and the behavior we want is slightly more complicated. This adjust things to try to express the more complicated behavior in a relatively clear (?) way.

When a bunch of working copies are nested inside one another, first pick the deepest one, then ask it to pick the best option among all working copies of the same type.

For Git and Mercurial repositories, just pick the deepest one.

For Subversion repositories, pick the directory with `.arcconfig` if one exists, or the shallowest directory otherwise (this could be more sophisticated, some day).

The general idea here is that if `/a` is a Git repository and `/a/b/c` is a Git repository and you run inside `/a/b/c`, that should be the working copy.

But we have to use a different rule for Subversion because //every directory// had a `.svn` directory in it until SVN 1.7.

Test Plan:
Locally, with `core/lib/arcanist/`, got `arc` to anchor to `arcanist/` instead of `core/` with the new ruleset.

(This will eventually get more extensive Subversion testing.)

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19707
2018-09-26 14:11:28 -07:00
epriestley
df2c1ba912 [Wilds] Provide a skeleton for prompt behaviors
Summary:
Ref T13098. Ref T13198. Ref T12996. The major ideas here are:

Workflows must define a list of all the prompts they can raise, so that these prompts can be enumerated with `arc prompts <workflow>`.

Prompts themselves should respond properly to ^C (abort immediately) and we should be able to make them nonblocking in the future (particularly, we'd like to be able to continue reading bytes from subprocess buffers while the prompt is shown on screen).

This doesn't have a lot of fancy features yet (non-confirm prompts, default yes, prompts which don't abort on "N", etc) but those should be easy to add later.

In the future, you'll be able to configure a default answer to prompts either in a config file or at runtime with `--config prompts=x.y.z=N` or similar.

This removes the history/readline mode for prompts, where you could use the up arrow to cycle through older responses. I believe this was only really useful for "excuse" prompts and intend to remove those.

Test Plan:
Forced `arc shell-complete` to always prompt, then:

  - Got prompted, answered "y", "n", "N", "", "quack". Got sensible behavior in all cases.
  - Ran `echo | arc shell-complete`, got a TTY error.
  - Ran `arc prompts`, `arc prompts shell-complete`.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098, T13198, T12996

Differential Revision: https://secure.phabricator.com/D19706
2018-09-26 14:08:49 -07:00
epriestley
a62c1d70db [Wilds] Handle SIGINT (^C) in ArcanistRuntime in a more formal way
Summary:
Ref T13098. Add ^C handling and some small bits:

  - Update `arc weld`.
  - Test that `arc weld filen<tab>` completes `filename` (it does).
  - Add a "workflow stack" -- I plan to make it easier for `arc diff` to call `arc unit` / `arc lint` as formal sub-workflows, etc., and make "workflow X delegates to workflow Y" a more formal thing.

On interrupts:

  - Workflows can do something when you press ^C.
  - If they do, press ^C twice quickly to exit.
  - Otherwise, we exit on the first ^C.

The major thing I'd like to do in the short-ish term is to make `phage` report status on interrupt, but some other workflows might make sense to have interrupt handlers (maybe long-running stuff like `arc upload` / `arc download`) and third parties may find creative uses for them.

Test Plan:
- Added some `sleep(...)` to WeldWorkflow.
- Interrupted, got program exit.
- Added interrupt handlers and interrupted, got interrupt handling.
- With interrupt handlers, interrupted twice. Got program exit.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19703
2018-09-26 14:07:25 -07:00
epriestley
afcaeea9c3 [Wilds] Shell complete files with spaces in them correctly
Summary: Fixes T9116. Ref T13098. Fix shell completion handling of filenames with spaces in them. This is a big mess -- see T9116 for discussion and I'll walk through things below.

Test Plan:
These all now seem to do the right thing:

```
arc we<tab> -> arc weld (+space)
arc weld fo<tab> -> arc weld foo\ bar (+space)
arc weld 'fo<tab> -> arc weld 'foo bar' (+space)
arc weld src<tab> -> arc weld src/ (no space)
arc weld src/w<tab> -> arc weld src/work (no space)
arc weld src/work<tab><tab> -> suggests "workflow/", "workingcopy/"
arc shell-complete --gen<tab> -> arc shell-complete --generate
```

These also work, which I think is nice-to-have:

```
arc WEL<tab> -> arc weld
arc shell-complete --GEN<tab> -> arc shell-complete --generate
```

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098, T9116

Differential Revision: https://secure.phabricator.com/D19705
2018-09-25 16:15:51 -07:00
epriestley
50dfc9cc41 [Wilds] Update "arc shell-complete" for toolsets
Summary:
Ref T13098. Major changes:

`arc shell-complete` now installs itself to your `~/.profile`. Running `arc shell-complete` again will update the hook and update the completion rules.

Completion rules work for all toolsets, so you can install once and then autocomplete in `arc`, `phage`, etc.

This code supports other shells in theory, and I developed most of it with ZSH support next to the Bash support. However, while actually testing ZSH support, I couldn't get it to even slightly work and found myself falling down a very, very deep rabbit hole of ZSH being entirely written in bash script and `${0🅰️h}` being a legitimate script construction. The existing ZSH support comes from one guy in 2012 and also does not work for me on `master`, so I ultimately removed it. Open to restoring it but I wasn't able to figure it out in 10 minutes of Googling and I'm not convinced it's worth 11 minutes of Googling.

I left a few rough edges here with notes on how to improve/fix them, but the basics all work.

Test Plan:
- Ran `arc shell-complete` under various stages of `~/.profile`, couldn't get it to do anything bad.
- Ran `arc lib<tab>`, `arc shell-complete --curr<tab>`, etc. Got sensible suggestions and completions.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19700
2018-09-25 16:02:13 -07:00
epriestley
b6f93a46d7 [Wilds] Shove the logging stuff into a bit of an abstraction before it gets out of control
Summary:
Ref T13098. The logging stuff is starting to get a little sketchy, so wrap it in several layers of class-based indirection before it can escape its cage.

This at least gives us an actual API and structure to work with later instead of scattering a lot of `fprintf(STDERR, ....)` all over the place.

Test Plan: Ran a few commands, got slightly more sensible/consistent logging out of them.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19699
2018-09-25 15:59:44 -07:00
epriestley
e6c37bd4b3 [Wilds] Make "arc call-conduit ..." call Conduit methods
Summary:
Ref T13098. This repairs Conduit integration. Conduit was meaningfully updated in the `experimental` branch so a lot of this is just deleting code I don't plan to support going forward.

This removes "conduit.timeout", "http.basicauth.user" and "http.basicauth.pass". I believe these were all crazy niche calls with essentially no legitimate use. We could provide extension support if anyone actually uses this stuff, now.

Fixes an old "phutil" reference in HTTPSFuture.

Builds Conduit engine support into `ArcanistWorkflow`. There's perhaps some argument for trying to not make this core, but every upstream thing we'll ever write probably wants it (`arc`, `phage`) and there's not much of a cost to making it core. Even non-core stuff may include extensions which expect Conduit support (for example, for reporting workflow metrics to Phabricator).

There's no authentication support yet, I'm planning to update "hosts" config handling next.

Test Plan:
```
$ echo '{}' | arc call-conduit conduit.ping
 WARNING  Ignoring unrecognized configuration option ("hosts") from source: User Config File (/Users/epriestley/.arcrc).
 WARNING  Ignoring unrecognized configuration option ("load") from source: Project Config File (/Users/epriestley/dev/core/.arcconfig).
{
  "error": null,
  "errorMessage": null,
  "response": "secure001.phacility.net"
}
```

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19698
2018-09-25 15:58:29 -07:00
epriestley
5e70719306 [Wilds] Continue toward a generalized "arc alias" workflow
Summary:
Ref T13098. This leaves a lot of rough edges but nothing is overtly broken so here's where we're at so far:

Config sources get "scopes", like user configuration vs system configuration. The major reason for this is so that `arc set-config x y` can know where it's supposed to write. This is generalized enough that we can implement `arc set-config --system ...` and `arc alias --local ...` and so on relatively easily later, although scopes themselves are not modular (a third-party can't add a new type of config scope). Maybe we'll modularize this some day but it felt like that's probably YAGNI/overboard since we have no current use cases. For now, a source does not need to belong to any particular scope.

Config may be writable (like user config in `~/.arcrc`) or nonwritable (like `--config` flags). Writable config can now specify how to write to disk. Config files can actually write to disk now, although the only pathway for doing this that exists is via `arc alias`.

Aliases now parse properly and can write to disk. `arc alias` now lets you define aliases, and writes them to disk. **The first time you do this, your `~/.arcrc` file will be rewritten into a format which old `arc` can not read!** It's relatively easily to unmangle/repair these files so I'm planning to just let this happen.

When a toolset is invoked, it now reads and evaluates aliases. Aliases have a lot of new guard rails like suggesting the user try `arc draft` if they type `phage draft`, allowing alias chains, detecting cycles, and limiting chain length.

Workflows can provide help and argument lists in a more structured way. I've moved this to sub-objects: help is now on `WorkflowInformation` (instead of a bunch of different `getHelp()`, `getSynopsis()` methods) and arguments now have a `WorkflowArgument` object instead of a dictionary. I think this pattern is generally better for extending: it lets us add and change stuff with less impact (and greater explicitness) down the road.

`arc alias` now has reasonable help text and argument documentation. The `arc alias` (list) and `arc alias x` (details/remove) flows don't work yet but `arc alias x y` does.

`arc liberate` now uses the new help/argument stuff, although the help needs more beef eventually. I pruned a bunch of long-obsolete or questionable flags and renamed `--all` to `--clean` since `--all` sounds like "liberate all libraries", which is now the default behavior of `arc liberate`.

Test Plan:
You can now define chains of aliases. Finally!

```
$ arc draft4
 WARNING  Ignoring unrecognized configuration option ("hosts") from source: User Config File (/Users/epriestley/.arcrc).
 WARNING  Ignoring unrecognized configuration option ("load") from source: Project Config File (/Users/epriestley/dev/core/.arcconfig).
 ALIAS  arc draft4 -> arc draft3
 ALIAS  arc draft3 -> arc draft2
 ALIAS  arc draft2 -> arc diff
Usage Exception: Unrecognized argument '--draft'.
```

This also works now:

```
$ phage alias deploy-secure -- deploy --hosts secure001-4 --limit 1
```

General!

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19697
2018-09-25 15:57:22 -07:00
epriestley
5ef6599239 [Wilds] When reading ".arcrc" files, modernize the data we read in-process if they're in an older format on disk
Summary:
See T13098. All ".arcconfig" files except "~/.arcrc" have config keys at top level.

"~/.arcrc" previously had "aliases" at top level, and currently has "hosts" at top level. "aliases" became standard configuration. I'd like to make "hosts" standard configuration too -- one reason to do this is to make automation with `--config-file` easier, so you can shove API tokens in a file somewhere (and not need a home directory). Another reason is just to standardize things.

If we read "~/.arcrc" and see a "config" key, put all those keys at top level and then fill in anything else left over so we end up with `~/.arcrc` that effectively looks like other "arcconfig" files. I'd possibly like to rename this file to "arcconfig" at some point, too, but that can happen later.

Test Plan: Ran `arc get-config`, which barely works, but now read my `~/.arcrc` somewhat more successfully.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D19696
2018-09-21 17:00:20 -07:00
epriestley
c64f86c2f6 [Wilds] Flesh out most of the new Config objects
Summary:
Ref T13098. This is pretty rough, but sketches out the general shape of a more modern configuration flow. The new flow is very similar to the Phabricator flow.

Each configuration option is typed (string, bool, list of dictionaries, etc) so we can typecheck it, and each type is a class so the types are modular and can do fancy stuff. Some of this "fancy stuff" that I want to do includes:

  - transparently rewriting/reformatting various options for modernness/consistency;
  - having some options exposed as objects instead of raw JSON values (in particular, aliases);
  - merging "list" options (like "aliases") in a modular way instead of by having hard-coded stuff that says "this particular option is magic gets merged instead of getting replaced when defined in multiple places".

Generally, this makes everything modular and extensible and gets rid of the hard-coded `switch (...)` stuff.

Test Plan: Ran `arc get-config`, it sort of almost worked.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19695
2018-09-21 16:57:57 -07:00
epriestley
23aaf85eaf [Wilds] Allow class loading to continue on failure
Ref T13098. I think I didn't turn this into an actual revision, but let
`ClassMapQuery` optionally continue if it encounters a class load failure.

If we don't allow this, it can become very difficult to modify or remove
some Arcanist classes since when you, say, remove a Workflow you can no
longer make it to "arc liberate" to update the map for the change.

This is currently used in roughly one place (in an upcoming diff) to let us
get through startup in Runtime and into the "liberate" workflow.
2018-09-21 16:56:36 -07:00
epriestley
412484022b [Wilds] Prepare for more modular configuration management
Summary:
Ref T13098. This is kind of a catch-all diff with stuff that didn't fit in prior diffs, and which fixes some bugs with that stuff now that I made it at least sort of reachable.

Beyond bugs, the general idea is to replace `ConfigurationManager` (a big class which knew about config-end-to-end) with a more modern/modular `ConfigurationEngine` using the standard Engine + EngineExtension modularity pattern.

Configuration becomes a `ConfigurationSourceList` of `ConfigurationSource` objects, each of which represents one source (a config file, `--config x=y`, etc). The various sources will have the logic to parse values (e.g., decode `x=y` flags or JSON files on disk). A new `--config-file` allows you to replace the system (`/etc/arcconfig`) and user (`~/.arcrc`) files.

This also gets rid of `--library` support entirely for now since it's kind of messy to bridge until Config works. I expect to either restore it or replace it with `arc install` and similar.

Test Plan: Ran `arc liberate`; it actually works now. (The Config stuff does not actually work yet.)

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19694
2018-09-21 16:54:00 -07:00
epriestley
11599cedb6 [Wilds] Implement a Filesystem::concatenatePaths(...) method
Summary:
Ref T13098. This is mostly for getting sensible results under Windows, hopefully instead of weird mixed paths with both `/` and `\`, at least in more cases.

You can pass in several components like `array('/path/to/something/', '/thing.c')` and they'll be concatenated with exactly one correct separator.

Test Plan: Used this in the new `WorkingCopy` stuff, which doesn't run yet. 💁

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19691
2018-09-21 16:52:38 -07:00
epriestley
c05bbd7be6 [Wilds] Allow "arc liberate" to liberate itself again
Summary:
Ref T13098. After libphutil/ and arcanist/ merged, some paths need to be adjusted. Try to organize things a little better, too.

Also, make `arc liberate` with no arguments just liberate all the libraries it can find.

Test Plan: Ran `arc liberate` and got a valid map rebuild, although I needed to apply some hacks on top of this to make the workflow reachable.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19690
2018-09-21 16:50:58 -07:00
epriestley
d936257018 [Wilds] Rewrite WorkingCopyIdentity in a more modern/modular way
Summary:
Ref T13098. Currently, `WorkingCopyIdentity` has rules for finding `.git/.svn/.hg` directories and `.arcconfig` files. It also has a ton of logic for reading and writing config files.

Generally:

  - Rename `WorkingCopyIdentity` to `WorkingCopy`.
  - Make it an abstract base with `Git`, `Mercurial` and `Subversion` subclasses, using the standard module/extension pattern.
  - Throw out almost all of the config file logic. This logic is going to move into Config classes. It is not unique to working copies.
    - Working copies retain the actual bit of this they need: knowing where stuff should go on disk.

This doesn't run yet, but sure looks a lot cleaner!

Test Plan: Doesn't run yet, since Config isn't working yet.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19689
2018-09-21 16:48:00 -07:00
epriestley
9a94aa216b [Wilds] Slightly simplify fatal handling during "arc" setup
Summary:
Ref T13098. We currently handle fatals by printing a message and returning an error code, since this was the most direct adaptation from the old `arcanist.php` script.

Instead, throw an exception and then handle it above, since we can reasonably do that in one place now.

Test Plan: Ran `arc`.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19693
2018-09-21 16:46:05 -07:00
epriestley
fe0c293895 [Wilds] Remove include_path mangling and drop support for "externals/includes"
Summary:
Ref T13098. This logic comes from D3243 and was theoretically used to let you install `libphutil` with Homebrew. Since libphutil no longer exists and the other use cases I can come up with are questionable/obsolete, remove it.

(As we move into T5055, I expect to provide better tools for bundling/managing external dependencies.)

Test Plan: Ran `arc`, same as the old `arc`.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19692
2018-09-21 16:44:11 -07:00
epriestley
8e0e07664a [Wilds] Remove libphutil
Summary:
Ref T13098. Historically, Phabricator was split into three parts:

  - Phabricator, the server.
  - Arcanist, the client.
  - libphutil, libraries shared between the client and server.

One imagined use case for this was that `libphutil` might become a general-purpose library that other projects would use.

However, this didn't really happen, and it seems unlikely to at this point: Phabricator has become a relatively more sophisticated application platform; we didn't end up seeing or encouraging much custom development; what custom development there is basically embraces all of Phabricator since there are huge advantages to doing so; and a general "open source is awful" sort of factor here in the sense that open source users often don't have goals well aligned to our goals.

Turning "arc" into a client platform and building package management solidify us in this direction of being a standalone platform, not a standalone utility library.

Phabricator also depends on `arcanist/`. If it didn't, there would be a small advantage to saying "shared code + client for client, shared code + server for server", but there's no such distinction and it seems unlikely that one will ever exist. Even if it did, I think this has little value.

Nowadays, I think this separation has no advantages for us and one significant cost: it makes installing `arcanist` more difficult for end-users.

This will need some more finesssing (Phabricator will need some changes for compatibility, and a lot of stuff that still says "libphutil" or "phutil" may eventually want to say "arcanist"), and some stuff (like xhpast) is probably straight-up broken right now and needs some tweaking, but I don't anticipate any major issues here. There was never anything particularly magical about libphutil as a separate standalone library.

Test Plan: Ran `arc`, it gets about as far as it did before.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19688
2018-09-21 16:38:53 -07:00
epriestley
f0608eef9b [Wilds] Remove the defunct "scripts/arcanist.php" script
This is now ArcanistRuntime, etc. I neglected to turn this into a revision but
it isn't a very interesting change.
2018-09-21 16:03:06 -07:00
epriestley
d8f660ec6f [Wilds] Move ArcanistRuntime to support/ArcanistRuntime.php
Summary:
Ref T13098. Currently, it lives in `init-script.php`. Move it to a separate file for similarity with `support/PhabricatorStartup.php`.

Two small changes here:

  - `dirname(dirname(...))` adjustments for new path.
  - Remove `memory_limit(-1)`, this is adjusted by the libphutil init script already.

Test Plan: Ran `arc`.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19687
2018-09-21 16:00:30 -07:00
epriestley
d62830195c [Wilds] Rename "--load-phutil-library" to "--library" in new arc
Summary: Ref T13098. The name of this option is needlessly obscure/verbose, and we now require it come first so it should be unambiguous even if we add `arc borrow-a-book` later.

Test Plan: Grepped for `--load-phutil-library`.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19686
2018-09-21 15:59:25 -07:00
epriestley
baadc1f842 [Wilds] Sort of make "arc help" work again
Summary:
Ref T13098. This makes "arc help" kind-of sort-of work again.

Previously, "arc help" was completely custom and hard-coded. Now it just proxies the generic libphutil "help" workflow. The two flows are substantially similar, although old `arc help` was a little more brief than the new version is. The old `arc help --full` was more similar to the default:

| Command | Old Behavior | New Behavior |
|---|---|---|
| `arc` | Tells you to run `arc help`. | Plan: make this a bit richer and give a quick summary of workflows. |
| `arc help` | Gives you a summary of workflows. | Gives you a detailed list of workflows. |
| `arc help --full` | Gives you a detailed list of workflows. | No such flag. |
| `arc --help` | Same as `arc help`. | Same as `arc`. Plan: same as `arc help`. |
| `arc help <workflow>` | Full workflow help. | Full workflow help. |
| `arc <workflow> --help` | As above. | As above. |

Overall this is largely the same and lets us delete a bunch of code.

Test Plan:
Ran `arc`, `arc help`, `arc --help`, `arc --help diff`, `arc diff --help`, `arc help diff`, `arc help help`.

These commands largely do something sensible now, with caveats per above.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19679
2018-09-21 15:58:35 -07:00
epriestley
8e51f89c79 [Wilds] Make "arc liberate" run in the untamed wilds
Summary:
Depends on D19677. Ref T13098. This gets enough of the new workflow/toolset stuff running to run `arc liberate` (without arguments) so that the new `arc` can bootstrap itself to continue development.

This change also moves some workflows which will be shared across toolsets (shell completion, versions, help, aliases) out of being `arc`-specific, to varying degrees of success. These workflows will need to be revisited and cleaned up so they work properly. They mostly fatal when run right now.

The Conduit flags have moved to the new `arc` parent workflow, but they'll likely move to some kind of support object so `my-company-thing megadiff` can accept Conduit flags. This is a more involved change, however.

Test Plan: Ran `arc liberate`, got the Wilds `arc` to rebuild its own map. Everything else crashes!

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19678
2018-09-21 15:57:36 -07:00
epriestley
7d05dbec15 [Wilds] Rewrite "arc" entrypoints for toolsets
Summary:
Ref T13098. Depends on D19675. This change is headed to the `untamed-wilds` branch.

This change prevents `arc` from running `arc diff`, so I'm copy/pasting it.

This change also completely breaks `arc`, but I'm just generally trying to do this rewrite step-by-step so we have at least a bit of context to refer to in the future.

The major change here is to turn both `arc` and `phage` into scripts which start an `ArcanistRuntime`. This runtime then decides which workflows (like "diff", "patch", or "remote") are available based on `$argv[0]`. This turns `arc` into more of a CLI tools platform: we can build `phage` on it, third parties can build `my-companion-tool-thing`, etc. But all the different entry points can share a lot of infrastructure like: `help`, `alias`, shell-complete, configuration, Conduit, prompting, `--trace`, extension infrastructure, and so on.

`ArcanistRuntime` is roughly a slightly more modern version of `scripts/arcanist.php`. That will be removed eventually, but not everything has ported yet.

Test Plan: This code basically doesn't run yet, although the next patch runs at least a little bit.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13098

Differential Revision: https://secure.phabricator.com/D19677
2018-09-21 15:55:08 -07:00
epriestley
9d59e9e590 Merge branch "master" into "experimental". 2018-08-24 17:44:52 -07:00
epriestley
e1e93271e6 Make the ArcanistBundle algorithm do what "diff -u" does when hunks are arguably mergeable
Summary:
Ref T13187. See PHI838. If two hunks are separated by 7 lines of context, we can render them as either:

```lang=diff
+ Hunk A
  Context 1
  Context 2
  Context 3
  Context 4
  Context 5
  Context 6
  Context 7
+ Hunk B
```

...or:

```lang=diff
+ Hunk A
  Context 1
  Context 2
  Context 3
@@ +1,2 -3,4 @@
  Context 5
  Context 6
  Context 7
+ Hunk B
```

Since we get the same number of output lines either way and the first one is more human-readable, we picked that one.

However, `diff -u` does the second one. Since human-readability is probably less important than compatibility, change the behavior to be more similar to `diff -u`.

Test Plan: Added unit tests for the edge cases with default parameters (6 context lines, 7 context lines) and made them pass.

Reviewers: amckinley

Maniphest Tasks: T13187

Differential Revision: https://secure.phabricator.com/D19603
2018-08-24 11:00:16 -07:00
epriestley
d9a4293ae7 Consolidate redundant "should should" from some linter help strings in Arcanist
Summary: See <https://phabricator.wikimedia.org/T201138>.

Test Plan: Read carefully.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D19561
2018-08-03 14:36:41 -07:00
Aviv Eyal
875d018360 Fix arc diff when adding large new file with new git
Summary:
See https://discourse.phabricator-community.org/t/arc-not-supporting-git-2-17-1/.
When treating it a large file  binary, we try to get the "old" and "new" content using `git ls-tree` and `cat-file`.
If the file is new or deleted, there is no old file, so we try to work with filename `null`.

Under git < 2.17.1, that gets treated as `git ls-tree -- .`, which falls in the next condition under "no such path".
In git 2.18, etc, this is an error.

Explicitly bail out if there is no filename.

Test Plan: Add a new, large (>4Mb) file, arc diff.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D19513
2018-07-09 17:59:15 +00:00
epriestley
222800a86e Parse Mercurial changeset evolution "instability" log field
Summary: See PHI718. Modern Mercurial with the "evolve" extension enabled may emit this field.

Test Plan: As D19262.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D19498
2018-06-19 16:15:30 -07:00
epriestley
c1b1e69b8f Merge branch "master" into "experimental". 2018-06-07 12:03:15 -07:00
epriestley
df7313bdf2 In "arc patch", update submodules slightly later
Summary:
Ref T13151. See PHI648. With `arc patch --nobranch`, we update submodules a little too early.

I //believe// it is safe to just update them a little later, after the intermediate branch management logic runs.

Test Plan: Ran `arc patch --nobranch`, saw submodule update run later. Not 100% sure this doesn't cause weird issues, but I can't anticipate any.

Reviewers: amckinley, jmeador

Reviewed By: jmeador

Maniphest Tasks: T13151

Differential Revision: https://secure.phabricator.com/D19475
2018-06-07 12:03:08 -07:00
Tim McJilton
b199ca8086 [ARCUNIT] Set the ConfigurationManager of ConfigurationDrivenUnitTestEngines
Summary:
The Configuration Manager is supported by ArcanistUnitTestEngine but not support by the ArcanistConfigurationDrivenUnitTestEngine.

Added the configuration manager as one of the initially set properties of an ArcUnitTestEngine created by the ArcanistConfigurationDrivenTestEngine

Test Plan: Ran arc unit against a project without the change, verified the Configuration was none. Added this change and ran again and verified it was set

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D19465
2018-06-05 20:58:47 +00:00
epriestley
1a451a2e9a Merge branch "master" into "experimental" 2018-06-01 14:58:53 -07:00
epriestley
d581c453b8 Allow diff generation via ArcanistBundle to be limited to an approximate maximum byte size
Summary:
Ref T13137. See PHI592. When you have a diff with 600MB of videos, we want to bail out of diff generation early (as soon as we realize what we're dealing with), not build an 800MB text diff in memory and then throw it away.

Support bailout //during// diff generation once we realize we're in over our heads.

This is approximate, but since the limit is fairly large (512KB by default) it isn't too important to be precise.

Test Plan: Rigged some callers to set various byte limits, generated diffs including diffs with large binaries. Got an appropriate diff or exeception depending on how low the limit was.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13137

Differential Revision: https://secure.phabricator.com/D19444
2018-05-14 09:09:06 -07:00
epriestley
a1aec701e3 Raise the intraline diff hard limit from 80 to 100 characters
Summary: Fixes T1246. See PHI637. See T13137. Computers have gotten a bit faster so we can probably bump this up a little and see if it causes problems. This is `O(N^2)` so the this should be less than twice as expensive in the worst case.

Test Plan:
Created a diff affecting characters on a very long line separated by more than 80 but fewer than 100 characters, got a good intraline diff out of it:

{F5605162}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T1246

Differential Revision: https://secure.phabricator.com/D19442
2018-05-09 13:38:20 -07:00
epriestley
290821d3f2 (experimental) Merge branch "master" into "experimental". 2018-04-30 11:40:15 -07:00