Commit Graph

1269 Commits

Author SHA1 Message Date
Jun Wu
2e640ac84f dag: add SpanSet::push
Summary:
This is the mutable operation that allows other code paths to add spans to a
SpanSet. It will be used in a later change.

Reviewed By: markbt

Differential Revision: D17169483

fbshipit-source-id: be9286e67bfa64e961ee75482432aa61dfc0e6ed
2019-09-13 19:30:59 -07:00
Xavier Deguillard
6b6701fdc2 edenapi: remove unecessary tokio dependency
Summary: This is no longer used, let's remove it.

Reviewed By: quark-zju

Differential Revision: D17337442

fbshipit-source-id: 2272c2662440bc2be2a3ff29ef11fc4e0eb3605f
2019-09-13 15:16:57 -07:00
Xavier Deguillard
3e1eccd586 replace std::sync{Mutex, RwLock, Condvar} with parking_lot
Summary:
The parking_lot crate is more convenient to use than std::sync, on top
of everything else listed at https://crates.io/crates/parking_lot. Let's
use it everywhere.

Reviewed By: quark-zju

Differential Revision: D17337444

fbshipit-source-id: b5489be0b7d2bd5f6a6edc5d1d6eea366a6c05b9
2019-09-13 15:16:57 -07:00
Arun Kulshreshtha
f1b2353793 manifest: move test helpers to new testutil module
Summary: Now that several of the submodules in the Manifest crate have their own unit tests, let's de-duplicate the test helper functions across those tests by moving them to a `testutil` submodule (which only gets built in `cfg(test)`).

Reviewed By: xavierd

Differential Revision: D17352890

fbshipit-source-id: 1b7d7cb754ee501def8d1d508f2af5733d548f4d
2019-09-12 18:28:44 -07:00
Arun Kulshreshtha
83a5a1565b manifest: move diff tests into diff module
Summary: Previously, all of the tests for the manifest code were at the top level of this module. The BFS diff module added it own unit tests; for symmetry with this, let's move the tests for the DFS diff into that submodule.

Reviewed By: xavierd

Differential Revision: D17352889

fbshipit-source-id: 9c1685344656d0b2b5af6495bba67929f47d578f
2019-09-12 18:28:44 -07:00
Arun Kulshreshtha
6448c23a63 manifest: move File and Directory out of BFS module
Summary: These structs are generally useful when writing code that traverses manifests. As such, let's move them out of the BFS module into the top level of the tree module so that other code can use them.

Reviewed By: xavierd

Differential Revision: D17352891

fbshipit-source-id: b390ec84a29604dc6eef31a95dba976a5224f5e9
2019-09-12 18:28:43 -07:00
Arun Kulshreshtha
960c151540 manifest: move diff into own module
Summary: For symmetry with the BFS diff implementation, move the DFS diff implementation into its own module. This will help unclutter mod.rs.

Reviewed By: xavierd

Differential Revision: D17352892

fbshipit-source-id: 61709cd3e430c8676c529fbbbb76a9775c05053d
2019-09-12 18:28:43 -07:00
Arun Kulshreshtha
980bcdd0f8 manifest: add bfs diff to bindings crate
Summary: Add support for calling the new BFS diff implementation from Python. This diff adds the appropriate glue code to the bindings crate and adds a config option (`treemanifest.bfsdiff`) to enable the new functionality.

Reviewed By: xavierd

Differential Revision: D17334739

fbshipit-source-id: 24aac21910e74a42d625c93bed7fa3aa08e167c0
2019-09-12 18:28:43 -07:00
Xavier Deguillard
e79a440ca6 revisionstore: reduce max IndexedLog{History,Data}Store logs
Summary:
On WWW, an `hg update` ends up writing ~15GB worth of data onto the
IndexedLogDataStore, which eats up their precious RAM. As a quick workaround,
let's reduce the max number of logs from 10 down to 4, and increase the size of
each log to keep the total expected size around ~10GB.

Ideally, both these values should be able to configured within the hg config,
but since the IndexedLog is written within hg_memcache_client, we would have to
plumb the values onto it. Medium term, hg_memcache_client will be folded into
hg itself, and this change will be much easier by then.

Do the same for the IndexedLogHistoryStore.

Reviewed By: quark-zju

Differential Revision: D17354856

fbshipit-source-id: 0a75953f40e1982eaf43557f7866f089873300db
2019-09-12 17:31:29 -07:00
Arun Kulshreshtha
467f602d64 remotefilelog: add prefetch method to remotetreestore
Summary: Add a prefetch method to the `remotetreestore` in the `treemanifest` extension, along with the necessary plumbing to call it from Rust code.

Reviewed By: quark-zju

Differential Revision: D17335773

fbshipit-source-id: 2b71638f56ea7e1398348f437d737a599d8be476
2019-09-12 10:24:46 -07:00
Arun Kulshreshtha
95fe3c583a manifest: add matcher support to bfs diff
Summary: Add matcher support for BFS diff, bringing feature parity with the non-BFS implementation.

Reviewed By: xavierd

Differential Revision: D17276969

fbshipit-source-id: f63194508e10950a691df0202a68211e2876f742
2019-09-12 10:24:46 -07:00
Arun Kulshreshtha
76e31ae145 manifest: add initial bfs diff implementation
Summary: This diff provides an implementation of the diff operation for trees which processes directories in BFS order (i.e., layer by layer). This allows the iterator to perform a bulk prefetch of the changed nodes in each layer at the start of each layer of the traversal. This should hopefully provide a more efficient fetch pattern than the existing implementation, which requires a full prefetch of both trees upfront for reasonable performance.

Reviewed By: xavierd

Differential Revision: D17276971

fbshipit-source-id: 284f1d458f43cb76befe27e85f53a641f29d7550
2019-09-12 10:24:46 -07:00
Arun Kulshreshtha
dbf37904d4 manifest: add prefetch method to store interface
Summary:
Add a `prefetch` method to the `TreeStore` trait. This will be used by code using the store to signal that certain keys will be accessed soon. The default implementation is a no-op, but in the case of stores where prefetching makes sense (such as stores backed by remote servers), the default implementation can be overridden to include the appropriate prefetching logic.

For now, this change is a no-op, but later in this stack it will be used to signal to the underlying Python data store to perform the appropriate tree fetches via the Eden API. This will be used to support a more efficient pattern of bulk tree fetches during the diff operation.

Reviewed By: sfilipco

Differential Revision: D17276970

fbshipit-source-id: 22a5d847e5be5dbf1b0a74b47587a98d840b8cdc
2019-09-12 10:24:45 -07:00
David Tolnay
e84e100f06 Delete extern crate lines
Summary:
`extern crate` is usually no longer needed in 2018 edition of Rust. This diff removes `extern crate` lines from fbcode where possible, replacing #[macro_use] with individual import of macros.

Before:

```
#[macro_use]
extern crate futures_ext;
extern crate serde_json;
```

After:

```
use futures_ext::try_boxfuture;
```

Reviewed By: Imxset21

Differential Revision: D17313537

fbshipit-source-id: 70462a2c161375017b77fa44aba166884ad2fdc3
2019-09-11 22:02:16 -07:00
Xavier Deguillard
1d807635df revisionstore: MutableHistoryStore now accept &self
Summary:
This allows any MutableHistoryStore to be shared and written from multiple
threads.

Reviewed By: quark-zju

Differential Revision: D17278149

fbshipit-source-id: 69f81bb0b182cb27022f13b2e6330b7fc805cbaa
2019-09-11 10:24:59 -07:00
Xavier Deguillard
5a1dd15ad6 revisionstore: MutableDeltaStore now accept &self
Summary:
This allows any MutableDeltaStore to be shared and written from multiple
threads.

Reviewed By: quark-zju

Differential Revision: D17278153

fbshipit-source-id: 17e1474ca1c6d5285cac7dbf519bfd2d5da6e08d
2019-09-11 10:24:59 -07:00
Xavier Deguillard
56887a52bf revisionstore: MutableHistoryPack uses Arc<Mutex<>>
Summary: This will enable switching MutableHistoryStore to use `&self` instead of `&mut self`.

Reviewed By: quark-zju

Differential Revision: D17278151

fbshipit-source-id: 5a6edde5efb0ada14b994d11f33f0aa48780446e
2019-09-11 10:24:59 -07:00
Xavier Deguillard
6dd98111ef revisionstore: IndexedLogHistoryStore uses Arc<RwLock<>>
Summary: This will enable switching MutableHistoryStore to use `&self` instead of `&mut self`.

Reviewed By: quark-zju

Differential Revision: D17278154

fbshipit-source-id: cc66d2874bd86235cd39ce3f5357d155e20ef447
2019-09-11 10:24:58 -07:00
Xavier Deguillard
d9d5396dfc revisionstore: MutableDataPack now uses Arc<Mutex<>>
Summary: This will enable switching MutableDeltaStore to use `&self` instead of `&mut self`.

Reviewed By: quark-zju

Differential Revision: D17278155

fbshipit-source-id: e7c5d464fb6ba2b31b07127832104b8bd4062fa0
2019-09-11 10:24:58 -07:00
Xavier Deguillard
ee01856154 revisionstore: IndexedLogDataStore now internally uses an Arc<RwLock<>>
Summary: This will enable switching MutableDeltaStore to use `&self` instead of `&mut self`.

Reviewed By: quark-zju

Differential Revision: D17278148

fbshipit-source-id: c90f62461f784f4a8efb4e5b0ba0c3e21a6f9f77
2019-09-11 10:24:58 -07:00
Xavier Deguillard
f2cae00958 indexedlog: remove RefCell usage
Summary:
The RefCell makes the IndexedLog not Sync, let's replace the RefCell with
atomic operation to make it Sync.

The `index lookup (disk, verified)` benchmark does not changed much with
this change.

Reviewed By: quark-zju

Differential Revision: D17298580

fbshipit-source-id: 41cb8fea7e06676f3e2cbca3475ac863b0d8454d
2019-09-11 10:24:57 -07:00
Xavier Deguillard
ea472d54cc indexedlog: fix benches
Summary: Compiling failed due to moved crates and removed feature.

Reviewed By: quark-zju

Differential Revision: D17298579

fbshipit-source-id: 02e35e71896175ad415efa75c9558074b66cbfa0
2019-09-11 10:24:57 -07:00
Xavier Deguillard
f5e8568d45 revisionstore: rename IterableStore to ToKeys
Summary:
It's hard (impossible?) to write the iter method for a Store that uses interior
mutability with RefCell and/or Mutex. Due to how MutableDeltaStore and
MutableHistoryStore are designed, it's impossible to use a MutableDeltaStore in
a UnionStore while still being able to add to it due to the requirement of the
add method to be passed in a `&mut self`. To change this, the method needs to
be changed to accept a `&self`, which thus requires the use of a Mutex/RefCell.

Since the IterableStore is never used to get a subset of the keys, let's change
and rename it to always return a Vec of all the keys.

Reviewed By: quark-zju

Differential Revision: D17278150

fbshipit-source-id: 64bad54e69dd89a91acad0d0877d888685858994
2019-09-11 10:24:57 -07:00
Jun Wu
a55fe385eb dispatch: change 'no repository found' message
Summary:
Change the message so it looks more like a user error, not a crash in the
software. This is motivated by some people reporting `hg rage` crash with
`abort: no repository found` messages.

Reviewed By: sfilipco

Differential Revision: D17292658

fbshipit-source-id: 9988f54f2ff8fd48949bcd35c13309c117f3afc6
2019-09-10 18:29:50 -07:00
David Tolnay
97c13edcc7 Delete lines of the form "use [a-z_]+;"
Summary: I think these are left over from pre-2018 code where they may have been necessary. In 2018 edition, import paths in `use` always begin with a crate name or `crate`/`super`/`self`, so `use $ident;` always refers to a crate. Since extern crates are always in scope in every module, `use $ident` does nothing.

Reviewed By: Imxset21

Differential Revision: D17290473

fbshipit-source-id: 23d86e5d0dcd5c2d4e53c7a36b4267101dd4b45c
2019-09-10 15:06:37 -07:00
Xavier Deguillard
4ecde73558 revisionstore: simplify Repackable trait
Summary:
Now that no repack code uses kind/id/cleanup, let's remove the code and all the
associated types.

Reviewed By: quark-zju

Differential Revision: D17207644

fbshipit-source-id: 7e8891b288e1b6193c4fc3a52f18115fe199a8e2
2019-09-10 11:36:01 -07:00
Jun Wu
0cc8f5ce84 commitstore/bench-serialize: add benchmark for mincode
Summary:
Add benchmark for the newly added mincode serialization. An example run shows:

  serialize   by cbor                                32.573 ms   9.701 MB
  deserialize by cbor                                79.471 ms
  serialize   by cbor-packed                         28.574 ms   7.801 MB
  deserialize by cbor-packed                         73.337 ms
  serialize   by bincode                             25.175 ms   6.789 MB
  deserialize by bincode                             23.193 ms
  serialize   by mincode                             19.687 ms   5.389 MB
  deserialize by mincode                             24.852 ms
  serialize   by handwritten                          2.939 ms   5.389 MB
  deserialize by handwritten                          7.963 ms
  serialize   by abomonation                          1.752 ms  10.389 MB
  deserialize by abomonation                          6.060 ms

Interesting facts:
- mincode serialization is actually faster than bincode. (it would appear
  slower if vec was not preallocated).
- mincode is much slower than handwritten. This is partially caused by serde
  not having a native "fixed array" type so it cannot do `write_all(&[u8; 20])`
  but has to `write_u8(x)` 20 times (which translates to
  `Vec::extend_from_slice` 20 times.

Regardless, the main reason I think mincode is compelling is its compactness
and relatively good performance. Although handwritten is the fastest, the
mincode performance is fine in the commit storage usecase, since mincode is
probably not the bottleneck.

Reviewed By: kulshrax

Differential Revision: D17087352

fbshipit-source-id: 820ff8538d3ab9ebef2eda0a40cad126e26db622
2019-09-06 13:13:49 -07:00
Jun Wu
3f459fc3ef mincode: add serialize_into API
Summary:
The existing API is a bit harder to use - the caller must provide a
`&mut Vec<u8>`. Rename that to `serialize_into` and provide a `serialize` that
creates the `Vec<u8>` automatically. This is more consistent with the `bincode`
API interface.

Reviewed By: kulshrax

Differential Revision: D17087349

fbshipit-source-id: 0307b85818ab0f7549a264b41a08e53f7573372e
2019-09-06 13:13:48 -07:00
Jun Wu
e92da70818 mincode: add a basic test
Summary: Add a basic test to ensure mincode is somehow working.

Reviewed By: kulshrax

Differential Revision: D17087350

fbshipit-source-id: efa5d18e579688521e91fe28ee67f1d7f7c15558
2019-09-06 13:13:48 -07:00
Jun Wu
234eefc294 mincode: use vlqencoding for integers
Summary:
This completes the mincode implementation.

I later learned wez has published a very similar crate at
https://github.com/wez/varbincode. Great minds think alike.

Benchmark with varbincode shows this crate is a little bit faster
(varbincode is not in tp2 so we cannot easily add it to benchmark now).

Reviewed By: kulshrax

Differential Revision: D17087351

fbshipit-source-id: 179392029e7b34d7cb92f00b7926ee6be4722d09
2019-09-06 13:13:48 -07:00
Jun Wu
305d739ac3 mincode: initial boilerplate
Summary:
Initialize the mincode library using serde-rs/bench.  See the previous diff for
context.

Reviewed By: kulshrax

Differential Revision: D17087354

fbshipit-source-id: 6e9b6376b8aaec61e85a76320933b63d0ba1b698
2019-09-06 13:13:47 -07:00
Jun Wu
1d00c6d1af third-party: initial import https://github.com/serde-rs/bench
Summary:
I'd like to have a mincode-like serialization format that is really simple:
vlqencoding for integers and use bincode-like strategy for the rest.

There is a mincode crate, but it does not compile due to extra depenencies and
out-of-date serde. It has extra features like bitpack, bitvec which are less
interesing in our commit serialization usecase.

The serde API needs a lot of boilerplate since it supports 20+ types. To make
it easier, I'm importing dtolnay's [serde-rs/bench](9718508c30)
as a starting point.

The serde API needs a lot of boilerplate. Import a minimal implementation so we
can customize on top of it. serde-rs/bench is similar to bincode but much smaller:

bincode:

   333 config.rs
   486 de/mod.rs
   185 de/read.rs
   115 error.rs
   173 internal.rs
   173 lib.rs
   788 ser/mod.rs
  2253 total

mincode:

    57 bitpack.rs
    84 bitvec.rs
    95 float.rs
    90 lib.rs
   434 refbox.rs
   103 rustc_serialize/mod.rs
   427 rustc_serialize/reader.rs
   460 rustc_serialize/writer.rs
   123 serde/mod.rs
   661 serde/reader.rs
   682 serde/writer.rs
  3216 total

serde-rs/bench:

  407 de.rs
   60 error.rs
   25 lib.rs
  442 ser.rs
  934 total

The following (unrelated) files are excluded in this import:

  README.md
  benches/bincode.rs
  tests/bincode.rs
  .gitignore
  .travis.yml

The code does not compile internally due to mismatched `bincode` version. It
will be fixed in the next diff.

Reviewed By: dtolnay

Differential Revision: D17087353

fbshipit-source-id: 26329b36e1488c0c6149287f1f2dcd89acd15b0b
2019-09-06 13:13:47 -07:00
Jun Wu
2ecc23920d commitstore/benchmark-serialize: add bencharmk about commit serialization
Summary:
The `dag` crate provides low-level primitives for DAG queries. To be able to
replace the revlog-based changelog, we need to store actual commit data for
draft commits. That requires some serialization logic.

Till now, I have been writing serialization logic by hand for raw performance.
Given the fact that the commit object might be a bit more complex, it seems
a good idea to try some serialization framework. This diff adds some benchmark
for common choices to get a sense about how expensive serialization is.

A pre-allocated Vec was used to avoid benchmarking `realloc` performance.

A sample run outputs:

  serialize   by cbor                                30.838 ms   9.701 MB
  deserialize by cbor                                78.422 ms
  serialize   by cbor-packed                         29.122 ms   7.801 MB
  deserialize by cbor-packed                         72.826 ms
  serialize   by bincode                             23.120 ms   6.789 MB
  deserialize by bincode                             23.184 ms
  serialize   by handwritten                          2.797 ms   5.389 MB
  deserialize by handwritten                          8.238 ms
  serialize   by abomonation                          1.644 ms  10.389 MB
  deserialize by abomonation                          6.033 ms

The `handwritten` format is designed to be compact, similar to mincode [1].

Some interesting facts:
- bincode is more compact than cbor-packed/rmps-packed, although bincode does
  not have compact integers. This is likely because cbor/msgpack needs to
  encode "type" information and bincode doesn't.
- Handwritten is pretty close to abomonation (basically memcpy).
- Handwritten (mincode) is the most compact format.

[1]: https://github.com/Boscop/mincode

Reviewed By: kulshrax

Differential Revision: D17087348

fbshipit-source-id: 52252aae0d4e44bb326b4dc52f3be767ac04d26c
2019-09-06 13:13:47 -07:00
Jun Wu
06a3ca881b dag: add SpanSet::{min,max}
Summary:
This can be done by using SpanSet::iter. But the `min`, `max` code is easier to
read.

Benchmark does not show significant change.

Reviewed By: markbt

Differential Revision: D17065952

fbshipit-source-id: 9ed8352ceb25499143931bd890e694de475ee9d2
2019-09-06 09:33:50 -07:00
Jun Wu
7e37aa54aa dag: add Span::full
Summary: This will be used in a later change.

Reviewed By: markbt

Differential Revision: D17065955

fbshipit-source-id: 562ee050cf308f3740de123e77f81a29c35089bd
2019-09-06 09:33:49 -07:00
Jun Wu
9e2013f068 dag: union spans automatically during SpanSet::from_spans
Summary:
Previously, `SpanSet::from_spans` is one of the few ways to get a non-compact
SpanSet (ex. contains spans that can be merged). This diff solves it.

There are no usage of `SpanSet::from_spans` for large sets. Benchmark does not
change.

Since checking overlapped spans now take extra work. Overlapped spans are now
merged automatically. This makes `SpanSet::from_spans` panic-free.

Reviewed By: markbt

Differential Revision: D17065954

fbshipit-source-id: 38947852d9a5a06cee1eabb05b81b410bff755f9
2019-09-06 09:33:49 -07:00
Jun Wu
f5aa41727e dag: add SpanSet::from_sorted_spans
Summary:
There are cases we already know spans are sorted. Provide an API for that.
This affects some of the future changes.

Reviewed By: markbt

Differential Revision: D17065953

fbshipit-source-id: 350844d7c1770d4a9c70a5d7f41d6b20d17d9757
2019-09-06 09:33:49 -07:00
Jun Wu
94f6edd4be dag: implement a friendly SpanSet::Debug
Summary:
Implement a more fridently SpanSet::Debug and use it in tests.
This makes the test code shorter and easier to read.

Reviewed By: markbt

Differential Revision: D16988045

fbshipit-source-id: 3ac51dd5b525de03c406f7fd138d96b2b2e8e5b0
2019-09-06 09:33:49 -07:00
Xavier Deguillard
cf64b3dc99 revisionstore: allow a PackStore to ignore corrupted packfiles
Summary:
While a corrupted packfile can be safely removed from the shared hgcache, the
same isn't true for local packfile. When building the packstore, let's allow
the behavior on corrupted packfile to be chosen. This is voluntarily made as an
explicit argument to DataPackStore and HistoryPackStore constructor so the
caller can take this into account.

Reviewed By: quark-zju

Differential Revision: D17187155

fbshipit-source-id: 658fce401f8902a74cfd92780013d1b96e20a590
2019-09-05 10:21:26 -07:00
Xavier Deguillard
27055ce83b revisionstore: delete corrupted packfiles
Summary: This brings the Rust based PackStore on par with the Python implementation.

Reviewed By: quark-zju

Differential Revision: D17082190

fbshipit-source-id: 8cf925c3d6136c0ba586e7578a2b90b7f39192e9
2019-09-04 09:37:17 -07:00
Xavier Deguillard
bc75a4c02b revisionstore: add a PackStoreOptions builder
Summary:
Instead of adding more arguments to the PackStore constructor, let's use the
Builder pattern.

Reviewed By: quark-zju

Differential Revision: D17082191

fbshipit-source-id: b9e31251c0fa942e76339d568049c1b75226cb88
2019-09-04 09:37:16 -07:00
Xavier Deguillard
06894086e4 revisionstore: always try to rescan when calling get_missing
Summary:
When created, the PackStore are empty as no disk scan are performed. As
get_missing is one of the first API to be called on the store when a prefetch
is needed, that means that get_missing always pretend that everything is
missing, which isn't true.

Since we don't want to always rescan on get_missing, let's respect the scanning
frequency and then figure out what's missing.

Reviewed By: quark-zju

Differential Revision: D16794077

fbshipit-source-id: 460fda8f118c1b36e5d5b29472e8a06ef0754ec9
2019-09-04 09:37:16 -07:00
Stefan Filip
edfeb9f529 treemanifest: remove delta storing of manifest entries when autocreate
Summary:
It is somewhat difficult to fetch the raw entry on the p1 side in the Rust
Manifests. These entries are used to write deltas to revlogs or to datapacks.

Reviewed By: xavierd

Differential Revision: D17143551

fbshipit-source-id: 6624116324664354d199d5f6ac55712c8ed29b9d
2019-09-03 15:08:34 -07:00
Thomas Orozco
817fb8839c rust-crates-io: add gotham_derive
Summary: This updates rust-crates-io to add gotham_derive.

Reviewed By: StanislavGlebik

Differential Revision: D17163951

fbshipit-source-id: 27c6d728fee9b837ae504b51362feaa71e69d66f
2019-09-03 14:57:52 -07:00
Xavier Deguillard
70796a2a30 bindings: add bindings for the Rust PackStore
Summary:
The Rust code is almost at parity with the Python code, let's expose it to
Python.

Reviewed By: quark-zju

Differential Revision: D16794076

fbshipit-source-id: faf1da775b4e57328be62a06d0065c7becf1b9f4
2019-09-03 13:56:38 -07:00
Xavier Deguillard
3be26f6c50 revisionstore: a non existent pack directory isn't an error
Summary:
In some rare situation, the packs directory may not exist, the PackStore
shouldn't fail in these case, it should just act as if nothing is present in
it.

Reviewed By: quark-zju

Differential Revision: D16794079

fbshipit-source-id: e33bd55e0f378b9be58831a85ec822221af7a9bc
2019-09-03 13:56:38 -07:00
Xavier Deguillard
309833592f revisionstore: add an LruStore
Summary:
The LruStore keeps the packfiles in a somewhat ordered manner to reduce the
cost of finding an object in the stores. For now, its implementation is very
basic as it just moves the store where data was found at the front.

Reviewed By: quark-zju

Differential Revision: D16746800

fbshipit-source-id: 67375e6ab8a4d9e54da9a9bb4af5d95061446e6f
2019-09-03 13:56:38 -07:00
Xavier Deguillard
4d9c67701b revisionstore: impl IterableStore for IndexedLogHistoryStore
Summary: This just iterates over all the keys contained in the store.

Reviewed By: quark-zju

Differential Revision: D17104467

fbshipit-source-id: 34eee949cf4a1504df67c09fab7f71ef95210eed
2019-08-30 18:30:47 -07:00
Xavier Deguillard
8fe088a73d asyncrevisionstore: add an async wrapper for the IndexedLogHistoryStore
Summary: See above.

Reviewed By: quark-zju

Differential Revision: D17100018

fbshipit-source-id: 2370c18d608540b9978fcd578618ae4ba14656b7
2019-08-30 18:30:47 -07:00
Xavier Deguillard
8ec0ee1afa asyncrevisionstore: add AsyncMutableHistoryStore
Summary:
This moves code from AsyncMutableHistoryPack. This allows abstracting the type
of history store so the IndexedLogHistoryStore can be easily added.

Reviewed By: quark-zju

Differential Revision: D17100019

fbshipit-source-id: ca226336ae9ff05385f9218e88e853bf6e5356e3
2019-08-30 18:30:46 -07:00
Xavier Deguillard
8a28530f5f revisionstore: handle indexedlog corruption
Summary:
We've seen a handful of cases where the indexedlogdatastore becomes corrupted
which makes Mercurial unable to run properly. For now, and since we only use
the indexedlog for the hgcache, let's just remove it.

A better solution would be to harden the indexedlog code to better detect the
corruption and attempt to fix them.

Reviewed By: quark-zju

Differential Revision: D17115622

fbshipit-source-id: ee474a5df60c4414f6ea21ace7dff0f7048879c9
2019-08-30 11:26:16 -07:00
Stefan Filip
490a99230c manifest: preserve p1 and p2 order in finalize
Summary:
I had assumed that we store p1 and p2 in the same order that they are used in
Node computation. That is incorrect. In general p1 and p2 are assumed to have
an ordering that matters and it's Node computation that is specific.

Reviewed By: quark-zju

Differential Revision: D17125743

fbshipit-source-id: 3a2673d9c243e2d2103aba0cb4fd8f536386efa7
2019-08-30 10:50:06 -07:00
Stefan Filip
abf02ee9ca manifest: update finalize to work on durable trees
Summary:
In some cases the finalize algorithm is used to persist data that is received
in a bundle. The process is that it constructs a store from the bundle and
goes to construct a tree with the root node received. It then goes through
finalize to generate the entries that need to be written to local storage.

Reviewed By: quark-zju

Differential Revision: D17125149

fbshipit-source-id: de5a1e922a6aebe48e238d8473177a8d3f7a9ef5
2019-08-30 10:50:06 -07:00
Stefan Filip
f8fa8d9367 manifest: add list directory functionality
Summary:
`listdir` returns the contents a directory in the manifest. The format
is pretty simple, containing only the simple names of the files and or
directories. I don't know if this is something that eden can use because
it seems to simple. In other words, we have something but we may want
to iterate on it before we market it broadly.

Reviewed By: quark-zju

Differential Revision: D17098082

fbshipit-source-id: d6aa42c96781cf1f8b2e916fa10bb275593bdc65
2019-08-30 10:50:05 -07:00
Stefan Filip
ffb563f1bb manifest: add subdir_diff compatibility function for gettreepacks
Summary:
The C++ manifest implements walksubdirtrees which is used to compute the packs
that a "client" wants for a prefetch. In terms of interface the function is very
annoying and couples with storage and tree representations without being part
of any of them.

We reproduce that functionality as a means to replace the C++ implementation.
The long term goal is to do lazy fetches using an iteration style that plays
nicer with batching downloads.

This change also includes fastmanifest updates because they are required to
enable the walksubdirtrees functionality in our tests.

Reviewed By: quark-zju

Differential Revision: D17086669

fbshipit-source-id: 6c1f9fbf975814f0a2071f8d1c8e022e5ad58e29
2019-08-30 10:50:05 -07:00
David Tolnay
67f279e778 Update to Rust 1.38.0-beta.3
Reviewed By: bolinfest

Differential Revision: D17128329

fbshipit-source-id: caa2699bf0ae94b33bebd42fb4bbf09d22405056
2019-08-30 02:01:28 -07:00
Jun Wu
30f293314c clidispatch: support explicitly named arguments in define_flags!
Summary:
This makes it possible to use explicitly named arguments. It can simplify the
code a bit by moving the error handling (incorrect number of arguments) to the
derived code.

Reviewed By: xavierd

Differential Revision: D16905460

fbshipit-source-id: 93dc58d684bb52cd2f9bddc25108ef0c500f81db
2019-08-28 19:26:28 -07:00
Jun Wu
ed3f36bb85 cliparser: return errors if unexpected arguments are provided
Summary:
If there is no `#[args]` field set, the command does not need arguments. In
that case, just error out directly. This can simplify command implementations.

Reviewed By: xavierd

Differential Revision: D16905461

fbshipit-source-id: f4a2d03cf032f34d1b5794010774ff80eb88e1cd
2019-08-28 19:26:28 -07:00
Jun Wu
3c881c88d7 clidispatch: change From to TryFrom for flags parsing
Summary: This make it possible for the flags parsing to return an error.

Reviewed By: xavierd

Differential Revision: D16905462

fbshipit-source-id: 06a70ee7c72132ebb2df453a740b58e6b46dfba2
2019-08-28 19:26:27 -07:00
Jun Wu
06ff75a799 cliparser: add #[command_name] to define_flags!
Summary:
Most commands do not care about the "command name" (aka. arg0). Only commands
sharing a similar implementation (ex. hg up/down/bottom/top) would need it.
Make it optional and make `args` not containing the command name.

Reviewed By: xavierd

Differential Revision: D16905459

fbshipit-source-id: 0a786731ebce2580e116fd50aad75062b03a1fa3
2019-08-28 19:26:27 -07:00
Jun Wu
48e21aebc8 cliparser: add names to define_flags! internal fields
Summary: This makes the code easier to read as we add more fields to the macro state.

Reviewed By: xavierd

Differential Revision: D16905458

fbshipit-source-id: a3bc4dc1accf21cf491921469482f86aec16321b
2019-08-28 19:26:27 -07:00
Jun Wu
60008634e7 hgcommands: pass args and io to Python
Summary:
This makes it possible to capture output of a Python command via the Rust
hgcommands crate.

Reviewed By: xavierd

Differential Revision: D16866467

fbshipit-source-id: e64feece9b31196fabfea110015d5c45cb548046
2019-08-28 19:26:25 -07:00
Jun Wu
65ecfdc472 bindings: move io module to cpython-ext
Summary: This allows the io module to be used in non-extension code (ex. hgcommands).

Reviewed By: xavierd

Differential Revision: D16866458

fbshipit-source-id: b36b535e3804ba2b8e656508c10ca7ceb3e1fdf1
2019-08-28 19:26:24 -07:00
Jun Wu
636f2ecfdd clidispatch: make IO streams downcast-able
Summary: An upcoming change would like to downcast IO to stdio or PyObjects.

Reviewed By: xavierd

Differential Revision: D16866456

fbshipit-source-id: 73289aab13260ec421b979280f0b9c73383ab5d0
2019-08-28 19:26:24 -07:00
Jun Wu
1fc61320b8 bindings: add commands.run to run Rust commands
Summary: This makes it possible for Python to execute commands implemented in Rust.

Reviewed By: xavierd

Differential Revision: D16866457

fbshipit-source-id: e7352eed0e7b722c28974cb1123975f591ac44bc
2019-08-28 19:26:24 -07:00
Jun Wu
0bf732777a hgcommands: move the actual "run_command" logic from hgmain to hgcommands
Summary:
Expose a simple method in hgcommands to run the actual (Rust or Python) command.
This makes it easier to expose the "runcommand" API via bindings.

I have to disable chg temporarily since `hg root` with chg stops working at present.
chg will be re-enabled in a later diff.

Reviewed By: xavierd

Differential Revision: D16866461

fbshipit-source-id: 46c5df9a577d748fab302a8c7157d8aa62d6f1bd
2019-08-28 19:26:24 -07:00
Jun Wu
16613a894d hgpython: make HgPython take the arguments
Summary:
Previously, HgPython hardcodes the arguments to be std::env::args().
This diff makes that an configurable argument.

Reviewed By: xavierd

Differential Revision: D16866464

fbshipit-source-id: 3a37dd89793e0813732ea9b088ff22c9a4c6b125
2019-08-28 19:26:23 -07:00
Jun Wu
f654b6ebd9 hgcommands: do not call Py_Finalize if Python was not initialized by us
Summary:
`Py_Finalize` is not recursive. It unconditionally destroys the Python interpreter
state. To make `hgcommands` usable in a library (ex. bindings), detect the case
where the interpreter was initialized, and skip `Py_Finalize` in that case.

Reviewed By: markbt

Differential Revision: D16866454

fbshipit-source-id: ea6bb6a83bc0b0fe7b5c2ce21158ae9d9e2a779d
2019-08-28 16:36:21 -07:00
Xavier Deguillard
800e44a553 revisionstore: add an indexedlog based historystore
Summary:
The indexedlog based datastore is being rolled out more broadly, let's add a
basic historystore indexedlog to replace the historypacks. One of its first use
will be in hg_memcache_client write path to remove some pathological cases
where hg_memcache_client can write thousands of packfiles. This in turn will
remove the need to run repack to keep the amount of packfiles in control.

The IndexedLog key is the concatenation of sha1(path) and the node. Hashing the
path should be fairly cheap and makes it easy to integrate with the IndexedLog.

One of the drawback versus the histpack will be storage space usage, as the
path is always stored per entry, while it was shared with multiple entries in
the history pack. I though about having a separate index to easily translate
the hashed path to the path, but due to the potential log rotation, we could
end-up in a case where the path isn't present at all in the store.

Reviewed By: quark-zju

Differential Revision: D16616082

fbshipit-source-id: 1e47260b479f8923cc137a39dcba54b2d074f43a
2019-08-27 11:58:53 -07:00
Jun Wu
66cef07cf9 indexedlog: add a fsync option to Log and Index
Summary:
Add a way to explicitly `fsync` data to reduce changes of data corruption in
case of hard reboots.

If `fsync` is set on a `Log`, it sets `fsync` recursively on its indexes and
checksum tables. If frequent `fsync` is an issue, it might be possible to only
`fsync` the source of truth (log and meta) and have other logic to rebuild
indexes on demand.

`fsync` on btrfs seems to be relatively cheap (comparing to ext4), so maybe
this is fine for btrfs users.

Reviewed By: markbt

Differential Revision: D16926659

fbshipit-source-id: a9de2fa352f607fe6f0b9d36047323862770f2e6
2019-08-26 19:57:20 -07:00
Jun Wu
803a98f01f indexedlog: make Index own OpenOptions
Summary:
Put OpenOptions as a field in Index. This simplifies Index struct as we add
more fields to OpenOptions.

Reviewed By: markbt

Differential Revision: D16926660

fbshipit-source-id: 0d6fad0eb1c9b38831494be74b3c440e4d827202
2019-08-26 19:57:19 -07:00
Jun Wu
e24ddfd9ee indexedlog: change some errors to include path information
Summary:
Use `PathDataError` in some cases so they contain path information and might be
more useful.

Reviewed By: markbt

Differential Revision: D16876969

fbshipit-source-id: c85b576006872fdcdefb89588bccd871ace69aa6
2019-08-26 19:57:19 -07:00
Jun Wu
fabaa19c63 indexedlog: rework error definition
Summary:
Define errors using failure_derive. Remove ad-hoc macro.

As we're here, also define some more-detailed errors. They'll be used in
upcoming diffs.

Reviewed By: markbt

Differential Revision: D16876971

fbshipit-source-id: 0a47a7e03876f27b5a5bb54c5f396a3816488c47
2019-08-26 19:57:19 -07:00
Jun Wu
3695d23ed7 indexedlog: improve error message on checksum failure
Summary:
Previously, checksum error just shows "integrity check failed". This diff
changes it to print the file path and byte range.

`#[inline(never)]` was preserved to maintain performance.

Reviewed By: markbt

Differential Revision: D16872827

fbshipit-source-id: 606a6f80a47028ce4d51e84bacbf1d90a3e9e048
2019-08-26 19:57:18 -07:00
Jun Wu
6a304509f0 Back out "[hg] configparser: inline the pest grammar"
Summary:
The pest codegen has some non-determinism (HashMap) that breaks buck build.

According to jsgf:

  This basically indicates some kind of non-determinism in the build. They're a pain, so I'd been hoping that we'd got them all.

  Yeah, pest is generating non-deterministic output, which will screw things up badly. The problem is:

  https://github.com/pest-parser/pest/blob/master/generator/src/generator.rs#L92-L93

    fn generate_builtin_rules() -> HashMap<&'static str, TokenStream> {
        let mut builtins = HashMap::new();

  is putting builtins into a `HashMap`, then:

  https://github.com/pest-parser/pest/blob/master/generator/src/generator.rs#L46

    rules.extend(defaults.into_iter().map(|name| builtins[name].clone()));

  emitting them in hashmap order. It needs to use a `BTreeMap` to make sure they're in a consistent order.

  (I didn't check whether there are other instances of this.)

Reviewed By: jsgf

Differential Revision: D17063573

fbshipit-source-id: c03adc3c6d50bd09ffbd44ca8dc7bc51d6cad28d
2019-08-26 18:31:44 -07:00
Jun Wu
3e4443737f lib: remove cargo workspace
Summary:
The workspace was added by D8741175 mainly to make build artifacts share a same
"target" directory.  D14606468 made `setup.py` write a `.cargo/config` that
specifies a sharable "target" directory. Remove the workspace since the crates
already share a "target" directory.

This makes it a bit easier to add new crates.

Reviewed By: singhsrb

Differential Revision: D17053934

fbshipit-source-id: d34781c796356b725ddce3453c1951a4d4133807
2019-08-26 17:34:34 -07:00
Stefan Filip
8a402cc939 manifest: update insert validation
Summary:
The insert code would be unclear in what kind of issue it ran into when
inserting files. Sometimes the file we want to insert is a directory and
other times it want to traverse a directory. This change makes those
situations clear along with some other corner case behaviors.

Reviewed By: quark-zju

Differential Revision: D16775354

fbshipit-source-id: 50ab6bc52b70cc5cef013d11050eb3cdf5b160a5
2019-08-26 10:48:08 -07:00
Stefan Filip
d4614d568d manifest: update manifest.remove to return None for dirs
Summary:
Updating the manifest implementation for remove with the intended API.
When I originally implemented remove I wasn't confident what was the
best way to implement remove. As I've gained more experience, I feel
confident that doing two iteration over the tree is a good approach
for this method. The first iteration should validate that the file
exists then the second iteration will actually traverse down updating
the nodes to mutable ephemerals.

Reviewed By: quark-zju

Differential Revision: D16775353

fbshipit-source-id: 8ebee9ca347efcb694a6d27c1eeae2c149643766
2019-08-26 10:48:08 -07:00
Stefan Filip
2e3860a3d9 manifest: fix get_link to return None for children of files
Summary:
`get_link` started as test function that broaden in scope but did not have
it's behavior updated as it started to be used more broadly.
No reason to error out when we request a path that has parent files in the
manifest.

Reviewed By: quark-zju

Differential Revision: D16775356

fbshipit-source-id: a320926100378f16d723ca204746906e79c7752e
2019-08-26 10:48:07 -07:00
Jun Wu
42d2ec27d7 configparser: inline the pest grammar
Summary:
The latest pest_derive supports inline grammar. Replace the ad-hoc codegen with
it.

Reviewed By: markbt

Differential Revision: D16866455

fbshipit-source-id: e9cae33d4d97eeb09afa212a6c0ae777f4bb193b
2019-08-23 11:09:39 -07:00
Mark Thomas
756ee47bf3 commitcloud: add blackbox logging of cloud changes
Summary:
Add blackbox logging of syncing to or from the commit cloud workspace,
including which changes are being submitted.

Also log when obsmarker fixup happens in blackbox.

Reviewed By: quark-zju

Differential Revision: D16961281

fbshipit-source-id: 0d0f675d77ab3446198703b31eea940dae3bdd85
2019-08-23 05:03:38 -07:00
Jun Wu
b49ce531cc clidispatch: fix a minor case of debug command detection
Summary: This makes `config|debugconfig` as a debug command. Previously it was not.

Reviewed By: singhsrb

Differential Revision: D16866460

fbshipit-source-id: f1fcf0777d2fe6c1426f557ae1999710dd722109
2019-08-22 18:30:29 -07:00
Jun Wu
adbe2b2b32 alias: ignore alias definitions with ":" in name
Summary:
Aliases with `:doc` in name are not real commands. Do not treat them as
commands.

The upstream patch https://phab.mercurial-scm.org/D5087 added other metadata
including `:help` and `:category`. We might end up having some in the future
so I blacklisted names with `:` in them, not just `:doc`.

Reviewed By: chadaustin

Differential Revision: D16955596

fbshipit-source-id: b6f3e1129b632e0ba43c800e7e6fdd2b52d3b40c
2019-08-21 21:13:38 -07:00
Jun Wu
7eb73196c4 clidispatch: avoid fs::canonicalize
Summary:
`fs::canonicalize` has unwanted side effect - resolving symlinks.
Use `util::path::absolute` instead. This resolves a side effect where

Note on Linux, `chdir` resolves symlinks and `getcwd` (aka.
`std::env::current_dir`) will return the resolved path.  On Windows
`std::env::current_dir` does not return the resolved path, at least
for the mapped drive created via the `subst` command.

Differential Revision: D16952484

fbshipit-source-id: 6969a1844020ff6b82de46416d8950ec40394159
2019-08-21 17:59:50 -07:00
Jun Wu
3e73af0a9a util: add a function to get absolute path without resolving symlinks
Summary:
On Windows, some people use the "map drive" feature to map a long path (ex.
`C:\long\path\to\repo`) to a short path (ex. `Z:\`) so their tooling can
handle some long paths.

In that case, resolving symlinks by `hg root` is undesirable.

Unfortunately, the Rust stdlib does not have a Python `os.path.abspath`
equivalent. There were some attempts (ex. https://github.com/rust-lang/rust/pull/47363)
but the corner cases (ex. symlinks) have made the problem much more
complicated.

There are some 3rd-party crates. But they are not a good fit:
- https://github.com/danreeves/path-clean/ (last commit fb84930) follows the golang plan9 idea. It does not have proper support for Windows paths.
- https://github.com/vitiral/path_abs/ (latest commit 8370838) reinvents many path-related types, which is an overkill for this usecase.

This diff implements the feature "reasonably" for both Windows and Linux, with
nasty corner cases (symlink) ignored.

Differential Revision: D16952485

fbshipit-source-id: ba91f4975c2e018362e2530119765a380f103e19
2019-08-21 17:59:50 -07:00
Jun Wu
b85df9caf2 clidispatch: move logic to read system and user config to configparser
Summary: The configparser crate is a better place for logic to load system and user config.

Reviewed By: sfilipco

Differential Revision: D16796396

fbshipit-source-id: c1ae5f85aa9839d89f5026279d699135dc1b442b
2019-08-21 12:59:29 -07:00
Jun Wu
8f349dbb17 clidispatch: make repo.shared_path non-lazy
Summary:
Move `repo.shared_path` handling to repo initialization time and store it in
the repo structure.

This makes `repo.shared_path()` cheap if it gets used frequently.

Reviewed By: sfilipco

Differential Revision: D16796401

fbshipit-source-id: e19f3381cc87b55500ea1d27fd918ccb16a71972
2019-08-21 12:59:28 -07:00
Jun Wu
08a80a4bcc clidispatch: move repo specific logic to repo.rs
Summary:
Some functions in `dispatch.rs` are about the "repo". Move them to a better
place - `repo.rs`.

The repo and config logic is coupled. A new enum `OptionalRepo` was added, to
make code easier to write - `Some(repo)` means the repo exists, and `repo` owns
the config. `None(config)` means the repo is missing, but the config is still
available.

Reviewed By: sfilipco

Differential Revision: D16796403

fbshipit-source-id: 2f4017a52296b629e990f85437b2cfdd7263b9e6
2019-08-21 12:59:28 -07:00
Jun Wu
19b4a7c3de clidispatch: rename InferRepo to OptionalRepo
Summary:
"infer" means "try to get the repo path from command line arguments like a full path".
The enum variant is really "repo is optional". Rename to clarify.

Reviewed By: sfilipco

Differential Revision: D16796399

fbshipit-source-id: 505d2a406a83e0006200ece63d360b119548d2dd
2019-08-21 12:59:28 -07:00
Jun Wu
b6101a12e0 clidispatch: rework error handling
Summary:
Change error type in clidispatch from `DispatchError` to `failure::Error`.

Pros:
- `failure` will attach a backtrace for free. (otherwise, backtrace handling is
  manual)
- Wrapping other errors (ex. `io::Error`, `cliparser::Error`) is optional.
  (otherwise, wrapping other errors is mandatory, and needs to be careful to
  not lose information)

Cons:
- No longer able to enumerate *all* possible error types. (but can still
  downcast to specific errors)

This seems to be a good tradeoff especially because of the backtrace handling - I
ran into a few issues where the location where the error happened really helped
debugging.

Since we can no longer enumerate all possible error types, the enum was changed
to individual structs to make the code shorter (ex. the struct can be downcasted
directly, instead of down-casting to the enum, then matching its variant).

The `HighLevelError` handling was simplified and moved to `hgmain`.

The new code path falls back to Python less aggressively, therefore some behaviors
were tweaked (ex. `-R` takes a bundle path).

Reviewed By: sfilipco

Differential Revision: D16796400

fbshipit-source-id: 1b17eb8d62503644b118c6b799778182bf222538
2019-08-21 12:59:28 -07:00
Jun Wu
7cce00694c cliparser: use lowercase text in errors
Summary:
This is more conistent with Mercurial style. And make them usable directly in
Rust code.

Reviewed By: sfilipco

Differential Revision: D16796397

fbshipit-source-id: 9016ea2b09fdf96b2b54138f5c8405caf96390f7
2019-08-21 12:16:36 -07:00
Jun Wu
253b03e87c cliparser: sort possibilities in AmbiguousCommand error
Summary:
This makes the "content" of the error stable. It is used in a later diff where
AmbiguousCommand gets handled by Rust directly instead of falling back to
Python dispatch.py.

Reviewed By: sfilipco

Differential Revision: D16796404

fbshipit-source-id: c439db14ec83c76c4762d3c627bfce1ea44bccf4
2019-08-21 12:16:36 -07:00
Jun Wu
0f8f66f8b4 clidispatch: make CommandDefinition::flags lazy
Summary:
In case there are many CommandDefinitions, we don't need all their flag
definitions until we decided to execute one of the commands.

Reviewed By: sfilipco

Differential Revision: D16796398

fbshipit-source-id: af205f59efd77fd7ff9eb4655d1f9167e2c350da
2019-08-21 12:16:36 -07:00
Jun Wu
0bc2824c82 clidispatch: make use of HgGlobalOpts
Summary: Convert global flags to `HgGlobalOpts` struct to make code shorter.

Reviewed By: sfilipco

Differential Revision: D16796407

fbshipit-source-id: b9d4c3dbec68c81908d439da4c353249347ca74a
2019-08-21 12:16:36 -07:00
Jun Wu
1623399c15 clidispatch: remove tests
Summary:
The tests are

- Mostly testing about configurations.
- Mostly depends on private functions.

ConfigSet already has a good test coverage, the tests do not provide much
value (aside from testing config override ordering, which is also covered
by hg tests). I'm going to change / remove the private functions. Remove the
tests to make changes easier.

Reviewed By: sfilipco

Differential Revision: D16796402

fbshipit-source-id: 56a8d55a0d1b0438bd2fcde5d3379d76f51dcd9d
2019-08-21 12:16:35 -07:00
Jun Wu
c508ada8b2 clidispatch: use define_flags! to define global flags
Summary: This makes it possible to simplify the code reading global flags.

Reviewed By: sfilipco

Differential Revision: D16796405

fbshipit-source-id: eb604470d052ef84b748d1e60270cacd410fc5da
2019-08-21 12:16:35 -07:00
Jun Wu
210bf49f5e clidispatch: replace Dispatcher with CommandTable
Summary:
The `Dispatcher` provides lots of features but its internal state only contains
the command table. Replace it with `CommandTable` and make the methods free
functions.

This makes function dependencies more cleaner, for example things like "locating
a repo", "getting the args" etc. won't require a `Dispatcher`.

A side effect of this change is the non-utf8 command line arguments are no longer
supported. This is already broken since our hg wrapper (accidentally) enforced
utf-8 command line. Therefore related tests are removed.

Reviewed By: sfilipco

Differential Revision: D16796395

fbshipit-source-id: a793ce7b8befe7caf62405c582fc932eb3daa099
2019-08-21 12:16:35 -07:00
Jun Wu
6aeaa40b40 clidispatch: extract CommandTable to a separate struct
Summary:
The dispatch logic couples with too much stuff - repo, parsing, command,
config. The command / registration part can be cleanly seprated.

This diff moves the core logic of CommandTable to command.rs.

Reviewed By: sfilipco

Differential Revision: D16796406

fbshipit-source-id: 5a33d6b6452537f07895bd9944122a3b3149d925
2019-08-21 12:16:34 -07:00
Jun Wu
775ee9c0c9 root: normalize the repo path before printing it out
Summary:
Change `root` to normalize the repo path so it strips `\\?\` UNC prefix that
might break some (ex. Python) scripts.

Reviewed By: DurhamG

Differential Revision: D16928880

fbshipit-source-id: 9691b712f1ba0a07815d025e083d0cbd90b7d6a3
2019-08-20 16:40:25 -07:00
Jun Wu
b289384cce bindings: move configparser path normalization to a new util crate
Summary: This makes the code reusable.

Reviewed By: DurhamG

Differential Revision: D16928881

fbshipit-source-id: cced0ecd6099e86c4a3f2f843e4dcfa9c6748e27
2019-08-20 16:40:25 -07:00
Jun Wu
36f974ebae clidispatch: register commands without CommandDefinition
Summary:
Previously, the command table state in `Dispatcher` is confusing:

    command_table: BTreeMap<String, CommandFunc>,
    commands: BTreeMap<String, CommandDefinition>,

Question: In what case do these BTreeMaps have different keys?

It does not make much sense. Therefore merge `CommandFunc` into
`CommandDefinition`, and remove the `command_table` field.

This affects the `register` API:

		fn register(&mut self, command: CommandDefinition, f: FN)

`f` is part of `CommandFunc`, which duplicates with `CommandDefinition`.

`CommandDefinition` contains 3 things: name, doc, and flags.

In the new `define_flags!` world, `flags` can be inferred from the type
of the function, so only `name` and `doc` are needed. Therefore change
the register function to:

		fn register(&mut self, f: FN, name: &str, doc: &str)

Update `hgcommands` to use the newer APIs. Commands can now be registered
without going through `CommandDefinition` explicitly.

Reviewed By: sfilipco

Differential Revision: D16733275

fbshipit-source-id: 68e404a5b271b72aad52f640123b1c083f31d76c
2019-08-19 19:27:31 -07:00
Jun Wu
ebde0168a2 clidispatch: remove load_python_commands
Summary:
The only actual use of the function is to get Python command names (not
functions) so it can do prefix matching.

Just change the prefix matching logic to load the config and drop concepts
about "python" in CommandDefinition.

The Rust command table now only contains Rust commands.

Reviewed By: sfilipco

Differential Revision: D16733265

fbshipit-source-id: 7c680ef77874e9a136befc286cd26663ba82b09f
2019-08-19 19:27:31 -07:00
Jun Wu
f6659524bc clidispatch: rename CommandType to CommandFunc
Summary: The enum owns the function of the command. Rename to make it clear.

Reviewed By: sfilipco

Differential Revision: D16733262

fbshipit-source-id: 6fdc7e999b0863b2a7b35203ac704928f8f92cd2
2019-08-19 19:27:31 -07:00
Jun Wu
8ec9e492ff clidispatch: initial migration to define_flags!
Summary:
Use `define_flags!` to auto generate conversion from `ParseOutput`.
A side effect is `args` is moved to the struct, and function signature becomes simpler.

Currently, `args` will also include the command name itself. This might be
useful when multiple commands share a similar implementation (ex. `next`, `prev`).

Reviewed By: sfilipco

Differential Revision: D16733269

fbshipit-source-id: fe32e41fe48a97d2d2f5a122522a17fa3c5f5f82
2019-08-19 19:27:30 -07:00
Jun Wu
76cb250fcd cliparser: store positional args in structs
Summary:
This makes it possible to use one structure instead of a structure + another
`args` list.

The current version only supports a `Vec<String>` field and there is no verification
about how many arguments that `Vec<String>` can have. In the future we can add:
- Verification about arguments. Potentially change `From<ParseOutput>` to `TryFrom<ParseOutput>`.
- Individual named arguments as individual fields.

Reviewed By: sfilipco

Differential Revision: D16733272

fbshipit-source-id: 2bb407fff6cd1790cf33e8ce5527bb5e44255215
2019-08-19 19:27:30 -07:00
Jun Wu
2da208b718 cliparser: support multiple structures in one define_flags!
Summary: This can make code shorter.

Reviewed By: sfilipco

Differential Revision: D16733264

fbshipit-source-id: 27c0299c6e59bc30cfa14aa9ce122e2a542fd9c1
2019-08-19 19:27:30 -07:00
Jun Wu
7b96c8d292 cliparser: support shell alias
Summary:
Alias starting with `!` are considered shell commands. The entire command
string should be passed roughly as-is to the shell.

The current alias handling uses shlex::split to split the alias into arguments,
then replaces things like `$1` in arguments. The problem is, escaping
shlex::split a complex shell alias, then unesape (shlex::quote) it is not
loseless.

To maintain compatibility for existing complex shell alias configuration,
add a new code path that imitates the Python code behavior.

Reviewed By: sfilipco

Differential Revision: D16814144

fbshipit-source-id: 0e5e95f99bf8b8b16bd8d0cbcadd6760f7f77ebb
2019-08-19 19:27:27 -07:00
Carolyn Busch
09ceebfcac Debugstore command
Summary: New degbugstore command prints contents of blob in store give filenname and hash.

Reviewed By: xavierd

Differential Revision: D16791780

fbshipit-source-id: d4529f3f368677b4f65a5772f82a1655552fefa5
2019-08-15 19:36:31 -07:00
Jun Wu
917d75c85a rotatelog: make indexes of immutable Logs up-to-date
Summary:
The indexes are lagging by design to reduce space overhead. For immutable Logs
(esp. used by RotateLog), the indexes no longer need to be lagging.

Make it so to reduce overhead opening RotateLog.

As we're here, also fix an issue where `rotate_assume_locked` was not really
protected by a lock.

Reviewed By: sfilipco

Differential Revision: D16587181

fbshipit-source-id: 3cf81864e90c875ee661dbd994bcd3ebc4b55322
2019-08-15 16:32:55 -07:00
Adam Simpkins
ce3bf61c80 fix copyright headers in a few files
Summary: Fix copyright headers to pass our lint rules.

Reviewed By: xavierd

Differential Revision: D16824227

fbshipit-source-id: f9bc74f42e2c9d5c112f527eec479da9e1ce56fb
2019-08-15 11:33:07 -07:00
Jun Wu
d2e169b097 cliparser: remove ParseOptions::ignore_errors
Summary: It's not actually used anywhere.

Reviewed By: sfilipco

Differential Revision: D16715452

fbshipit-source-id: ea3e1411b38220f7555de11fa71da258c1c9d0d7
2019-08-15 10:08:36 -07:00
Jun Wu
f49868e6e7 cliparser: add a test demostrating incorrect behavior
Summary: `--no-foo` should only work if `foo` is a boolean flag.

Reviewed By: farnz

Differential Revision: D16715454

fbshipit-source-id: 9a8183586aa50fb55f30e19276bd60ebcc23a5fb
2019-08-15 10:08:36 -07:00
Jun Wu
bdd108a854 cliparser: remove create_args in tests
Summary: The helper function is no longer necessary.

Reviewed By: sfilipco

Differential Revision: D16715455

fbshipit-source-id: 3bf528d3c9f18418724793edebf298425a3bba87
2019-08-15 10:08:36 -07:00
Stefan Filip
135670fdc3 encoding: fix empty path handling on windows
Summary:
The Windows API `MultiByteToWideChar` will fail when given an empty bytearray to convert.
https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar

Reviewed By: quark-zju

Differential Revision: D16820239

fbshipit-source-id: 3234c3246c0d07277968dac1ac9ee864b016a40f
2019-08-14 19:01:34 -07:00
Jun Wu
2ee74da41f cliparser: rename ParseOutput::get to pick and make it do the unwrap
Summary:
Previously, `get` returns an `Option<T>`. Almost all callers use `unwrap`
immediately, since they know what flag names are available. Let's just
move the `unwrap` inside the function. `get` in the Rust (and Python)
eco-system is considered nullable and panic-free. Rename it to `pick`
to make the difference more obvious.

I considered using the `Index` trait, but it has to return a reference,
which does not fit into this use-case.

Reviewed By: sfilipco

Differential Revision: D16715453

fbshipit-source-id: f754d208c4a1b0adeddaee82c7db82c790d6436c
2019-08-14 16:58:29 -07:00
Jun Wu
9fbefb5981 cliparser: remove ParseOutput::get_or_default
Summary:
The default value of a flag is already provided with the flag. Therefore
`get_or_default` requiring another `default` does not make much sense.
Remove it.

Reviewed By: farnz

Differential Revision: D16713531

fbshipit-source-id: 95a55289077b7308083b6685f013d1058419a675
2019-08-14 16:58:29 -07:00
Jun Wu
f5cba1eeff cliparser: make ParseOutput::get typed
Summary:
This simplifies a lot of code. For example:

    - let config_path: Vec<String> = result.get("config").unwrap().clone().try_into().unwrap();
    + let config_path: Vec<String> = result.get("config").unwrap();

Also, the use of `TryInto` does not make sense - the code only implements
`Into`, and `TryInto` will panic. Therefore remove `TryInto`.

Reviewed By: farnz

Differential Revision: D16713534

fbshipit-source-id: 29dc71881dd844fa87e086543fb0a3bb5d8837a1
2019-08-14 16:58:28 -07:00
Jun Wu
4a585cf0f3 cliparser: support underscore names in define_flags macro
Summary:
Replace `_` in field names to `-` as long flag name. That is consistent with
the current hg behavior.

Reviewed By: sfilipco, farnz

Differential Revision: D16713530

fbshipit-source-id: ce36caebc6b3131cb418d86ca0fdc507d2d8f17f
2019-08-14 16:58:28 -07:00
Jun Wu
c9b69cdf2a cliparser: support defining short names in define_flags macro
Summary: Add rules to match `#[short('x')]` attributes.

Reviewed By: sfilipco

Differential Revision: D16713537

fbshipit-source-id: eaefd34ef51e64a755920feb402547adf9de96f8
2019-08-14 16:58:28 -07:00
Jun Wu
ca432367ca cliparser: support implicit default in define_flags macro
Summary: Add a rule to match implicit default value.

Reviewed By: sfilipco

Differential Revision: D16713533

fbshipit-source-id: 168fb59ee5607d5ae2c0d848943cbc8f55bdfb82
2019-08-14 16:58:27 -07:00
Jun Wu
11b414bccf cliparser: make define_flags stateful
Summary:
Change the macro to have state so we can parse fields one by one with different
syntax.

Reviewed By: sfilipco

Differential Revision: D16713536

fbshipit-source-id: 7f8cb63cfa0ea000c2c2a431454c2d88d49b9187
2019-08-14 16:58:27 -07:00
Jun Wu
6c3314110c cliparser: add define_flags macro
Summary:
This macro provides `Vec<Flag>` and implements `From<ParseOutput>` for a
struct intended to be used as command options.

The core macro is just 21 lines. Both structopt-derive and gumdrop_derive have
1000+ lines.

Of course, it lacks of features.  Some of those features are:

- No way to provide a "short flag".
- Default values have to be explicitly written.
- No way to compose structs (ex. reuse DiffOpts)
- Should "args" be part of the structure?
- Should "command help" be part of the structure?

Reviewed By: sfilipco

Differential Revision: D16713535

fbshipit-source-id: e8137e5f110ebb280fc40f84dace7b1d3a346c82
2019-08-14 16:58:27 -07:00
Adam Simpkins
bc17aecb54 fix a typo in an error message
Summary: mispelling

Reviewed By: xavierd

Differential Revision: D16811713

fbshipit-source-id: 26df600dd028d2c36fc8993c2b281db8310b890a
2019-08-14 14:28:48 -07:00
Thomas Orozco
e4b3f59969 mononoke: getpackv2 LFS support (+ getfiles / getpack / eden_get_data refactor)
Summary:
This updates Mononoke to support LFS metadata when serving data over getpackv2.

However, in doing so, I've also refactored the various ways in which we currently access file data to serve it to clients or to process client uploads (when we need to compute deltas). The motivation to do that is that we've had several issues recently where some protocols knew about some functionality, and others didn't. Notably, redaction and LFS were supported in getfiles, but neither of them were supported in getpack or eden_get_data.

This patch refactors all those callsites away from blobrepo and instead through repo_client/remotefilelog, which provides an internal common method to fetch a filenode and return its metadata and bytes (prepare_blob), and separate protocol specific implementations for getpackv1 (includes metadata + file content -- this is basically the existing fetch_raw_filenode_bytes function), getpackv2 (includes metadata + file contents + getpackv2 metadata), getfiles (includes just file content, and ties file history into its response) and eden_get_data (which uses getpackv1).

Here are a few notable changes here that are worth noting as you review this:

- The getfiles method used to get its filenode from get_maybe_draft_filenode, but all it needed was the copy info. However, the updated method gets its filenode from the envelope (which also has this data). This should be equivalent.
- I haven't been able to remove fetch_raw_filenode_bytes yet because there's a callsite that still uses it and it's not entirely clear to me whether this is used and why. I'll look into it, but for now I left it unchanged.
- I've used the Mercurial implementation of getpack metadata here. This feels like the better approach so we can reuse some of the code, but historically I don't think we've depended on many Mercurial crates. Let me know if there's a reason not to do that.

Finally, there are a couple things to be aware of as you review:

- I removed some more `Arc<BlobRepo>` in places where it made it more difficult to call the new remotefilelog methods.
- I updated the implementation to get copy metadata out of a file envelope to not require copying the metadata into a mercurial::file::File only to immediately discard it.
- I cleaned up an LFS integration test a little bit. There are few functional changes there, but it makes tests a little easier to work with.

Reviewed By: farnz

Differential Revision: D16784413

fbshipit-source-id: 5c045d001472fb338a009044ede1e22ccd34dc55
2019-08-14 08:49:22 -07:00
Jun Wu
89f4c87413 indexedlog: remove ChecksumType::None
Summary:
We have seen a case where the blackbox log file contains chunks of zeros where
it shouldn't. Right now, 2 zero bytes are a valid log entry (the first byte
indicates "no checksum", the second indicates the entry has length 0). That
means corruptions in the log file produces valid zero-sized entries. That in
turn can cause issues - some index functions assume the log entries to have at
least some bytes, or they will panic.

Given the fact that:
- `ChecksumType::None` is not actually used.
- The cost of calculating the checksum is negligible comparing to index
  lookups.

Let's just remove the `ChecksumType::None` feature so every entry is enforced
checksum verified.

Regarding on blackbox, it already has proper error handling to deal with
corrupted indexedlogs.

Reviewed By: DurhamG

Differential Revision: D16773741

fbshipit-source-id: f0c55b34c3c92d55baa3b54560c2ac5549987a51
2019-08-12 19:23:07 -07:00
Kostia Balytskyi
2023ba8d8b redaction: handle redacted content coming from the EdenAPI
Summary:
In some cases, the file we are trying to fetch from the EdenAPI can be
redacted. We need to handle those cases. The good way to do so would be to
support this on a protocol level, but that is a *lot* of work. For now,
we are using the "tombstone approach", in which the ApiServer reacts to
redaction errors by injecting a special "tomstone" content, which the client
needs to recognize as not an error, but as a special case. In particular,
it needs to not fail the validation.

Reviewed By: markbt

Differential Revision: D16752747

fbshipit-source-id: 1bf126d50ecd6b862954284461b7db8f51e7e891
2019-08-12 08:04:58 -07:00
Jun Wu
217c236090 dag: make ancestor APIs take a set
Summary:
Previously, `ancestors` only takes a single id, `gca_one` and `gca_all` only
take 2 ids. Extend them to accept a set. This is more consistent with the rest
of the APIs, ex. `heads` and `parents`.

Reviewed By: markbt, sfilipco

Differential Revision: D16672417

fbshipit-source-id: 98297486cb01215479e0e16f2189cf3053d60a1d
2019-08-09 16:17:53 -07:00
Jun Wu
92b5e9c5ab dag: implement "heads"
Summary: By defination, `heads(x) = x - parents(x)`.

Reviewed By: markbt

Differential Revision: D16672424

fbshipit-source-id: 63109eb9aabf65d82677f6e1582fab1c184c2ef4
2019-08-09 16:17:53 -07:00
Jun Wu
8d37ad1b09 dag: implement "parents"
Summary: As the title. It uses segments to speed up the calculation.

Reviewed By: markbt, sfilipco

Differential Revision: D16672422

fbshipit-source-id: 4c66b4db031a4f1da6ce3f3ac802efa093c65f3a
2019-08-09 16:17:53 -07:00
Jun Wu
f1b4cbece3 dag: extract some ASCII dags to static constants
Summary: Make them reusable for different tests.

Reviewed By: sfilipco

Differential Revision: D16672419

fbshipit-source-id: fc0bfbde833928620c13ba910c0bb2f2259e8714
2019-08-09 16:17:52 -07:00
Jun Wu
e1fa27f55c dag: add more utilities around SpanSet
Summary:
- from_span: Some create SpanSet using a single span, handy.
- push_set: Faster than `union` for certain cases.
- as_spans: provide fast paths for certain cases, ex. `set(id-1 for id in oldset)`.
- into: later the ancestor-related API will migrate to `impl Into<SpanSet>`,
  this allows syntax like `gca_one((a, b))`.

Reviewed By: sfilipco

Differential Revision: D16672423

fbshipit-source-id: 5b0e46d18c9bdb7a68e5edf1552e1699a5bf672a
2019-08-09 16:17:52 -07:00
Jun Wu
2fad9d7697 dag: make SpanSet::contains test Span
Summary:
Previously, `SpanSet::contains` can only test one `Id`. Change it to be able to
test a `Span`. This will be used in `Dag::parents` implementation.

Reviewed By: sfilipco

Differential Revision: D16672425

fbshipit-source-id: 769196b53b61c05b8a15537292cc1c24cd86013c
2019-08-09 16:17:52 -07:00
Jun Wu
5e139252d3 dag: implement segment::Dag::Debug
Summary:
Move the debug logic from test code to segment.rs so it can be used in the
Python bindings for debugging purposes.

Reviewed By: sfilipco

Differential Revision: D16672418

fbshipit-source-id: 9d2fef58ecc77167bdc44167ad14b58cb8eebc18
2019-08-09 16:17:52 -07:00
Jun Wu
0099d73ea1 dag: add more ancestor-related operations
Summary:
The existing hg APIs support things like getting all the gcas, and testing
"isancestor" without calcuating the gca. Implement them in the dag crate to
match those features.

I picked `gca` to make names shorter. Here is a list of how those features
get named in two codebases:

  Name in hg codebase  | Name in this crate
  -----------------------------------------
  ancestor             | gca_one
  commonancestorsheads | gca_all
  isancestor           | is_ancestor
  ancestors            | ancestors

Reviewed By: markbt, sfilipco

Differential Revision: D16672420

fbshipit-source-id: d205d7970623e992e656ae300218239cddbd26c8
2019-08-09 16:17:51 -07:00
Jun Wu
11417edf07 dag: add benchmark about various "segment size" choices
Summary:
Add a benchmark testing various segment sizes - time to build segments, log
size, and ancestor calcuation performance. An initial output looks like:

  building segment_size=4                             0.223 ms segments: [34859, 10972, 3156, 834, 218, 55, 13, 3]  log len: 1194609
  ancestor calcuation segment_size=4                  1.510 s
  building segment_size=8                             0.193 ms segments: [34859, 5472, 737, 95, 11, 1]  log len: 958272
  ancestor calcuation segment_size=8                  1.630 s
  building segment_size=10                            0.213 ms segments: [34859, 4339, 460, 46, 4]  log len: 918468
  ancestor calcuation segment_size=10                 1.739 s
  building segment_size=12                            0.187 ms segments: [34859, 3613, 316, 26, 2]  log len: 893901
  ancestor calcuation segment_size=12                 1.934 s
  building segment_size=14                            0.202 ms segments: [34859, 3034, 228, 16, 1]  log len: 873677
  ancestor calcuation segment_size=14                 2.311 s
  building segment_size=16                            0.199 ms segments: [34859, 2601, 172, 10]  log len: 858211
  ancestor calcuation segment_size=16                 2.139 s
  building segment_size=18                            0.193 ms segments: [34859, 2280, 133, 7]  log len: 847505
  ancestor calcuation segment_size=18                 2.301 s
  building segment_size=20                            0.175 ms segments: [34859, 2043, 105, 5]  log len: 839458
  ancestor calcuation segment_size=20                 2.335 s
  building segment_size=22                            0.187 ms segments: [34859, 1847, 85, 3]  log len: 832764
  ancestor calcuation segment_size=22                 2.500 s
  building segment_size=24                            0.206 ms segments: [34859, 1668, 71, 2]  log len: 826775
  ancestor calcuation segment_size=24                 2.570 s
  building segment_size=32                            0.194 ms segments: [34859, 1230, 38, 1]  log len: 811701
  ancestor calcuation segment_size=32                 3.091 s
  building segment_size=64                            0.215 ms segments: [34859, 598, 9]  log len: 790230
  ancestor calcuation segment_size=64                 4.215 s
  building segment_size=128                           0.281 ms segments: [34859, 293, 2]  log len: 779475
  ancestor calcuation segment_size=128                7.573 s

It seems segment size = 8 to 20 might be a reasonable choice.

Reviewed By: sfilipco

Differential Revision: D16660078

fbshipit-source-id: f8af64c703ce0209b9b4c09112c9bdc4a1371172
2019-08-09 16:17:51 -07:00
Jun Wu
ea320633a6 dag: return number of segments inserted
Summary:
This makes it possible to detect cases where it's no longer necessary to build
higher level segments.

Reviewed By: markbt

Differential Revision: D16683579

fbshipit-source-id: 77a0c2c1339616ee47778e4d0ab5ababb94e6bed
2019-08-09 16:17:51 -07:00
Jun Wu
ef271b55d6 dag: check in the mozilla-central DAG for experiments
Summary:
Use the bindag format to store the DAG from mozilla-central. The bindag file
was generated by:

  hg clone https://hg.mozilla.org/mozilla-central/
  cd mozilla-central
  hg debugbindag -o mozilla-central.bindag -r '::48797c5119a4d7fd1ff533501b6f80009cd3498c'

The file will be used to benchmark some parameters of the segment DAG.

Reviewed By: sfilipco

Differential Revision: D16660076

fbshipit-source-id: 4218e3d973e0b2847504733ae850d060b62bf729
2019-08-09 16:17:51 -07:00
Jun Wu
e14145c92c minibench: add a way to provide adhoc messages for measurement
Summary: This is useful where the user wants to define their own messages.

Reviewed By: markbt

Differential Revision: D16683580

fbshipit-source-id: 029e3b7720af7e53cb2b5b5efb1ebdd8ac940b67
2019-08-09 16:17:50 -07:00
Jun Wu
1fb7402aba minibench: relax the type of function to FnMut
Summary:
Previously, the function has the type `Fn`, which is less flexible.
Change it to `FnMut` so the function can have some side effects to
its environment.

Reviewed By: sfilipco

Differential Revision: D16660079

fbshipit-source-id: ef6b3e1688d265538df4fc67dccf5217125d0d15
2019-08-09 16:17:50 -07:00
Jun Wu
95de965102 minibench: relax the type of name
Summary: Previously, `name` is `&str`. Change it to `impl ToString` to be more flexible.

Reviewed By: sfilipco

Differential Revision: D16660075

fbshipit-source-id: c5c88f6ffd7788e0a2cef95713b7e48c127c7a3d
2019-08-09 16:17:50 -07:00
Jun Wu
26f6e2e3b2 dag: avoid stack overflow in assign_head
Summary:
In case there are too many merges, the function will stack overflow.

Avoid it by emulating the stack. The heuristic to optimize certain
cases is removed to simplify the code.

Reviewed By: sfilipco

Differential Revision: D16660077

fbshipit-source-id: 6491227e76374548b25a0804fd71a630d392adb9
2019-08-09 16:17:50 -07:00
Xavier Deguillard
825881eefb revisionstore: remove loosefile.rs
Summary: We never used this, and loosefiles are pretty much gone, let's remove the code.

Reviewed By: quark-zju

Differential Revision: D16726160

fbshipit-source-id: f810356a0a9cd980d8e5306bc967c3f25475afa6
2019-08-09 10:19:20 -07:00
Jun Wu
f5e6c0a966 hgcommands: move commands from hgmain
Summary:
Move commands.rs from hgmain to hgcommands so it can be reused in other places
(ex. bindings)

Reviewed By: farnz

Differential Revision: D16713532

fbshipit-source-id: f3ff66796df8c8e775f62a707f4c582d48fdd1ad
2019-08-08 22:54:10 -07:00
Jun Wu
3a7f54dffe lib: rename hgpython to hgcommands
Summary:
Upcoming patches will move hg command implementations from exec/hgmain to
lib/hgcommands. That has two benefits:

- The `bindings` crate can use `hgcommands` to call Rust commands from Python.
- Solve a link issue about CPython APIs. Right now, if `hgmain` depend
  on *multiple* libraries that depend on `cpython`, there will be a link error
  with `cargo build` complaining about lots of CPython APIs do not exist.
  With this change, `hgcommands` will be the only crate that `hgmain` depends
  on, therefore no such link issues.

Reviewed By: farnz

Differential Revision: D16713538

fbshipit-source-id: 3b0def6eec4870858cdb74ad1b3099dc4cbc42b2
2019-08-08 22:54:09 -07:00
Jun Wu
efa3a4e9c4 clidispatch: do not flush in IO::write
Summary:
`flush` can be an expensive operation if called frequently for certain `Write`
implementations (ex. stdio). Provide an explicit `flush` function and call
it on drop.

Reviewed By: farnz

Differential Revision: D16706191

fbshipit-source-id: 50521de9b67f4021844326f6337730f1212c221e
2019-08-08 22:54:09 -07:00
Jun Wu
2daff2a37f clidispatch: remove IO::write_str
Summary:
The current `write_str` can be easily merged into `write`. Although difficult
questions remain:

- What's the acceptable encoding of the stream?
- Who should do the encoding convertion?

Since the Python code path just assumes `ui.fout` talks bytes, let's just
assume the same thing here. We probably want to audit the behavior of native
Rust code using `IO::write`.

Reviewed By: farnz

Differential Revision: D16706187

fbshipit-source-id: 97ac0e2be1ddac15e608619a393191b9c82c835a
2019-08-08 22:54:09 -07:00
Jun Wu
72e6c7eb70 clidispatch: rename IO::default to IO::stdio
Summary:
It's unclear whether the default of IO should be redirecting everything to
null, or the stdio. Let's make stdio an explicit function to clarify.

Reviewed By: farnz

Differential Revision: D16706190

fbshipit-source-id: 618479abe8cef29efa4206f8cd1e1115107f37b8
2019-08-08 22:54:08 -07:00
Jun Wu
1de20a1581 clidispatch: add error stream to IO
Summary:
Otherwise there is no way to write to stderr via IO.

Also reorder the fields so it's "input, output, error" order.

Reviewed By: farnz

Differential Revision: D16706188

fbshipit-source-id: eb80716101978fdbf9ca1c8f02e03f806c9e26f1
2019-08-08 22:54:08 -07:00
Jun Wu
37c696c443 cliparser: stop using vendored shlex
Summary:
The vendored shlex crate was used to unblock progress. Now that `shlex`
is available in tp2 crate, let's drop the vendored shlex.

Reviewed By: farnz

Differential Revision: D16706184

fbshipit-source-id: f110ee91d8c9cc61b94fbafbf269f260bd73fd70
2019-08-08 22:54:08 -07:00
Jun Wu
3dc0224a53 hgpython: simplify set_command_table
Summary:
Remove unnecessary clones. I also don't think we will have a command
implemented in both Python and Rust. The flag and command definition
should only exist in one language. If Rust needs to fallback to Python,
it should probably just call `cmdutil...` instead of falling back
to a full Python command.

Reviewed By: farnz

Differential Revision: D16706185

fbshipit-source-id: c4248adffb4d0ea039563edf0fa21ebd03d53455
2019-08-08 22:54:07 -07:00