-
Notifications
You must be signed in to change notification settings - Fork 374
opam update
: load only changed opam files
#6614
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
c0d8002
to
ba9b12a
Compare
2cb1720
to
3136926
Compare
Updated simplfying a bunch of things. |
I'm not sure to follow, pre-processing isn't done for http/local (per apply_repo_update) |
You're right, my bad. So we can reuse the diffs avoiding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass of review. I haven't looked at everything yet but i think that's enough for now
| Some opams -> opams | ||
| None -> OpamPackage.Map.empty | ||
in | ||
let process_file acc file ~is_removal = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it's done elsewhere or something, but this function seems to assume every files that can change are opam files. What about changes from their files
directory or other non-opam file related changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function purpose is to load opam files to update their definitions in rt
, all other files are ignored as it was already the case with original load_opams_from_dir
function. Any other extra files are read by OpamFileTools.read_repo_opam
and stored through metadata
@@ -0,0 +1,181 @@ | |||
N0REP0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests should be added all at once in the first commit of the PR, ran to unsure the initial state is correct, then ran again for each new commits to show new behaviours
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have a reftest called update.test
i think it should probably go there instead
f0a731c
to
0cfb4a3
Compare
0cfb4a3
to
6b19d06
Compare
6b19d06
to
74dbeb6
Compare
OpamConsole.msg "[%s] synchronised from %s\n" | ||
(OpamConsole.colorise `green | ||
(OpamRepositoryName.to_string repo.repo_name)) | ||
(OpamUrl.to_string repo.repo_url); | ||
log "%a: applying patch update at %a" | ||
(slog OpamRepositoryName.to_string) repo.repo_name | ||
(slog OpamFilename.to_string) f; | ||
let preprocess = | ||
match repo.repo_url.OpamUrl.backend with | ||
| `http | `rsync -> false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't think we should start running the the preprocessing for local and http repositories. Could you bring the ?preprocess
argument back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this PR depends on the completion of #6599 first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not, this is naturally done by the fact that OpamSystem.parse_patch_file
is only called in OpamVCS
(in OpamAction.prepare_package_build
as well, but that's a different story), for local and http repositories we reuse the diffs directly.
@@ -0,0 +1,181 @@ | |||
N0REP0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have a reftest called update.test
i think it should probably go there instead
@@ -67,7 +67,7 @@ let repository rt repo = | |||
in | |||
OpamProcess.Job.with_text text @@ | |||
OpamRepository.update r repo_root @@+ fun has_changes -> | |||
let has_changes = if redirect then `Changes else has_changes in | |||
let has_changes = if redirect then `Changes [] else has_changes in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### <REPO/packages/foo/foo.1/opam> | ||
opam-version: "2.0" | ||
synopsis: "Updated package" | ||
### opam update default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be nice if the new incremental behaviour was shown in the test. We could select the right OPAMDEBUGSECTION to show that only a limited number of files are being read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let internal_patch_error fmt = | ||
Printf.ksprintf (fun str -> raise (Internal_patch_error str)) fmt | ||
in | ||
let patch_info_path = | ||
OpamStd.Option.default ("in directory"^dir) patch_filename |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpamStd.Option.default ("in directory"^dir) patch_filename | |
OpamStd.Option.default ("in directory "^dir) patch_filename |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be updated on rebase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm overall, however it's a hard PR to review without its final clean commit structure so i'd rather wait for whenever this is finished.
I also think this PR should be queued on a PR adding a benchmark test for opam update as we currently don't have any. It would ideal to have a test for three kinds of cases:
- no diff
- small diff (just a few files)
- large diff (e.g. from ocaml/opam-repository#2025-01-before-archiving-phase1 to now)
with both local path and local git repositories
@@ -382,15 +382,14 @@ let diff_patch dir setup = | |||
let apply ~git diff = | |||
let git = if git then "GIT " else "" in | |||
let result = | |||
OpamFilename.patch ~allow_unclean:false diff | |||
(dir / first) | |||
OpamFilename.patch ~allow_unclean:false(`Patch_file diff) (dir / first) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> 80 characters + minor missing space
OpamFilename.patch ~allow_unclean:false(`Patch_file diff) (dir / first) | |
OpamFilename.patch ~allow_unclean:false (`Patch_file diff) | |
(dir / first) |
| Some patch_file -> | ||
let p = OpamFilename.to_string patch_file in | ||
try | ||
let diffs = OpamSystem.parse_patch_file | ||
~dir:(OpamFilename.Dir.to_string repo_root) p in | ||
OpamRepositoryBackend.Update_patch (patch_file, diffs) | ||
with exn -> Update_err exn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we had OpamFilename.parse_patch_file
for a more OpamFilename
friendly API we could simplify to:
| Some patch_file -> | |
let p = OpamFilename.to_string patch_file in | |
try | |
let diffs = OpamSystem.parse_patch_file | |
~dir:(OpamFilename.Dir.to_string repo_root) p in | |
OpamRepositoryBackend.Update_patch (patch_file, diffs) | |
with exn -> Update_err exn | |
| Some patch_file -> | |
match OpamFilename.parse_patch_file ~dir:repo_root patch_file with | |
| diffs -> OpamRepositoryBackend.Update_patch (patch_file, diffs) | |
| exception exn -> Update_err exn |
| Patch.Create f -> Patch.Create (rm_prefix f) | ||
| Patch.Delete f -> Patch.Delete (rm_prefix f) | ||
| Patch.Edit (f1, f2) -> Patch.Edit (rm_prefix f1, rm_prefix f2) | ||
| Patch.Git_ext (f1, f2, ext) -> Patch.Git_ext (rm_prefix f1, rm_prefix f2, ext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> 80 columns
| Patch.Git_ext (f1, f2, ext) -> Patch.Git_ext (rm_prefix f1, rm_prefix f2, ext) | |
| Patch.Git_ext (f1, f2, ext) -> | |
Patch.Git_ext (rm_prefix f1, rm_prefix f2, ext) |
Now run 'opam upgrade' to apply any package updates. | ||
### <REPO/repo> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### <REPO/repo> | |
### : Test incrementality | |
### rm -rf REPO | |
### <REPO/repo> |
This PR leverages the fact that we already compute a diff/patch during update to determine exactly which files have changed and it what way. Instead of reloading the entire repository we:
Patch.operation
info fromOpamFilename.patch
OpamRepositoryState.load_opams_incremental
On Windows the
OpamRepositoryState.load_opams_from_dir
inOpamUpdate.repository
currently takes ~10s. This PR brings it down to ~0.01s (the time it takes to load the opam files of a usual repository change).On unix, it is a bit less dramatic, but still going from ~3.5s to 1ms
closes #5824