-
Notifications
You must be signed in to change notification settings - Fork 482
Migration tool fixes #8157
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?
Migration tool fixes #8157
Changes from 6 commits
f9e1c93
2eaf010
9de4952
72cef3e
f44f5e4
650d0c6
0d98a22
9435093
aaf832c
cef32da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "name": "deprecatedlib", | ||
| "version": "0.0.1", | ||
| "scripts": { | ||
| "build": "rescript-legacy build", | ||
| "clean": "rescript clean" | ||
| }, | ||
| "dependencies": { | ||
| "rescript": "workspace:^" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "name": "deprecatedlib", | ||
| "sources": { "dir": "src", "subdirs": true }, | ||
| "package-specs": { "module": "commonjs", "in-source": true }, | ||
| "suffix": ".res.js" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| @deprecated({ | ||
| reason: "Use `newThing` instead.", | ||
| migrate: DeprecatedDep.newThing(), | ||
| }) | ||
| let oldThing = () => 1 | ||
|
|
||
| let newThing = () => 2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| let value = DeprecatedDep.oldThing() | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| let meaningOfLife = 42 | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| let value = DeprecatedDep.oldThing() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| let meaningOfLife = 42 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,33 @@ open Analysis | |
| module StringMap = Map.Make (String) | ||
| module StringSet = Set.Make (String) | ||
| module IntSet = Set.Make (Int) | ||
| module FileSet = SharedTypes.FileSet | ||
|
|
||
| let filter_deprecations_for_project ?package ?dependency_paths ~entryPointFile | ||
| ~deprecated_used = | ||
| let canonical p = try Unix.realpath p with _ -> p in | ||
| let package = | ||
| match package with | ||
| | Some p -> Some p | ||
| | None -> | ||
| let uri = Uri.fromPath entryPointFile in | ||
| Packages.getPackage ~uri | ||
| in | ||
| match package with | ||
| | None -> deprecated_used | ||
| | Some package -> | ||
| let dependency_paths = | ||
| match dependency_paths with | ||
| | Some paths -> paths | ||
| | None -> | ||
| FileSet.fold | ||
| (fun p acc -> acc |> FileSet.add p |> FileSet.add (canonical p)) | ||
| package.dependenciesFiles FileSet.empty | ||
| in | ||
| deprecated_used | ||
| |> List.filter (fun (d : Cmt_utils.deprecated_used) -> | ||
| let loc_path = canonical d.source_loc.Location.loc_start.pos_fname in | ||
| not (FileSet.mem loc_path dependency_paths)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The dependency filter is keyed off Useful? React with 👍 / 👎.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How would you suggest fixing this?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @codex verify that this has been fixed now please. |
||
|
|
||
| (* Public API: migrate ~entryPointFile ~outputMode *) | ||
|
|
||
|
|
@@ -736,18 +763,14 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = | |
| in | ||
| mapper | ||
|
|
||
| let migrate ~entryPointFile ~outputMode = | ||
| let migrate ?package ?dependency_paths ~outputMode entryPointFile = | ||
| let path = | ||
| match Filename.is_relative entryPointFile with | ||
| | true -> Unix.realpath entryPointFile | ||
| | false -> entryPointFile | ||
| in | ||
| let result = | ||
| if Filename.check_suffix path ".res" then | ||
| let parser = | ||
| Res_driver.parsing_engine.parse_implementation ~for_printer:true | ||
| in | ||
| let {Res_driver.parsetree; comments; source} = parser ~filename:path in | ||
| match Cmt.loadCmtInfosFromPath ~path with | ||
| | None -> | ||
| Error | ||
|
|
@@ -756,31 +779,43 @@ let migrate ~entryPointFile ~outputMode = | |
| could not be found. try to build the project" | ||
| path) | ||
| | Some {cmt_extra_info = {deprecated_used}} -> | ||
| let mapper = makeMapper deprecated_used in | ||
| let astMapped = mapper.structure mapper parsetree in | ||
| (* Second pass: apply any post-migration transforms signaled via @apply.transforms *) | ||
| let apply_transforms = | ||
| let expr mapper (e : Parsetree.expression) = | ||
| let e = Ast_mapper.default_mapper.expr mapper e in | ||
| MapperUtils.ApplyTransforms.apply_on_self e | ||
| in | ||
| {Ast_mapper.default_mapper with expr} | ||
| let deprecated_used = | ||
| filter_deprecations_for_project ~entryPointFile:path ~deprecated_used | ||
| ?package ?dependency_paths | ||
| in | ||
| let astTransformed = | ||
| apply_transforms.structure apply_transforms astMapped | ||
| in | ||
| Ok | ||
| ( Res_printer.print_implementation | ||
| ~width:Res_printer.default_print_width astTransformed ~comments, | ||
| source ) | ||
| if Ext_list.is_empty deprecated_used then | ||
| match outputMode with | ||
| | `Stdout -> | ||
| let source = Res_io.read_file ~filename:path in | ||
| Ok (`Unchanged source) | ||
| | `File -> Ok (`Unchanged "") | ||
| else | ||
| let parser = | ||
| Res_driver.parsing_engine.parse_implementation ~for_printer:true | ||
| in | ||
| let {Res_driver.parsetree; comments; source} = | ||
| parser ~filename:path | ||
| in | ||
| let mapper = makeMapper deprecated_used in | ||
| let astMapped = mapper.structure mapper parsetree in | ||
| (* Second pass: apply any post-migration transforms signaled via @apply.transforms *) | ||
| let apply_transforms = | ||
| let expr mapper (e : Parsetree.expression) = | ||
| let e = Ast_mapper.default_mapper.expr mapper e in | ||
| MapperUtils.ApplyTransforms.apply_on_self e | ||
| in | ||
| {Ast_mapper.default_mapper with expr} | ||
| in | ||
| let astTransformed = | ||
| apply_transforms.structure apply_transforms astMapped | ||
| in | ||
| let contents = | ||
| Res_printer.print_implementation | ||
| ~width:Res_printer.default_print_width astTransformed ~comments | ||
| in | ||
| if contents = source then Ok (`Unchanged source) | ||
| else Ok (`Changed contents) | ||
| else if Filename.check_suffix path ".resi" then | ||
| let parser = | ||
| Res_driver.parsing_engine.parse_interface ~for_printer:true | ||
| in | ||
| let {Res_driver.parsetree = signature; comments; source} = | ||
| parser ~filename:path | ||
| in | ||
|
|
||
| match Cmt.loadCmtInfosFromPath ~path with | ||
| | None -> | ||
| Error | ||
|
|
@@ -789,9 +824,29 @@ let migrate ~entryPointFile ~outputMode = | |
| could not be found. try to build the project" | ||
| path) | ||
| | Some {cmt_extra_info = {deprecated_used}} -> | ||
| let mapper = makeMapper deprecated_used in | ||
| let astMapped = mapper.signature mapper signature in | ||
| Ok (Res_printer.print_interface astMapped ~comments, source) | ||
| let deprecated_used = | ||
| filter_deprecations_for_project ~entryPointFile:path ~deprecated_used | ||
| ?package ?dependency_paths | ||
| in | ||
| if Ext_list.is_empty deprecated_used then | ||
| match outputMode with | ||
| | `Stdout -> | ||
| let source = Res_io.read_file ~filename:path in | ||
| Ok (`Unchanged source) | ||
| | `File -> Ok (`Unchanged "") | ||
| else | ||
| let parser = | ||
| Res_driver.parsing_engine.parse_interface ~for_printer:true | ||
| in | ||
| let {Res_driver.parsetree = signature; comments; source} = | ||
| parser ~filename:path | ||
| in | ||
|
|
||
| let mapper = makeMapper deprecated_used in | ||
| let astMapped = mapper.signature mapper signature in | ||
| let contents = Res_printer.print_interface astMapped ~comments in | ||
| if contents = source then Ok (`Unchanged source) | ||
| else Ok (`Changed contents) | ||
| else | ||
| Error | ||
| (Printf.sprintf | ||
|
|
@@ -800,15 +855,17 @@ let migrate ~entryPointFile ~outputMode = | |
| in | ||
| match result with | ||
| | Error e -> Error e | ||
| | Ok (contents, source) when contents <> source -> ( | ||
| | Ok (`Unchanged source) -> ( | ||
| match outputMode with | ||
| | `Stdout -> Ok contents | ||
| | `Stdout -> Ok (`Unchanged source) | ||
| | `File -> | ||
| Ok (`Unchanged (Filename.basename path ^ ": File did not need migration")) | ||
| ) | ||
| | Ok (`Changed contents) -> ( | ||
| match outputMode with | ||
| | `Stdout -> Ok (`Changed contents) | ||
| | `File -> | ||
| let oc = open_out path in | ||
| Printf.fprintf oc "%s" contents; | ||
| close_out oc; | ||
| Ok (Filename.basename path ^ ": File migrated successfully")) | ||
| | Ok (contents, _) -> ( | ||
| match outputMode with | ||
| | `Stdout -> Ok contents | ||
| | `File -> Ok (Filename.basename path ^ ": File did not need migration")) | ||
| Ok (`Changed (Filename.basename path ^ ": File migrated successfully"))) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,13 @@ | ||
| val migrate : | ||
| entryPointFile:string -> | ||
| ?package:Analysis.SharedTypes.package -> | ||
| ?dependency_paths:Analysis.SharedTypes.FileSet.t -> | ||
| outputMode:[`File | `Stdout] -> | ||
| (string, string) result | ||
| string -> | ||
| ([`Changed of string | `Unchanged of string], string) result | ||
|
|
||
| val filter_deprecations_for_project : | ||
| ?package:Analysis.SharedTypes.package -> | ||
| ?dependency_paths:Analysis.SharedTypes.FileSet.t -> | ||
| entryPointFile:string -> | ||
| deprecated_used:Cmt_utils.deprecated_used list -> | ||
| Cmt_utils.deprecated_used list |
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 redirection order
2>&1 > $outputredirects stderr to the original stdout before stdout is sent to the file, so stderr still goes to the terminal and will not appear in the expected output. This contradicts the comment and means warnings won’t be captured by the test; use> $output 2>&1(or an equivalent pipe) to combine the streams.Useful? React with 👍 / 👎.