On Sun, Mar 18, 2018 at 10:17 PM, <thepudds1...@gmail.com> wrote: > Hi Anuj, > > Two quick comments. > > 1. FYI, in case you didn't see this in the recent vgo dependency > management discussion, go fix might start to be used much more broadly in > the not-too-distant future across the go community as a way to help > automate in some cases the ability to update client code as a way to help > manage API changes, somewhat similar to how go fix was used by the core go > team before go 1.0. See the snippet pasted below from one of rsc's recent > blog posts, or visit that link for a longer discussion. Not yet > implemented, but could be very nice if it happens. > > 2. I'm mildly curious what type of changes you are trying to do, including > what aspect of your intended changes makes it such that the simpler 'gofmt > -r' automated refactoring or the more flexible 'eg' example-based > refactoring tool (from the go team) aren't applicable. The 'eg' help is > mildly annoying to track down via godoc, so forgive the volume of text but > I pasted in the main help text below from 'eg' at the bottom of this post. > 'eg' is focused on expression-level changes, so perhaps that is one reason > it might not be applicable for you, but as I said I'm a bit curious about > the specifics of your case... > > Thanks, I will try it out and will post here if I find a case where it does not work. I had read the gofix blog <https://blog.golang.org/introducing-gofix> and thought it should solve my problem.
> ======================================================== > from https://research.swtch.com/vgo-import > ======================================================== > Before Go 1, we relied heavily on go fix, which users ran after updating > to a new Go release and finding their programs no longer compiled. > > ... > > The ability to name and work with multiple incompatible versions of a > package in a single program suggests a possible solution: if a v1 API > function can be implemented as a wrapper around the v2 API, the wrapper > implementation can double as the fix specification. For example, suppose v1 > of an API has functions EnableFoo and DisableFoo and v2 replaces the pair > with a single SetFoo(enabled bool). After v2 is released, v1 can be > implemented as a wrapper around v2: > > package p // v1 > > import v2 "p/v2" > > func EnableFoo() { > //go:fix > v2.SetFoo(true) > } > > func DisableFoo() { > //go:fix > v2.SetFoo(false) > } > > The special //go:fix comments would indicate to go fix that the wrapper > body that follows should be inlined into the call site. Then running go fix > would rewrite calls to v1 EnableFoo to v2 SetFoo(true). The rewrite is > easily specified and type-checked, since it is plain Go code. > ======================================================== > > > ======================================================== > from golang/tools eg help via https://github.com/golang/ > tools/blob/release-branch.go1.10/refactor/eg/eg.go#L20 > ======================================================== > This tool implements example-based refactoring of expressions. > > The transformation is specified as a Go file defining two functions, > 'before' and 'after', of identical types. Each function body consists > of a single statement: either a return statement with a single > (possibly multi-valued) expression, or an expression statement. The > 'before' expression specifies a pattern and the 'after' expression its > replacement. > > package P > import ( "errors"; "fmt" ) > func before(s string) error { return fmt.Errorf("%s", s) } > func after(s string) error { return errors.New(s) } > > The expression statement form is useful when the expression has no > result, for example: > > func before(msg string) { log.Fatalf("%s", msg) } > func after(msg string) { log.Fatal(msg) } > > The parameters of both functions are wildcards that may match any > expression assignable to that type. If the pattern contains multiple > occurrences of the same parameter, each must match the same expression > in the input for the pattern to match. If the replacement contains > multiple occurrences of the same parameter, the expression will be > duplicated, possibly changing the side-effects. > > The tool analyses all Go code in the packages specified by the > arguments, replacing all occurrences of the pattern with the > substitution. > > So, the transform above would change this input: > err := fmt.Errorf("%s", "error: " + msg) > to this output: > err := errors.New("error: " + msg) > > Identifiers, including qualified identifiers (p.X) are considered to > match only if they denote the same object. This allows correct > matching even in the presence of dot imports, named imports and > locally shadowed package names in the input program. > > Matching of type syntax is semantic, not syntactic: type syntax in the > pattern matches type syntax in the input if the types are identical. > Thus, func(x int) matches func(y int). > > This tool was inspired by other example-based refactoring tools, > 'gofmt -r' for Go and Refaster for Java. > > > LIMITATIONS > =========== > > EXPRESSIVENESS > > Only refactorings that replace one expression with another, regardless > of the expression's context, may be expressed. Refactoring arbitrary > statements (or sequences of statements) is a less well-defined problem > and is less amenable to this approach. > > A pattern that contains a function literal (and hence statements) > never matches. > > There is no way to generalize over related types, e.g. to express that > a wildcard may have any integer type, for example. > > It is not possible to replace an expression by one of a different > type, even in contexts where this is legal, such as x in fmt.Print(x). > > The struct literals T{x} and T{K: x} cannot both be matched by a single > template. > > > SAFETY > > Verifying that a transformation does not introduce type errors is very > complex in the general case. An innocuous-looking replacement of one > constant by another (e.g. 1 to 2) may cause type errors relating to > array types and indices, for example. The tool performs only very > superficial checks of type preservation. > > > IMPORTS > > Although the matching algorithm is fully aware of scoping rules, the > replacement algorithm is not, so the replacement code may contain > incorrect identifier syntax for imported objects if there are dot > imports, named imports or locally shadowed package names in the input > program. > > Imports are added as needed, but they are not removed as needed. > Run 'goimports' on the modified file for now. > > Dot imports are forbidden in the template. > > > TIPS > ==== > > Sometimes a little creativity is required to implement the desired > migration. This section lists a few tips and tricks. > > To remove the final parameter from a function, temporarily change the > function signature so that the final parameter is variadic, as this > allows legal calls both with and without the argument. Then use eg to > remove the final argument from all callers, and remove the variadic > parameter by hand. The reverse process can be used to add a final > parameter. > > To add or remove parameters other than the final one, you must do it in > stages: (1) declare a variant function f' with a different name and the > desired parameters; (2) use eg to transform calls to f into calls to f', > changing the arguments as needed; (3) change the declaration of f to > match f'; (4) use eg to rename f' to f in all calls; (5) delete f'. > ======================================================== > > --thepudds > > On Friday, March 16, 2018 at 9:51:58 AM UTC-4, peterGo wrote: >> >> Anuj Agrawal, >> >> Exporting an API carries a commitment to maintain and support that API. >> go fix was a special-purpose command, that was useful before the Go1 >> compatibility guarantee. I can see no reason to export a go fix API. >> Peter >> >> >> On Thursday, March 15, 2018 at 6:20:47 AM UTC-4, Anuj Agrawal wrote: >>> >>> Hi, >>> >>> I am looking to create a gofix for one of my projects. I thought of >>> importing the code in >>> https://github.com/golang/go/tree/master/src/cmd/fix so that I could >>> simply write a plugin, build a binary and give it to people who import >>> my code. >>> >>> However, I do not see any exported symbols in this code. That leaves >>> me with only one choice - that I copy the code and then write the >>> plugin on top of it. That does not sound like a very great idea as >>> compared to being able to import the package itself. >>> >>> Is there any particular reason for not exporting any symbols in the >>> gofix code? >>> >>> Thanks, >>> Anuj Agrawal >>> >> -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.