---
source: src/feeds/atom.rs
expression: result
---
[
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/contributors-summit-2019",
        link: "https://blog.golang.org/contributors-summit-2019",
        title: "Contributors Summit 2019",
        date: 2019-08-15T11:00:00Z,
        summary: Some(
            "For the third year in a row, the Go team and contributors convened\nthe day before GopherCon to discuss and plan for the future of the Go project.\nThe event included self-organizing into breakout groups,\na town-hall style discussion about the proposal process in the morning,\nand afternoon break-out roundtable discussions\nbased on topics our contributors chose.\nWe asked five contributors to write about their experience\nin various discussions at this year’s summit.\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n  <h4>Introduction</h4>\n  \n  \n  <p>\n    For the third year in a row, the Go team and contributors convened\n\n\n    the day before GopherCon to discuss and plan for the future of the Go project.\n\n\n    The event included self-organizing into breakout groups,\n\n\n    a town-hall style discussion about the proposal process in the morning,\n\n\n    and afternoon break-out roundtable discussions\n\n\n    based on topics our contributors chose.\n\n\n    We asked five contributors to write about their experience\n\n\n    in various discussions at this year’s summit.\n  </p>\n  \n\n<div>\n  <img src=\"https://blog.golang.org/contributors-summit-2019/group.jpg\" width=\"800\" alt=\"\">\n</div>\n\n  \n  <p>\n    <i>(Photo by Steve Francia.)</i>\n  </p>\n  \n\n\n    \n      \n  <h4>Compiler and Runtime (report by Lynn Boger)</h4>\n  \n  \n  <p>\n    The Go contributors summit was a great opportunity\n\n\n    to meet and discuss topics and ideas with others who also contribute to Go.\n  </p>\n  \n\n  \n  <p>\n    The day started out with a time to meet everyone in the room.\n\n\n    There was a good mix of the core Go team\n\n\n    and others who actively contribute to Go.\n\n\n    From there we decided what topics were of interest\n\n\n    and how to split the big group into smaller groups.\n\n\n    My area of interest is the compiler, so I joined that group\n\n\n    and stayed with them for most of the time.\n  </p>\n  \n\n  \n  <p>\n    At our first meeting, a long list of topics were brought up\n\n\n    and as a result the compiler group decided to keep meeting throughout the day.\n\n\n    I had a few topics of interest that I shared and many that others suggested\n\n\n    were also of interest to me.\n\n\n    Not all items on the list were discussed in detail;\n\n\n    here is my list of those topics which had the most interest and discussion,\n\n\n    followed by some brief comments that were made on other topics.\n  </p>\n  \n\n  \n  <p>\n    <b>Binary size</b>.\n\n\n    There was a concern expressed about binary size,\n\n\n    especially that it continues to grow with each release.\n\n\n    Some possible reasons were identified such as increased inlining and other optimizations.\n\n\n    Most likely there is a set of users who want small binaries,\n\n\n    and another group who wants the best performance possible and maybe some don’t care.\n\n\n    This led to the topic of TinyGo, and it was noted that TinyGo was not a full implementation of Go\n\n\n    and that it is important to keep TinyGo from diverging from Go and splitting the user base.\n\n\n    More investigation is required to understand the need among users and the exact reasons\n\n\n    contributing to the current size.\n\n\n    If there are opportunities to reduce the size without affecting performance,\n\n\n    those changes could be made, but if performance were affected\n\n\n    some users would prefer better performance.\n  </p>\n  \n\n  \n  <p>\n    <b>Vector assembly</b>.\n\n\n    How to leverage vector assembly in Go was discussed for a while\n\n\n    and has been a topic of interest in the past.\n\n\n    I have split this into three separate possibilities, since they all relate to the use of vector instructions,\n\n\n    but the way they are used are different, starting with the topic of vector assembly.\n\n\n    This is another case of a compiler trade off.\n  </p>\n  \n\n  \n  <p>\n    For most targets, there are critical functions in standard packages\n\n\n    such as crypto, hash, math and others, where the use of assembly is necessary\n\n\n    to get the best possible performance; however having large functions\n\n\n    written in assembly makes them difficult to support and maintain\n\n\n    and could require different implementations for each target platform.\n\n\n    One solution is to make use of macro assembly or other\n\n\n    high-level generation techniques to make the vector assembly easier to read and understand.\n  </p>\n  \n\n  \n  <p>\n    Another side to this question is whether the Go compiler can\n\n\n    directly generate SIMD vector instructions when compiling a Go source file,\n\n\n    by enhancing the Go compiler to transform code sequences to “simdize”\n\n\n    the code to make use of vector instructions.\n\n\n    Implementing SIMD in the Go compiler would add complexity and compile time,\n\n\n    and might not always result in code that performs better.\n\n\n    The way the code is transformed could in some cases depend\n\n\n    on the target platform so that would not be ideal.\n  </p>\n  \n\n  \n  <p>\n    Another way to leverage vector instructions in Go is to provide a way\n\n\n    to make it easier to make use of vector instructions from within the Go source code.\n\n\n    Topics discussed were intrinsics, or implementations that exist in other compilers like Rust.\n\n\n    In gcc some platforms provide inline asm, and Go possibly could provide this capability,\n\n\n    but I know from experience that intermixing inline asm with Go code adds complexity\n\n\n    to the compiler in terms of tracking register use and debugging.\n\n\n    It allows the user to do things the compiler might not expect or want,\n\n\n    and it does add an extra level of complexity.\n\n\n    It could be inserted in places that are not ideal.\n  </p>\n  \n\n  \n  <p>\n    In summary, it is important to provide a way to leverage\n\n\n    the available vector instructions, and make it easier and safer to write.\n\n\n    Where possible, functions use as much Go code as possible,\n\n\n    and potentially find a way to use high level assembly.\n\n\n    There was some discussion of designing an experimental vector package\n\n\n    to try and implement some of these ideas.\n  </p>\n  \n\n  \n  <p>\n    <b>New calling convention</b>.\n\n\n    Several people were interested in the topic of the\n\n\n    <a href=\"https://golang.org/issue/18597\" rel=\"noopener noreferrer\">ABI changes to provide a register based calling convention</a>.\n\n\n    The current status was reported with details.\n\n\n    There was discussion on what remained to be done before it could be used.\n\n\n    The ABI specification needs to be written first and it was not clear when that would be done.\n\n\n    I know this will benefit some target platforms more than others\n\n\n    and a register calling convention is used in most compilers for other platforms.\n  </p>\n  \n\n  \n  <p>\n    <b>General optimizations</b>.\n\n\n    Certain optimizations that are more beneficial for some platforms other than x86 were discussed.\n\n\n    In particular, loop optimizations such as hoisting of invariants and strength reduction could be done\n\n\n    and provide more benefit on some platforms.\n\n\n    Potential solutions were discussed, and implementation would probably be\n\n\n    up to the targets that find those improvements important.\n  </p>\n  \n\n  \n  <p>\n    <b>Feedback-directed optimizations</b>.\n\n\n    This was discussed and debated as a possible future enhancement.\n\n\n    In my experience, it is hard to find meaningful programs to use for\n\n\n    collecting performance data that can later be used to optimize code.\n\n\n    It increases compile time and takes a lot of space to save the data\n\n\n    which might only be meaningful for a small set of programs.\n  </p>\n  \n\n  \n  <p>\n    <b>Pending submissions</b>.\n\n\n    A few members in the group mentioned changes they had been working on\n\n\n    and plan to submit soon, including improvements to makeslice, and a rewrite of rulegen.\n  </p>\n  \n\n  \n  <p>\n    <b>Compile time concerns</b>.\n\n\n    Compile time was discussed briefly. It was noted that phase timing was added to the GOSSAFUNC output.\n  </p>\n  \n\n  \n  <p>\n    <b>Compiler contributor communication</b>.\n\n\n    Someone asked if there was a need for a Go compiler mailing list.\n\n\n    It was suggested that we use golang-dev for that purpose,\n\n\n    adding compiler to the subject line to identify it.\n\n\n    If there is too much traffic on golang-dev, then a compiler-specific mailing list\n\n\n    can be considered at some later point in time.\n  </p>\n  \n\n  \n  <p>\n    <b>Community</b>.\n\n\n    I found the day very beneficial in terms of connecting with people\n\n\n    who have been active in the community and have similar areas of interest.\n\n\n    I was able to meet many people who I’ve only known by the user name\n\n\n    appearing in issues or mailing lists or CLs.\n\n\n    I was able to discuss some topics and existing issues\n\n\n    and get direct interactive feedback instead of waiting for online responses.\n\n\n    I was encouraged to write issues on problems I have seen.\n\n\n    These connections happened not just during this day but while\n\n\n    running into others throughout the conference,\n\n\n    having been introduced on this first day, which led to many interesting discussions.\n\n\n    Hopefully these connections will lead to more effective communication\n\n\n    and improved handling of issues and code changes in the future.\n  </p>\n  \n\n\n    \n      \n  <h4>Tools (report by Paul Jolly)</h4>\n  \n  \n  <p>\n    The tools breakout session during the contributor summit took an extended form,\n\n\n    with two further sessions on the main conference days organized by the\n\n\n    <a href=\"https://github.com/golang/go/wiki/golang-tools\" rel=\"noopener noreferrer\">golang-tools</a> group.\n\n\n    This summary is broken down into two parts: the tools session at the contributor workshop,\n\n\n    and a combined report from the golang-tools sessions on the main conference days.\n  </p>\n  \n\n  \n  <p>\n    <b>Contributor summit</b>.\n\n\n    The tools session started with introductions from ~25 folks gathered,\n\n\n    followed by a brainstorming of topics, including:\n\n\n    gopls, ARM 32-bit, eval, signal, analysis, go/packages api, refactoring, pprof,\n\n\n    module experience, mono repo analysis, go mobile, dependencies, editor integrations,\n\n\n    compiler opt decisions, debugging, visualization, documentation.\n\n\n    A lot of people with lots of interest in lots of tools!\n  </p>\n  \n\n  \n  <p>\n    The session focused on two areas (all that time allowed): gopls and visualizations.\n\n\n    <a href=\"https://golang.org/wiki/gopls\" rel=\"noopener noreferrer\">Gopls</a> (pronounced: “go please”) is an implementation of the\n\n\n    <a href=\"https://langserver.org/\" rel=\"noopener noreferrer\">Language Server Protocol (LSP)</a> server for Go.\n\n\n    Rebecca Stamber, the gopls lead author, and the rest of the Go tools team were interested\n\n\n    in hearing people’s experiences with gopls: stability, missing features, integrations in editors working, etc?\n\n\n    The general feeling was that gopls was in really good shape and working extremely well for the majority of use cases.\n\n\n    Integration test coverage needs to be improved, but this is a hard problem to get “right” across all editors.\n\n\n    We discussed a better means of users reporting gopls errors they encounter via their editor,\n\n\n    telemetry/diagnostics, gopls performance metrics, all subjects that got more detailed coverage\n\n\n    in golang-tools sessions that followed on the main conference days (see below).\n\n\n    A key area of discussion was how to extend gopls, e.g., in the form of\n\n\n    additional go/analysis vet-like checks, lint checks, refactoring, etc.\n\n\n    Currently there is no good solution, but it’s actively under investigation.\n\n\n    Conversation shifted to the very broad topic of visualizations, with a\n\n\n    demo-based introduction from Anthony Starks (who, incidentally, gave an excellent talk about\n\n\n    <a href=\"https://www.youtube.com/watch?v=NyDNJnioWhI\" rel=\"noopener noreferrer\">Go for information displays</a> at GopherCon 2018).\n  </p>\n  \n\n  \n  <p>\n    <b>Conference days</b>.\n\n\n    The golang-tools sessions on the main conference days were a continuation of the\n\n\n    <a href=\"https://golang.org/wiki/golang-tools\" rel=\"noopener noreferrer\">monthly calls</a> that have been happening since the group’s inception at GopherCon 2018.\n\n\n    Full notes are available for the\n\n\n    <a href=\"https://docs.google.com/document/d/1-RVyttQ0ncjCpR_sRwizf-Ubedkr0Emwmk2LhnsUOmE/edit\" rel=\"noopener noreferrer\">day 1</a> and\n\n\n    <a href=\"https://docs.google.com/document/d/1ZI_WqpLCB8DO6teJ3aBuXTeYD2iZZZlkDptmcY6Ja60/edit#heading=h.x9lkytc2gxmg\" rel=\"noopener noreferrer\">day 2</a> sessions.\n\n\n    These sessions were again well attended with 25-30 people at each session.\n\n\n    The Go tools team was there in strength (a good sign of the support being put behind this area), as was the Uber platform team.\n\n\n    In contrast to the contributor summit, the goal from these sessions was to come away with specific action items.\n  </p>\n  \n\n  \n  <p>\n    <b>Gopls</b>.\n\n\n    Gopls “readiness” was a major focus for both sessions.\n\n\n    This answer effectively boiled down to determining when it makes sense to tell\n\n\n    editor integrators “we have a good first cut of gopls” and then compiling a\n\n\n    list of “blessed” editor integrations/plugins known to work with gopls.\n\n\n    Central to this “certification” of editor integrations/plugins is a well-defined process\n\n\n    by which users can report problems they experience with gopls.\n\n\n    Performance and memory are not blockers for this initial “release”.\n\n\n    The conversation about how to extend gopls, started in the\n\n\n    contributor summit the day before, continued in earnest.\n\n\n    Despite the many obvious benefits and attractions to extending gopls\n\n\n    (custom go/analysis checks, linter support, refactoring, code generation…),\n\n\n    there isn’t a clear answer on how to implement this in a scalable way.\n\n\n    Those gathered agreed that this should not be seen as a blocker for the\n\n\n    initial “release”, but should continue to be worked on.\n\n\n    In the spirit of gopls and editor integrations,\n\n\n    Heschi Kreinick from the Go tools team brought up the topic of debugging support.\n\n\n    Delve has become the de facto debugger for Go and is in good shape;\n\n\n    now the state of debugger-editor integration needs to be established,\n\n\n    following a process similar to that of gopls and the “blessed” integrations.\n  </p>\n  \n\n  \n  <p>\n    <b>Go Discovery Site</b>.\n\n\n    The second golang-tools session started with an excellent introduction to\n\n\n    the Go Discovery Site by Julie Qiu from the Go tools team, along with a quick demo.\n\n\n    Julie talked about the plans for the Discovery Site: open sourcing the project,\n\n\n    what signals are used in search ranking, how <a href=\"http://godoc.org/\" rel=\"noopener noreferrer\">godoc.org</a> will ultimately be replaced,\n\n\n    how submodules should work, how users can discover new major versions.\n  </p>\n  \n\n  \n  <p>\n    <b>Build Tags</b>.\n\n\n    Conversation then moved to build tag support within gopls.\n\n\n    This is an area that clearly needs to be better understood\n\n\n    (use cases are currently being gathered in <a href=\"https://golang.org/issue/33389\" rel=\"noopener noreferrer\">issue 33389</a>).\n\n\n    In light of this conversation, the session wrapped up with\n\n\n    Alexander Zolotov from the JetBrains GoLand team suggesting that the gopls and\n\n\n    GoLand teams should share experience in this and more areas, given GoLand\n\n\n    has already gained lots of experience.\n  </p>\n  \n\n  \n  <p>\n    <b>Join Us!</b>\n\n\n    We could easily have talked about tools-related topics for days!\n\n\n    The good news is that the golang-tools calls will continue for the foreseeable future.\n\n\n    Anyone interested in Go tooling is very much encouraged to join: <a href=\"https://golang.org/wiki/golang-tools\" rel=\"noopener noreferrer\">the wiki</a> has more details.\n  </p>\n  \n\n\n    \n      \n  <h4>Enterprise Use (report by Daniel Theophanes)</h4>\n  \n  \n  <p>\n    Actively asking after the needs of less vocal developers will be the largest challenge,\n\n\n    and greatest win, for the Go language. There is a large segment of programmers\n\n\n    who don’t actively participate in the Go community.\n\n\n    Some are business associates, marketers, or quality assurance who also do development.\n\n\n    Some will wear management hats and make hiring or technology decisions.\n\n\n    Others just do their job and return to their families.\n\n\n    And lastly, many times these developers work in businesses with strict IP protection contracts.\n\n\n    Even though most of these developers won’t end up directly participating in open source\n\n\n    or the Go community proposals, their ability to use Go depends on both.\n  </p>\n  \n\n  \n  <p>\n    The Go community and Go proposals need to understand the needs of these less vocal developers.\n\n\n    Go proposals can have a large impact on what is adopted and used.\n\n\n    For instance, the vendor folder and later the Go modules proxy are incredibly important\n\n\n    for businesses that strictly control source code and\n\n\n    typically have fewer direct conversations with the Go community.\n\n\n    Having these mechanisms allow these organizations to use Go at all.\n\n\n    It follows that we must not only pay attention to current Go users,\n\n\n    but also to developers and organizations who have considered Go,\n\n\n    but have chosen against it.\n\n\n    We need to understand these reasons.\n  </p>\n  \n\n  \n  <p>\n    Similarly, should the Go community pay attention to “enterprise”\n\n\n    environments it would unlock many additional organizations who can utilize Go.\n\n\n    By ensuring active directory authentication works, users who would\n\n\n    be forced to use a different ecosystem can keep Go on the table.\n\n\n    By ensuring WSDL just works, a section of users can pick Go up as a tool.\n\n\n    No one suggested blindly making changes to appease non-Go users.\n\n\n    But rather we should be aware of untapped potential and unrecognized\n\n\n    hindrances in the Go language and ecosystem.\n  </p>\n  \n\n  \n  <p>\n    While several different possibilities to actively solicit this information\n\n\n    from the outside was discussed, this is a problem we fundamentally need your help.\n\n\n    If you are in an organization that doesn’t use Go even though it was considered,\n\n\n    let us know why Go wasn’t chosen.\n\n\n    If you are in an organization where Go is only used for a subsection of programming tasks,\n\n\n    but not others, why isn’t it used for more? Are there specific blockers to adoption?\n  </p>\n  \n\n\n    \n      \n  <h4>Education (report by Andy Walker)</h4>\n  \n  \n  <p>\n    One of the roundtables I was involved in at the Contributors Summit\n\n\n    this year was on the topic of Go education,\n\n\n    specifically what kind of resources we make available\n\n\n    to the new Go programmer, and how we can improve them.\n\n\n    Present were a number of very passionate organizers, engineers and educators,\n\n\n    each of whom had a unique perspective on the subject,\n\n\n    either through tools they’d designed,\n\n\n    documents they’d written or workshops they’d given to developers of all stripes.\n  </p>\n  \n\n  \n  <p>\n    Early on, talk turned to whether or not Go makes a good first programming language.\n\n\n    I wasn’t sure, and advocated against it.\n\n\n    Go isn’t a good first language, I argued, because it isn’t intended to be.\n\n\n    As Rob Pike <a href=\"https://talks.golang.org/2012/splash.article\" rel=\"noopener noreferrer\">wrote back in 2012</a>,\n\n\n    “the language was designed by and for people who write—and read and debug and maintain—large software systems”.\n\n\n    To me, this guiding ethos is clear: Go is a deliberate response to perceived flaws\n\n\n    in the processes used by experienced engineers, not an attempt to create an ideal\n\n\n    programming language, and as such a certain basic familiarity with programming concepts is assumed.\n  </p>\n  \n\n  \n  <p>\n    This is evident in the official documentation at <a href=\"https://golang.org/doc/\" rel=\"noopener noreferrer\">golang.org/doc</a>.\n\n\n    It jumps right into how to install the language before passing the user on to the\n\n\n    <a href=\"https://tour.golang.org/\" rel=\"noopener noreferrer\">tour</a>, which is geared towards programmers\n\n\n    who are already familiar with a C-like language.\n\n\n    From there, they are taken to <a href=\"https://golang.org/doc/code.html\" rel=\"noopener noreferrer\">How to Write Go Code</a>,\n\n\n    which provides a very basic introduction to the classic non-module Go workspace,\n\n\n    before moving immediately on to writing libraries and testing.\n\n\n    Finally, we have <a href=\"https://golang.org/doc/effective_go.html\" rel=\"noopener noreferrer\">Effective Go</a>,\n\n\n    and a series of references including the <a href=\"https://golang.org/ref/spec\" rel=\"noopener noreferrer\">spec</a>,\n\n\n    rounded out by some examples.\n\n\n    These are all decent resources if you’re already familiar with a C-like language,\n\n\n    but they still leave a lot to be desired, and there’s nothing to be found\n\n\n    for the raw beginner or even someone coming directly from a language like Python.\n  </p>\n  \n\n  \n  <p>\n    As an accessible, interactive starting point, the tour is a natural first target\n\n\n    towards making the language more beginner friendly,\n\n\n    and I think a lot of headway can be made targeting that alone.\n\n\n    First, it should be the first link in the documentation,\n\n\n    if not the first link in the bar at the top of golang.org, front and center.\n\n\n    We should encourage the curious user to jump right in and start playing with the language.\n\n\n    We should also consider including optional introductory sections on coming\n\n\n    from other common languages, and the differences they are\n\n\n    likely to encounter in Go, with interactive exercises.\n\n\n    This would go a long way to helping new Go programmers in mapping\n\n\n    the concepts they are already familiar with onto Go.\n  </p>\n  \n\n  \n  <p>\n    For experienced programmers, an optional, deeper treatment should be given\n\n\n    to most sections in the tour, allowing them to drill down into more\n\n\n    detailed documentation or interactive exercises enumerating the\n\n\n    design decisions principles of good architecture in Go.\n\n\n    They should find answers to questions like:\n  </p>\n  \n\n  <ul>\n  \n    <li>Why are there so many integer types when I am encouraged to use <code>int</code> most of the time?</li>\n  \n    <li>Is there ever a good reason to pick a value receiver?</li>\n  \n    <li>Why is there a plain <code>int</code>, but no plain <code>float</code>?</li>\n  \n    <li>What are send- and receive-only channels, and when would I use them?</li>\n  \n    <li>How do I effectively compose concurrency primitives, and when would I <i>not</i> want to use channels?</li>\n  \n    <li>What is <code>uint</code> good for? Should I use it to restrict my user to positive values? Why not?</li>\n  \n  </ul>\n\n  \n  <p>\n    The tour should be someplace they can revisit upon finishing the first run-through\n\n\n    to dive more deeply into some of the more interesting choices in language design.\n  </p>\n  \n\n  \n  <p>\n    But we can do more. Many people seek out programming as a way to design\n\n\n    applications or scratch a particular itch, and they are most likely to want\n\n\n    to target the interface they are most familiar with: the browser.\n\n\n    Go does not have a good front-end story yet.\n\n\n    Javascript is still the only language that really provides\n\n\n    both a frontend and a backend environment,\n\n\n    but WASM is fast becoming a first-order platform,\n\n\n    and there are so many places we could go with that.\n\n\n    We could provide something like <a href=\"https://github.com/gopherjs/vecty\" rel=\"noopener noreferrer\">vecty</a>\n\n\n    in <a href=\"https://goplay.space/\" rel=\"noopener noreferrer\">The Go Play Space</a>,\n\n\n    or perhaps <a href=\"https://gioui.org/\" rel=\"noopener noreferrer\">Gio</a>, targeting WASM, for people to get\n\n\n    started programming in the browser right away, inspiring their imagination,\n\n\n    and provide them a migration path out of our playground into\n\n\n    a terminal and onto GitHub.\n  </p>\n  \n\n  \n  <p>\n    So, is Go a good first language?\n\n\n    I honestly don’t know, but it’s certainly true there are a significant\n\n\n    number of people entering the programming profession\n\n\n    with Go as their starting point, and I am very interested in talking to them,\n\n\n    learning about their journey and their process,\n\n\n    and shaping the future of Go education with their input.\n  </p>\n  \n\n\n    \n      \n  <h4>Learning Platforms (report by Ronna Steinberg)</h4>\n  \n  \n  <p>\n    We discussed what a learning platform for Go should look like\n\n\n    and how we can combine global resources to effectively teach the language.\n\n\n    We generally agreed that teaching and learning is easier with visualization\n\n\n    and that a REPL is very gratifying.\n\n\n    We also overviewed some existing solutions for visualization with Go:\n\n\n    templates, Go WASM, GopherJS as well as SVG and GIFs generation.\n  </p>\n  \n\n  \n  <p>\n    Compiler errors not making sense to the new developer was also brought up\n\n\n    and we considered ideas of how to handle it, perhaps a bank of errors and how they would be useful.\n\n\n    One idea was a wrapper for the compiler that explains your errors to you, with examples and solutions.\n  </p>\n  \n\n  \n  <p>\n    A new group convened for a second round later and we focused more on\n\n\n    what UX should the Go learning platform have,\n\n\n    and if and how we can take existing materials (talks, blog posts, podcasts, etc)\n\n\n    from the community and organize them into a program people can learn from.\n\n\n    Should such a platform link to those external resources?\n\n\n    Embed them?\n\n\n    Cite them?\n\n\n    We agreed that a portal-like-solution (of external links to resources)\n\n\n    makes navigation difficult and takes away from the learning experience,\n\n\n    which led us to the conclusion that such contribution cannot be passive,\n\n\n    and contributors will likely have to opt-in to have their material on the platform.\n\n\n    There was then much excitement around the idea of adding a voting mechanism to the platform,\n\n\n    effectively turning the learners into contributors, too,\n\n\n    and incentivizing the contributors to put their materials on the platform.\n  </p>\n  \n\n  \n  <p>\n    (If you are interested in helping in educational efforts for Go,\n\n\n    please email Carmen Andoh candoh@google.com.)\n  </p>\n  \n\n\n    \n      \n  <h4>Thank You!</h4>\n  \n  \n  <p>\n    Thanks to all the attendees for the excellent discussions on contributor day,\n\n\n    and thanks especially to Lynn, Paul, Daniel, Andy, and Ronna\n\n\n    for taking the time to write these reports.\n  </p>\n  \n\n\n    \n  \n",
        ),
        media_type: Some(
            MediaType {
                mime: "image/*",
            },
        ),
        media_link: Some(
            "https://blog.golang.org/contributors-summit-2019/group.jpg",
        ),
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/migrating-to-go-modules",
        link: "https://blog.golang.org/migrating-to-go-modules",
        title: "Migrating to Go Modules",
        date: 2019-08-21T11:00:00Z,
        summary: Some(
            "This post is part 2 in a series.\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n  <h4>Introduction</h4>\n  \n  \n  <p>\n    This post is part 2 in a series.\n  </p>\n  \n\n  <ul>\n  \n    <li>Part 1 — <a href=\"https://blog.golang.org/using-go-modules\" rel=\"noopener noreferrer\">Using Go Modules</a></li>\n  \n    <li><b>Part 2 — Migrating To Go Modules</b> (this post)</li>\n  \n    <li>Part 3 — <a href=\"https://blog.golang.org/publishing-go-modules\" rel=\"noopener noreferrer\">Publishing Go Modules</a></li>\n  \n    <li>Part 4 — <a href=\"https://blog.golang.org/v2-go-modules\" rel=\"noopener noreferrer\">Go Modules: v2 and Beyond</a></li>\n  \n  </ul>\n\n  \n  <p>\n    Go projects use a wide variety of dependency management strategies. <a href=\"https://golang.org/cmd/go/#hdr-Vendor_Directories\" rel=\"noopener noreferrer\">Vendoring</a> tools such as <a href=\"https://github.com/golang/dep\" rel=\"noopener noreferrer\">dep</a> and <a href=\"https://github.com/Masterminds/glide\" rel=\"noopener noreferrer\">glide</a> are popular, but they have wide differences in behavior and don\'t always work well together. Some projects store their entire GOPATH directory in a single Git repository. Others simply rely on <code>go get</code> and expect fairly recent versions of dependencies to be installed in GOPATH.\n  </p>\n  \n\n  \n  <p>\n    Go\'s module system, introduced in Go 1.11, provides an official dependency management solution built into the <code>go</code> command. This article describes tools and techniques for converting a project to modules.\n  </p>\n  \n\n  \n  <p>\n    Please note: if your project is already tagged at v2.0.0 or higher, you will need to update your module path when you add a <code>go.mod</code> file. We\'ll explain how to do that without breaking your users in a future article focused on v2 and beyond.\n  </p>\n  \n\n\n    \n      \n  <h4>Migrating to Go modules in your project</h4>\n  \n  \n  <p>\n    A project might be in one of three states when beginning the transition to Go modules:\n  </p>\n  \n\n  <ul>\n  \n    <li>A brand new Go project.</li>\n  \n    <li>An established Go project with a non-modules dependency manager.</li>\n  \n    <li>An established Go project without any dependency manager.</li>\n  \n  </ul>\n\n  \n  <p>\n    The first case is covered in <a href=\"https://blog.golang.org/using-go-modules\" rel=\"noopener noreferrer\">Using Go Modules</a>; we\'ll address the latter two in this post.\n  </p>\n  \n\n\n    \n      \n  <h4>With a dependency manager</h4>\n  \n  \n  <p>\n    To convert a project that already uses a dependency management tool, run the following commands:\n  </p>\n  \n\n  \n  <div><pre>$ git clone https://github.com/my/project\n[...]\n$ cd project\n$ cat Godeps/Godeps.json\n{\n    \"ImportPath\": \"github.com/my/project\",\n    \"GoVersion\": \"go1.12\",\n    \"GodepVersion\": \"v80\",\n    \"Deps\": [\n        {\n            \"ImportPath\": \"rsc.io/binaryregexp\",\n            \"Comment\": \"v0.2.0-1-g545cabd\",\n            \"Rev\": \"545cabda89ca36b48b8e681a30d9d769a30b3074\"\n        },\n        {\n            \"ImportPath\": \"rsc.io/binaryregexp/syntax\",\n            \"Comment\": \"v0.2.0-1-g545cabd\",\n            \"Rev\": \"545cabda89ca36b48b8e681a30d9d769a30b3074\"\n        }\n    ]\n}\n$ go mod init github.com/my/project\ngo: creating new go.mod: module github.com/my/project\ngo: copying requirements from Godeps/Godeps.json\n$ cat go.mod\nmodule github.com/my/project\n\ngo 1.12\n\nrequire rsc.io/binaryregexp v0.2.1-0.20190524193500-545cabda89ca\n$</pre></div>\n  \n\n  \n  <p>\n    <code>go mod init</code> creates a new go.mod file and automatically imports dependencies from <code>Godeps.json</code>, <code>Gopkg.lock</code>, or a number of <a href=\"https://go.googlesource.com/go/+/362625209b6cd2bc059b6b0a67712ddebab312d9/src/cmd/go/internal/modconv/modconv.go#9\" rel=\"noopener noreferrer\">other supported formats</a>. The argument to <code>go mod init</code> is the module path, the location where the module may be found.\n  </p>\n  \n\n  \n  <p>\n    This is a good time to pause and run <code>go build ./...</code> and <code>go test ./...</code> before continuing. Later steps may modify your <code>go.mod</code> file, so if you prefer to take an iterative approach, this is the closest your <code>go.mod</code> file will be to your pre-modules dependency specification.\n  </p>\n  \n\n  \n  <div><pre>$ go mod tidy\ngo: downloading rsc.io/binaryregexp v0.2.1-0.20190524193500-545cabda89ca\ngo: extracting rsc.io/binaryregexp v0.2.1-0.20190524193500-545cabda89ca\n$ cat go.sum\nrsc.io/binaryregexp v0.2.1-0.20190524193500-545cabda89ca h1:FKXXXJ6G2bFoVe7hX3kEX6Izxw5ZKRH57DFBJmHCbkU=\nrsc.io/binaryregexp v0.2.1-0.20190524193500-545cabda89ca/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\n$</pre></div>\n  \n\n  \n  <p>\n    <code>go mod tidy</code> finds all the packages transitively imported by packages in your module. It adds new module requirements for packages not provided by any known module, and it removes requirements on modules that don\'t provide any imported packages. If a module provides packages that are only imported by projects that haven\'t migrated to modules yet, the module requirement will be marked with an <code>// indirect</code> comment. It is always good practice to run <code>go mod tidy</code> before committing a <code>go.mod</code> file to version control.\n  </p>\n  \n\n  \n  <p>\n    Let\'s finish by making sure the code builds and tests pass:\n  </p>\n  \n\n  \n  <div><pre>$ go build ./...\n$ go test ./...\n[...]\n$</pre></div>\n  \n\n  \n  <p>\n    Note that other dependency managers may specify dependencies at the level of individual packages or entire repositories (not modules), and generally do not recognize the requirements specified in the <code>go.mod</code> files of dependencies. Consequently, you may not get exactly the same version of every package as before, and there\'s some risk of upgrading past breaking changes. Therefore, it\'s important to follow the above commands with an audit of the resulting dependencies. To do so, run\n  </p>\n  \n\n  \n  <div><pre>$ go list -m all\ngo: finding rsc.io/binaryregexp v0.2.1-0.20190524193500-545cabda89ca\ngithub.com/my/project\nrsc.io/binaryregexp v0.2.1-0.20190524193500-545cabda89ca\n$</pre></div>\n  \n\n  \n  <p>\n    and compare the resulting versions with your old dependency management file to ensure that the selected versions are appropriate. If you find a version that wasn\'t what you wanted, you can find out why using <code>go mod why -m</code> and/or <code>go mod graph</code>, and upgrade or downgrade to the correct version using <code>go get</code>. (If the version you request is older than the version that was previously selected, <code>go get</code> will downgrade other dependencies as needed to maintain compatibility.) For example,\n  </p>\n  \n\n  \n  <div><pre>$ go mod why -m rsc.io/binaryregexp\n[...]\n$ go mod graph | grep rsc.io/binaryregexp\n[...]\n$ go get rsc.io/binaryregexp@v0.2.0\n$</pre></div>\n  \n\n\n    \n      \n  <h4>Without a dependency manager</h4>\n  \n  \n  <p>\n    For a Go project without a dependency management system, start by creating a <code>go.mod</code> file:\n  </p>\n  \n\n  \n  <div><pre>$ git clone https://go.googlesource.com/blog\n[...]\n$ cd blog\n$ go mod init golang.org/x/blog\ngo: creating new go.mod: module golang.org/x/blog\n$ cat go.mod\nmodule golang.org/x/blog\n\ngo 1.12\n$</pre></div>\n  \n\n  \n  <p>\n    Without a configuration file from a previous dependency manager, <code>go mod init</code> will create a <code>go.mod</code> file with only the <code>module</code> and <code>go</code> directives. In this example, we set the module path to <code>golang.org/x/blog</code> because that is its <a href=\"https://golang.org/cmd/go/#hdr-Remote_import_paths\" rel=\"noopener noreferrer\">custom import path</a>. Users may import packages with this path, and we must be careful not to change it.\n  </p>\n  \n\n  \n  <p>\n    The <code>module</code> directive declares the module path, and the <code>go</code> directive declares the expected version of the Go language used to compile the code within the module.\n  </p>\n  \n\n  \n  <p>\n    Next, run <code>go mod tidy</code> to add the module\'s dependencies:\n  </p>\n  \n\n  \n  <div><pre>$ go mod tidy\ngo: finding golang.org/x/website latest\ngo: finding gopkg.in/tomb.v2 latest\ngo: finding golang.org/x/net latest\ngo: finding golang.org/x/tools latest\ngo: downloading github.com/gorilla/context v1.1.1\ngo: downloading golang.org/x/tools v0.0.0-20190813214729-9dba7caff850\ngo: downloading golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7\ngo: extracting github.com/gorilla/context v1.1.1\ngo: extracting golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7\ngo: downloading gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637\ngo: extracting gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637\ngo: extracting golang.org/x/tools v0.0.0-20190813214729-9dba7caff850\ngo: downloading golang.org/x/website v0.0.0-20190809153340-86a7442ada7c\ngo: extracting golang.org/x/website v0.0.0-20190809153340-86a7442ada7c\n$ cat go.mod\nmodule golang.org/x/blog\n\ngo 1.12\n\nrequire (\n    github.com/gorilla/context v1.1.1\n    golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7\n    golang.org/x/text v0.3.2\n    golang.org/x/tools v0.0.0-20190813214729-9dba7caff850\n    golang.org/x/website v0.0.0-20190809153340-86a7442ada7c\n    gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637\n)\n$ cat go.sum\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngit.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=\ngit.apache.org/thrift.git v0.0.0-20181218151757-9b75e4fe745a/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\n[...]\n$</pre></div>\n  \n\n  \n  <p>\n    <code>go mod tidy</code> added module requirements for all the packages transitively imported by packages in your module and built a <code>go.sum</code> with checksums for each library at a specific version. Let\'s finish by making sure the code still builds and tests still pass:\n  </p>\n  \n\n  \n  <div><pre>$ go build ./...\n$ go test ./...\nok      golang.org/x/blog    0.335s\n?       golang.org/x/blog/content/appengine    [no test files]\nok      golang.org/x/blog/content/cover    0.040s\n?       golang.org/x/blog/content/h2push/server    [no test files]\n?       golang.org/x/blog/content/survey2016    [no test files]\n?       golang.org/x/blog/content/survey2017    [no test files]\n?       golang.org/x/blog/support/racy    [no test files]\n$</pre></div>\n  \n\n  \n  <p>\n    Note that when <code>go mod tidy</code> adds a requirement, it adds the latest version of the module. If your <code>GOPATH</code> included an older version of a dependency that subsequently published a breaking change, you may see errors in <code>go mod tidy</code>, <code>go build</code>, or <code>go test</code>. If this happens, try downgrading to an older version with <code>go get</code> (for example, <code>go get github.com/broken/module@v1.1.0</code>), or take the time to make your module compatible with the latest version of each dependency.\n  </p>\n  \n\n  <h4>Tests in module mode</h4>\n  \n  \n  <p>\n    Some tests may need tweaks after migrating to Go modules.\n  </p>\n  \n\n  \n  <p>\n    If a test needs to write files in the package directory, it may fail when the package directory is in the module cache, which is read-only. In particular, this may cause <code>go test all</code> to fail. The test should copy files it needs to write to a temporary directory instead.\n  </p>\n  \n\n  \n  <p>\n    If a test relies on relative paths (<code>../package-in-another-module</code>) to locate and read files in another package, it will fail if the package is in another module, which will be located in a versioned subdirectory of the module cache or a path specified in a <code>replace</code> directive. If this is the case, you may need to copy the test inputs into your module, or convert the test inputs from raw files to data embedded in <code>.go</code> source files.\n  </p>\n  \n\n  \n  <p>\n    If a test expects <code>go</code> commands within the test to run in GOPATH mode, it may fail. If this is the case, you may need to add a <code>go.mod</code> file to the source tree to be tested, or set <code>GO111MODULE=off</code> explicitly.\n  </p>\n  \n\n\n\n    \n      \n  <h4>Publishing a release</h4>\n  \n  \n  <p>\n    Finally, you should tag and publish a release version for your new module. This is optional if you haven\'t released any versions yet, but without an official release, downstream users will depend on specific commits using <a href=\"https://golang.org/cmd/go/#hdr-Pseudo_versions\" rel=\"noopener noreferrer\">pseudo-versions</a>, which may be more difficult to support.\n  </p>\n  \n\n  \n  <div><pre>$ git tag v1.2.0\n$ git push origin v1.2.0</pre></div>\n  \n\n  \n  <p>\n    Your new <code>go.mod</code> file defines a canonical import path for your module and adds\n\n\n    new minimum version requirements. If your users are already using the correct\n\n\n    import path, and your dependencies haven\'t made breaking changes, then adding\n\n\n    the <code>go.mod</code> file is backwards-compatible — but it\'s a significant change, and\n\n\n    may expose existing problems. If you have existing version tags, you should\n\n\n    increment the <a href=\"https://semver.org/#spec-item-7\" rel=\"noopener noreferrer\">minor version</a>. See\n\n\n    <a href=\"https://blog.golang.org/publishing-go-modules\" rel=\"noopener noreferrer\">Publishing Go Modules</a> to learn how to increment and\n\n\n    publish versions.\n  </p>\n  \n\n\n    \n      \n  <h4>Imports and canonical module paths</h4>\n  \n  \n  <p>\n    Each module declares its module path in its <code>go.mod</code> file. Each <code>import</code> statement that refers to a package within the module must have the module path as a prefix of the package path. However, the <code>go</code> command may encounter a repository containing the module through many different <a href=\"https://golang.org/cmd/go/#hdr-Remote_import_paths\" rel=\"noopener noreferrer\">remote import paths</a>. For example, both <code>golang.org/x/lint</code> and <code>github.com/golang/lint</code> resolve to repositories containing the code hosted at <a href=\"https://go.googlesource.com/lint\" rel=\"noopener noreferrer\">go.googlesource.com/lint</a>. The <a href=\"https://go.googlesource.com/lint/+/refs/heads/master/go.mod\" rel=\"noopener noreferrer\"><code>go.mod</code> file</a> contained in that repository declares its path to be <code>golang.org/x/lint</code>, so only that path corresponds to a valid module.\n  </p>\n  \n\n  \n  <p>\n    Go 1.4 provided a mechanism for declaring canonical import paths using <a href=\"https://golang.org/cmd/go/#hdr-Import_path_checking\" rel=\"noopener noreferrer\"><code>// import</code> comments</a>, but package authors did not always provide them. As a result, code written prior to modules may have used a non-canonical import path for a module without surfacing an error for the mismatch. When using modules, the import path must match the canonical module path, so you may need to update <code>import</code> statements: for example, you may need to change <code>import \"github.com/golang/lint\"</code> to <code>import \"golang.org/x/lint\"</code>.\n  </p>\n  \n\n  \n  <p>\n    Another scenario in which a module\'s canonical path may differ from its repository path occurs for Go modules at major version 2 or higher. A Go module with a major version above 1 must include a major-version suffix in its module path: for example, version <code>v2.0.0</code> must have the suffix <code>/v2</code>. However, <code>import</code> statements may have referred to the packages within the module <i>without</i> that suffix. For example, non-module users of <code>github.com/russross/blackfriday/v2</code> at <code>v2.0.1</code> may have imported it as <code>github.com/russross/blackfriday</code> instead, and will need to update the import path to include the <code>/v2</code> suffix.\n  </p>\n  \n\n\n    \n      \n  <h4>Conclusion</h4>\n  \n  \n  <p>\n    Converting to Go modules should be a straightforward process for most users. Occasional issues may arise due to non-canonical import paths or breaking changes within a dependency. Future posts will explore <a href=\"https://blog.golang.org/publishing-go-modules\" rel=\"noopener noreferrer\">publishing new versions</a>, v2 and beyond, and ways to debug strange situations.\n  </p>\n  \n\n  \n  <p>\n    To provide feedback and help shape the future of dependency management in Go, please send us <a href=\"https://golang.org/issue/new\" rel=\"noopener noreferrer\">bug reports</a> or <a href=\"https://golang.org/wiki/ExperienceReports\" rel=\"noopener noreferrer\">experience reports</a>.\n  </p>\n  \n\n  \n  <p>\n    Thanks for all your feedback and help improving modules.\n  </p>\n  \n\n\n    \n  \n",
        ),
        media_type: None,
        media_link: None,
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/module-mirror-launch",
        link: "https://blog.golang.org/module-mirror-launch",
        title: "Module Mirror and Checksum Database Launched",
        date: 2019-08-29T11:00:00Z,
        summary: Some(
            "We are excited to share that our module mirror,\nindex, and\nchecksum database are now production ready! The go command\nwill use the module mirror and checksum database by default for\nGo 1.13 module users.  See\nproxy.golang.org/privacy for privacy\ninformation about these services and the\ngo command documentation\nfor configuration details, including how to disable the use of these servers or\nuse different ones.  If you depend on non-public modules, see the\ndocumentation for configuring your environment.\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n        \n  \n  <p>\n    We are excited to share that our module <a href=\"https://proxy.golang.org/\" rel=\"noopener noreferrer\">mirror</a>,\n\n\n    <a href=\"https://index.golang.org/\" rel=\"noopener noreferrer\">index</a>, and\n\n\n    <a href=\"https://sum.golang.org/\" rel=\"noopener noreferrer\">checksum database</a> are now production ready! The <code>go</code> command\n\n\n    will use the module mirror and checksum database by default for\n\n\n    <a href=\"https://golang.org/doc/go1.13#introduction\" rel=\"noopener noreferrer\">Go 1.13 module users</a>.  See\n\n\n    <a href=\"https://proxy.golang.org/privacy\" rel=\"noopener noreferrer\">proxy.golang.org/privacy</a> for privacy\n\n\n    information about these services and the\n\n\n    <a href=\"https://golang.org/cmd/go/#hdr-Module_downloading_and_verification\" rel=\"noopener noreferrer\">go command documentation</a>\n\n\n    for configuration details, including how to disable the use of these servers or\n\n\n    use different ones.  If you depend on non-public modules, see the\n\n\n    <a href=\"https://golang.org/cmd/go/#hdr-Module_configuration_for_non_public_modules\" rel=\"noopener noreferrer\">documentation for configuring your environment</a>.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    This post will describe these services and the benefits of using them, and\n\n\n    summarizes some of the points from the\n\n\n    <a href=\"https://youtu.be/KqTySYYhPUE\" rel=\"noopener noreferrer\">Go Module Proxy: Life of a Query</a> talk at Gophercon 2019.\n\n\n    See the <a href=\"https://youtu.be/KqTySYYhPUE\" rel=\"noopener noreferrer\">recording</a> if you are interested in the full talk.\n  </p>\n  \n\n      \n        \n  <h4>Module Mirror</h4>\n  \n  \n  <p>\n    <a href=\"https://blog.golang.org/versioning-proposal\" rel=\"noopener noreferrer\">Modules</a> are sets of Go packages\n\n\n    that are versioned together, and the contents of each version are immutable.\n\n\n    That immutability provides new opportunities for caching and authentication.\n\n\n    When <code>go get</code> runs in module mode, it must fetch the module containing the\n\n\n    requested packages, as well as any new dependencies introduced by that module,\n\n\n    updating your\n\n\n    <a href=\"https://golang.org/cmd/go/#hdr-The_go_mod_file\" rel=\"noopener noreferrer\">go.mod</a> and\n\n\n    <a href=\"https://golang.org/cmd/go/#hdr-Module_downloading_and_verification\" rel=\"noopener noreferrer\">go.sum</a>\n\n\n    files as needed. Fetching modules from version control can be expensive in terms\n\n\n    of latency and storage in your system: the <code>go</code> command may be forced to pull down\n\n\n    the full commit history of a repository containing a transitive dependency, even\n\n\n    one that isn’t being built, just to resolve its version.\n  </p>\n  \n\n  \n  <p>\n    The solution is to use a module proxy, which speaks an API that is better suited\n\n\n    to the <code>go</code> command’s needs (see <code>go help goproxy</code>). When <code>go get</code> runs in\n\n\n    module mode with a proxy, it will work faster by only asking for the specific\n\n\n    module metadata or source code it needs, and not worrying about the rest. Below is\n\n\n    an example of how the <code>go</code> command may use a proxy with <code>go get</code> by requesting the list\n\n\n    of versions, then the info, mod, and zip file for the latest tagged version.\n  </p>\n  \n\n<div>\n  <img src=\"https://blog.golang.org/module-mirror-launch/proxy-protocol.png\" width=\"800\" alt=\"\">\n</div>\n\n  \n  <p>\n    A module mirror is a special kind of module proxy that caches metadata and\n\n\n    source code in its own storage system, allowing the mirror to continue to serve\n\n\n    source code that is no longer available from the original locations. This can\n\n\n    speed up downloads and protect you from disappearing dependencies. See\n\n\n    <a href=\"https://blog.golang.org/modules2019\" rel=\"noopener noreferrer\">Go Modules in 2019</a> for more information.\n  </p>\n  \n\n  \n  <p>\n    The Go team maintains a module mirror, served at\n\n\n    <a href=\"https://proxy.golang.org/\" rel=\"noopener noreferrer\">proxy.golang.org</a>, which the <code>go</code> command will use by\n\n\n    default for module users as of Go 1.13. If you are running an earlier version of the <code>go</code>\n\n\n    command, then you can use this service by setting\n\n\n    <code>GOPROXY=https://proxy.golang.org</code> in your local environment.\n  </p>\n  \n\n\n      \n        \n  <h4>Checksum Database</h4>\n  \n  \n  <p>\n    Modules introduced the <code>go.sum</code> file, which is a list of SHA-256 hashes of the\n\n\n    source code and <code>go.mod</code> files of each dependency when it was first downloaded.\n\n\n    The <code>go</code> command can use the hashes to detect misbehavior by an origin server or\n\n\n    proxy that gives you different code for the same version.\n  </p>\n  \n\n  \n  <p>\n    The limitation of this <code>go.sum</code> file is that it works entirely by trust on <i>your</i>\n\n\n    first use. When you add a version of a dependency that you’ve never seen before\n\n\n    to your module (possibly by upgrading an existing dependency), the <code>go</code> command\n\n\n    fetches the code and adds lines to the <code>go.sum</code> file on the fly. The problem is\n\n\n    that those <code>go.sum</code> lines aren’t being checked against anyone else’s: they might\n\n\n    be different from the <code>go.sum</code> lines that the <code>go</code> command just generated for\n\n\n    someone else, perhaps because a proxy intentionally served malicious code\n\n\n    targeted to you.\n  </p>\n  \n\n  \n  <p>\n    Go\'s solution is a global source of <code>go.sum</code> lines, called a\n\n\n    <a href=\"https://go.googlesource.com/proposal/+/master/design/25530-sumdb.md#checksum-database\" rel=\"noopener noreferrer\">checksum database</a>,\n\n\n    which ensures that the <code>go</code> command always adds the same lines to everyone\'s\n\n\n    <code>go.sum</code> file. Whenever the <code>go</code> command receives new source code, it can verify the\n\n\n    hash of that code against this global database to make sure the hashes match,\n\n\n    ensuring that everyone is using the same code for a given version.\n  </p>\n  \n\n  \n  <p>\n    The checksum database is served by <a href=\"https://sum.golang.org/\" rel=\"noopener noreferrer\">sum.golang.org</a>, and\n\n\n    is built on a <a href=\"https://research.swtch.com/tlog\" rel=\"noopener noreferrer\">Transparent Log</a> (or “Merkle\n\n\n    tree”) of hashes backed by <a href=\"https://github.com/google/trillian\" rel=\"noopener noreferrer\">Trillian</a>. The\n\n\n    main advantage of a Merkle tree is that it is tamper proof and has properties\n\n\n    that don’t allow for misbehavior to go undetected, which makes it more\n\n\n    trustworthy than a simple database. The <code>go</code> command uses this tree to check\n\n\n    “inclusion” proofs (that a specific record exists in the log) and “consistency”\n\n\n    proofs (that the tree hasn’t been tampered with) before adding new <code>go.sum</code> lines\n\n\n    to your module’s <code>go.sum</code> file. Below is an example of such a tree.\n  </p>\n  \n\n<div>\n  <img src=\"https://blog.golang.org/module-mirror-launch/tree.png\" width=\"800\" alt=\"\">\n</div>\n\n  \n  <p>\n    The checksum database supports\n\n\n    <a href=\"https://go.googlesource.com/proposal/+/master/design/25530-sumdb.md#checksum-database\" rel=\"noopener noreferrer\">a set of endpoints</a>\n\n\n    used by the <code>go</code> command to request and verify <code>go.sum</code> lines. The <code>/lookup</code>\n\n\n    endpoint provides a “signed tree head” (STH) and the requested <code>go.sum</code> lines. The\n\n\n    <code>/tile</code> endpoint provides chunks of the tree called <i>tiles</i> which the <code>go</code> command\n\n\n    can use for proofs. Below is an example of how the <code>go</code> command may\n\n\n    interact with the checksum database by doing a <code>/lookup</code> of a module version, then\n\n\n    requesting the tiles required for the proofs.\n  </p>\n  \n\n<div>\n  <img src=\"https://blog.golang.org/module-mirror-launch/sumdb-protocol.png\" width=\"800\" alt=\"\">\n</div>\n\n  \n  <p>\n    This checksum database allows the <code>go</code> command to safely use an otherwise\n\n\n    untrusted proxy. Because there is an auditable security layer sitting on top of\n\n\n    it, a proxy or origin server can’t intentionally, arbitrarily, or accidentally\n\n\n    start giving you the wrong code without getting caught. Even the author of a\n\n\n    module can’t move their tags around or otherwise change the bits associated with\n\n\n    a specific version from one day to the next without the change being detected.\n  </p>\n  \n\n  \n  <p>\n    If you are using Go 1.12 or earlier, you can manually check a <code>go.sum</code> file\n\n\n    against the checksum database with\n\n\n    <a href=\"https://godoc.org/golang.org/x/mod/gosumcheck\" rel=\"noopener noreferrer\">gosumcheck</a>:\n  </p>\n  \n\n  \n  <div><pre>$ go get golang.org/x/mod/gosumcheck\n$ gosumcheck /path/to/go.sum</pre></div>\n  \n\n  \n  <p>\n    In addition to verification done by the <code>go</code> command, third-party\n\n\n    auditors can hold the checksum database accountable by iterating over the log\n\n\n    looking for bad entries. They can work together and gossip about the state of\n\n\n    the tree as it grows to ensure that it remains uncompromised, and we hope that\n\n\n    the Go community will run them.\n  </p>\n  \n\n\n      \n        \n  <h4>Module Index</h4>\n  \n  \n  <p>\n    The module index is served by <a href=\"https://index.golang.org/\" rel=\"noopener noreferrer\">index.golang.org</a>, and\n\n\n    is a public feed of new module versions that become available through\n\n\n    <a href=\"https://proxy.golang.org/\" rel=\"noopener noreferrer\">proxy.golang.org</a>. This is particularly useful for\n\n\n    tool developers that want to keep their own cache of what’s available in\n\n\n    <a href=\"https://proxy.golang.org/\" rel=\"noopener noreferrer\">proxy.golang.org</a>, or keep up-to-date on some of the\n\n\n    newest modules that people are using.\n  </p>\n  \n\n\n      \n        \n  <h4>Feedback or bugs</h4>\n  \n  \n  <p>\n    We hope these services improve your experience with modules, and encourage you\n\n\n    to <a href=\"https://github.com/golang/go/issues/new?title=proxy.golang.org\" rel=\"noopener noreferrer\">file issues</a> if you run into\n\n\n    problems or have feedback!\n  </p>\n  \n\n\n      \n    \n  \n",
        ),
        media_type: Some(
            MediaType {
                mime: "image/*",
            },
        ),
        media_link: Some(
            "https://blog.golang.org/module-mirror-launch/proxy-protocol.png",
        ),
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/go1.13",
        link: "https://blog.golang.org/go1.13",
        title: "Go 1.13 is released",
        date: 2019-09-03T11:00:00Z,
        summary: Some(
            "Today the Go team is very happy to announce the release of Go 1.13. You can get it from the download page.\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n        \n  \n  <p>\n    Today the Go team is very happy to announce the release of Go 1.13. You can get it from the <a href=\"https://golang.org/dl\" rel=\"noopener noreferrer\">download page</a>.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Some of the highlights include:\n  </p>\n  \n\n      \n        \n  <ul>\n  \n    <li>The <code>go</code> command now downloads and authenticates modules <a href=\"https://golang.org/doc/go1.13#introduction\" rel=\"noopener noreferrer\">using the Go module mirror and Go checksum database by default</a></li>\n  \n    <li><a href=\"https://golang.org/doc/go1.13#language\" rel=\"noopener noreferrer\">Improvements to number literals</a></li>\n  \n    <li><a href=\"https://golang.org/doc/go1.13#error_wrapping\" rel=\"noopener noreferrer\">Error wrapping</a></li>\n  \n    <li><a href=\"https://golang.org/doc/go1.13#tls_1_3\" rel=\"noopener noreferrer\">TLS 1.3 on by default</a></li>\n  \n    <li><a href=\"https://golang.org/doc/go1.13#modules\" rel=\"noopener noreferrer\">Improved modules support</a></li>\n  \n  </ul>\n\n      \n        \n  \n  <p>\n    For the complete list of changes and more information about the improvements above, see the <a href=\"https://golang.org/doc/go1.13\" rel=\"noopener noreferrer\"><b>Go 1.13 release notes</b></a>.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    We want to thank everyone who contributed to this release by writing code, filing bugs, providing feedback, and/or testing the beta and release candidates.\n\n\n    Your contributions and diligence helped to ensure that Go 1.13 is as stable as possible.\n\n\n    That said, if you notice any problems, please <a href=\"https://golang.org/issue/new\" rel=\"noopener noreferrer\">file an issue</a>.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    We hope you enjoy the new release!\n  </p>\n  \n\n      \n    \n  \n",
        ),
        media_type: None,
        media_link: None,
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/publishing-go-modules",
        link: "https://blog.golang.org/publishing-go-modules",
        title: "Publishing Go Modules",
        date: 2019-09-26T11:00:00Z,
        summary: Some(
            "This post is part 3 in a series.\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n  <h4>Introduction</h4>\n  \n  \n  <p>\n    This post is part 3 in a series.\n  </p>\n  \n\n  <ul>\n  \n    <li>Part 1 — <a href=\"https://blog.golang.org/using-go-modules\" rel=\"noopener noreferrer\">Using Go Modules</a></li>\n  \n    <li>Part 2 — <a href=\"https://blog.golang.org/migrating-to-go-modules\" rel=\"noopener noreferrer\">Migrating To Go Modules</a></li>\n  \n    <li><b>Part 3 — Publishing Go Modules</b> (this post)</li>\n  \n    <li>Part 4 — <a href=\"https://blog.golang.org/v2-go-modules\" rel=\"noopener noreferrer\">Go Modules: v2 and Beyond</a></li>\n  \n  </ul>\n\n  \n  <p>\n    This post discusses how to write and publish modules so other modules can depend\n\n\n    on them.\n  </p>\n  \n\n  \n  <p>\n    Please note: this post covers development up to and including <code>v1</code>. If you are\n\n\n    interested in <code>v2</code>, please see <a href=\"https://blog.golang.org/v2-go-modules\" rel=\"noopener noreferrer\">Go Modules: v2 and Beyond</a>.\n  </p>\n  \n\n  \n  <p>\n    This post uses <a href=\"https://git-scm.com/\" rel=\"noopener noreferrer\">Git</a> in examples.\n\n\n    <a href=\"https://www.mercurial-scm.org/\" rel=\"noopener noreferrer\">Mercurial</a>,\n\n\n    <a href=\"http://wiki.bazaar.canonical.com/\" rel=\"noopener noreferrer\">Bazaar</a>, and others are supported as well.\n  </p>\n  \n\n\n    \n      \n  <h4>Project setup</h4>\n  \n  \n  <p>\n    For this post, you\'ll need an existing project to use as an example. So, start\n\n\n    with the files from the end of the\n\n\n    <a href=\"https://blog.golang.org/using-go-modules\" rel=\"noopener noreferrer\">Using Go Modules</a> article:\n  </p>\n  \n\n  \n  <div><pre>$ cat go.mod\nmodule example.com/hello\n\ngo 1.12\n\nrequire rsc.io/quote/v3 v3.1.0\n\n$ cat go.sum\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\nrsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n\n$ cat hello.go\npackage hello\n\nimport \"rsc.io/quote/v3\"\n\nfunc Hello() string {\n    return quote.HelloV3()\n}\n\nfunc Proverb() string {\n    return quote.Concurrency()\n}\n\n$ cat hello_test.go\npackage hello\n\nimport (\n    \"testing\"\n)\n\nfunc TestHello(t *testing.T) {\n    want := \"Hello, world.\"\n    if got := Hello(); got != want {\n        t.Errorf(\"Hello() = %q, want %q\", got, want)\n    }\n}\n\nfunc TestProverb(t *testing.T) {\n    want := \"Concurrency is not parallelism.\"\n    if got := Proverb(); got != want {\n        t.Errorf(\"Proverb() = %q, want %q\", got, want)\n    }\n}\n\n$</pre></div>\n  \n\n  \n  <p>\n    Next, create a new <code>git</code> repository and add an initial commit. If you\'re\n\n\n    publishing your own project, be sure to include a <code>LICENSE</code> file. Change to the\n\n\n    directory containing the <code>go.mod</code> then create the repo:\n  </p>\n  \n\n  \n  <div><pre>$ git init\n$ git add LICENSE go.mod go.sum hello.go hello_test.go\n$ git commit -m \"hello: initial commit\"\n$</pre></div>\n  \n\n\n    \n      \n  <h4>Semantic versions and modules</h4>\n  \n  \n  <p>\n    Every required module in a <code>go.mod</code> has a\n\n\n    <a href=\"https://semver.org/\" rel=\"noopener noreferrer\">semantic version</a>, the minimum version of that dependency\n\n\n    to use to build the module.\n  </p>\n  \n\n  \n  <p>\n    A semantic version has the form <code>vMAJOR.MINOR.PATCH</code>.\n  </p>\n  \n\n  <ul>\n  \n    <li>Increment the <code>MAJOR</code> version when you make a <a href=\"https://golang.org/doc/go1compat\" rel=\"noopener noreferrer\">backwards incompatible</a> change to the public API of your module. This should only be done when absolutely necessary.</li>\n  \n    <li>Increment the <code>MINOR</code> version when you make a backwards compatible change to the API, like changing dependencies or adding a new function, method, struct field, or type.</li>\n  \n    <li>Increment the <code>PATCH</code> version after making minor changes that don\'t affect your module\'s public API or dependencies, like fixing a bug.</li>\n  \n  </ul>\n\n  \n  <p>\n    You can specify pre-release versions by appending a hyphen and dot separated\n\n\n    identifiers (for example, <code>v1.0.1-alpha</code> or <code>v2.2.2-beta.2</code>). Normal releases\n\n\n    are preferred by the <code>go</code> command over pre-release versions, so users must ask\n\n\n    for pre-release versions explicitly (for example,\n\n\n    <code>go get example.com/hello@v1.0.1-alpha</code>) if your module has any normal releases.\n  </p>\n  \n\n  \n  <p>\n    <code>v0</code> major versions and pre-release versions do not guarantee backwards\n\n\n    compatibility. They let you refine your API before making stability commitments\n\n\n    to your users. However, <code>v1</code> major versions and beyond require backwards\n\n\n    compatibility within that major version.\n  </p>\n  \n\n  \n  <p>\n    The version referenced in a <code>go.mod</code> may be an explicit release tagged in the\n\n\n    repository (for example, <code>v1.5.2</code>), or it may be a\n\n\n    <a href=\"https://golang.org/cmd/go/#hdr-Pseudo_versions\" rel=\"noopener noreferrer\">pseudo-version</a> based on a\n\n\n    specific commit (for example, <code>v0.0.0-20170915032832-14c0d48ead0c</code>).\n\n\n    Pseudo-versions are a special type of pre-release version. Pseudo-versions are\n\n\n    useful when a user needs to depend on a project that has not published any\n\n\n    semantic version tags, or develop against a commit that hasn\'t been tagged yet,\n\n\n    but users should not assume that pseudo-versions provide a stable or well-tested\n\n\n    API. Tagging your modules with explicit versions signals to your users that\n\n\n    specific versions are fully tested and ready to use.\n  </p>\n  \n\n  \n  <p>\n    Once you start tagging your repo with versions, it\'s important to keep tagging\n\n\n    new releases as you develop your module. When users request a new version of\n\n\n    your module (with <code>go get -u</code> or <code>go get example.com/hello</code>), the <code>go</code> command\n\n\n    will choose the greatest semantic release version available, even if that\n\n\n    version is several years old and many changes behind the primary branch.\n\n\n    Continuing to tag new releases will make your ongoing improvements available to\n\n\n    your users.\n  </p>\n  \n\n  \n  <p>\n    Do not delete version tags from your repo. If you find a bug or a security issue\n\n\n    with a version, release a new version. If people depend on a version that you\n\n\n    have deleted, their builds may fail. Similarly, once you release a version, do\n\n\n    not change or overwrite it. The\n\n\n    <a href=\"https://blog.golang.org/module-mirror-launch\" rel=\"noopener noreferrer\">module mirror and checksum database</a>\n\n\n    store modules, their versions, and signed cryptographic hashes to ensure that\n\n\n    the build of a given version remains reproducible over time.\n  </p>\n  \n\n\n    \n      \n  <h4>v0: the initial, unstable version</h4>\n  \n  \n  <p>\n    Let\'s tag the module with a <code>v0</code> semantic version. A <code>v0</code> version does not make\n\n\n    any stability guarantees, so nearly all projects should start with <code>v0</code> as they\n\n\n    refine their public API.\n  </p>\n  \n\n  \n  <p>\n    Tagging a new version has a few steps:\n  </p>\n  \n\n  \n  <p>\n    1. Run <code>go mod tidy</code>, which removes any dependencies the module might have accumulated that are no longer necessary.\n  </p>\n  \n\n  \n  <p>\n    2. Run <code>go test ./...</code> a final time to make sure everything is working.\n  </p>\n  \n\n  \n  <p>\n    3. Tag the project with a new version using <a href=\"https://git-scm.com/docs/git-tag\" rel=\"noopener noreferrer\"><code>git tag</code></a>.\n  </p>\n  \n\n  \n  <p>\n    4. Push the new tag to the origin repository.\n  </p>\n  \n\n  \n  <div><pre>$ go mod tidy\n$ go test ./...\nok      example.com/hello       0.015s\n$ git add go.mod go.sum hello.go hello_test.go\n$ git commit -m \"hello: changes for v0.1.0\"\n$ git tag v0.1.0\n$ git push origin v0.1.0\n$</pre></div>\n  \n\n  \n  <p>\n    Now other projects can depend on <code>v0.1.0</code> of <code>example.com/hello</code>. For your own\n\n\n    module, you can run <code>go list -m example.com/hello@v0.1.0</code> to confirm the latest\n\n\n    version is available (this example module does not exist, so no versions are\n\n\n    available). If you don\'t see the latest version immediately and you\'re using the\n\n\n    Go module proxy (the default since Go 1.13), try again in a few minutes to give\n\n\n    the proxy time to load the new version.\n  </p>\n  \n\n  \n  <p>\n    If you add to the public API, make a breaking change to a <code>v0</code> module, or\n\n\n    upgrade the minor or version of one of your dependencies,  increment the <code>MINOR</code>\n\n\n    version for your next release. For example, the next release after <code>v0.1.0</code>\n\n\n    would be <code>v0.2.0</code>.\n  </p>\n  \n\n  \n  <p>\n    If you fix a bug in an existing version, increment the <code>PATCH</code> version. For\n\n\n    example, the next release after <code>v0.1.0</code> would be <code>v0.1.1</code>.\n  </p>\n  \n\n\n    \n      \n  <h4>v1: the first stable version</h4>\n  \n  \n  <p>\n    Once you are absolutely sure your module\'s API is stable, you can release\n\n\n    <code>v1.0.0</code>. A <code>v1</code> major version communicates to users that no incompatible\n\n\n    changes will be made to the module\'s API. They can upgrade to new <code>v1</code> minor and\n\n\n    patch releases, and their code should not break. Function and method signatures\n\n\n    will not change, exported types will not be removed, and so on. If there are\n\n\n    changes to the API, they will be backwards compatible (for example, adding a new\n\n\n    field to a struct) and will be included in a new minor release. If there are bug\n\n\n    fixes (for example, a security fix), they will be included in a patch release\n\n\n    (or as part of a minor release).\n  </p>\n  \n\n  \n  <p>\n    Sometimes, maintaining backwards compatibility can lead to awkward APIs. That\'s\n\n\n    OK. An imperfect API is better than breaking users\' existing code.\n  </p>\n  \n\n  \n  <p>\n    The standard library\'s <code>strings</code> package is a prime example of maintaining\n\n\n    backwards compatibility at the cost of API consistency.\n  </p>\n  \n\n  <ul>\n  \n    <li><a href=\"https://godoc.org/strings#Split\" rel=\"noopener noreferrer\"><code>Split</code></a> slices a string into all substrings separated by a separator and returns a slice of the substrings between those separators.</li>\n  \n    <li><a href=\"https://godoc.org/strings#SplitN\" rel=\"noopener noreferrer\"><code>SplitN</code></a> can be used to control the number of substrings to return.</li>\n  \n  </ul>\n\n  \n  <p>\n    However, <a href=\"https://godoc.org/strings#Replace\" rel=\"noopener noreferrer\"><code>Replace</code></a> took a count of how\n\n\n    many instances of the string to replace from the beginning (unlike <code>Split</code>).\n  </p>\n  \n\n  \n  <p>\n    Given <code>Split</code> and <code>SplitN</code>, you would expect functions like <code>Replace</code> and\n\n\n    <code>ReplaceN</code>. But, we couldn\'t change the existing <code>Replace</code> without breaking\n\n\n    callers, which we promised not to do. So, in Go 1.12, we added a new function,\n\n\n    <a href=\"https://godoc.org/strings#ReplaceAll\" rel=\"noopener noreferrer\"><code>ReplaceAll</code></a>. The resulting API is a\n\n\n    little odd, since <code>Split</code> and <code>Replace</code> behave differently, but that\n\n\n    inconsistency is better than a breaking change.\n  </p>\n  \n\n  \n  <p>\n    Let\'s say you\'re happy with the API of <code>example.com/hello</code> and you want to\n\n\n    release <code>v1</code> as the first stable version.\n  </p>\n  \n\n  \n  <p>\n    Tagging <code>v1</code> uses the same process as tagging a <code>v0</code> version: run <code>go mod tidy</code>\n\n\n    and <code>go test ./...</code>, tag the version, and push the tag to the origin repository:\n  </p>\n  \n\n  \n  <div><pre>$ go mod tidy\n$ go test ./...\nok      example.com/hello       0.015s\n$ git add go.mod go.sum hello.go hello_test.go\n$ git commit -m \"hello: changes for v1.0.0\"\n$ git tag v1.0.0\n$ git push origin v1.0.0\n$</pre></div>\n  \n\n  \n  <p>\n    At this point, the <code>v1</code> API of <code>example.com/hello</code> is solidified. This\n\n\n    communicates to everyone that our API is stable and they should feel comfortable\n\n\n    using it.\n  </p>\n  \n\n\n    \n      \n  <h4>Conclusion</h4>\n  \n  \n  <p>\n    This post walked through the process of tagging a module with semantic versions\n\n\n    and when to release <code>v1</code>. A future post will cover how to maintain and publish\n\n\n    modules at <code>v2</code> and beyond.\n  </p>\n  \n\n  \n  <p>\n    To provide feedback and help shape the future of dependency management in Go,\n\n\n    please send us <a href=\"https://golang.org/issue/new\" rel=\"noopener noreferrer\">bug reports</a> or\n\n\n    <a href=\"https://golang.org/wiki/ExperienceReports\" rel=\"noopener noreferrer\">experience reports</a>.\n  </p>\n  \n\n  \n  <p>\n    Thanks for all your feedback and help improving Go modules.\n  </p>\n  \n\n\n    \n  \n",
        ),
        media_type: None,
        media_link: None,
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/go1.13-errors",
        link: "https://blog.golang.org/go1.13-errors",
        title: "Working with Errors in Go 1.13",
        date: 2019-10-17T11:00:00Z,
        summary: Some(
            "Go’s treatment of errors as values\nhas served us well over the last decade. Although the standard library’s support\nfor errors has been minimal—just the errors.New and fmt.Errorf functions,\nwhich produce errors that contain only a message—the built-in error interface\nallows Go programmers to add whatever information they desire. All it requires\nis a type that implements an Error method:\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n  <h4>Introduction</h4>\n  \n  \n  <p>\n    Go’s treatment of <a href=\"https://blog.golang.org/errors-are-values\" rel=\"noopener noreferrer\">errors as values</a>\n\n\n    has served us well over the last decade. Although the standard library’s support\n\n\n    for errors has been minimal—just the <code>errors.New</code> and <code>fmt.Errorf</code> functions,\n\n\n    which produce errors that contain only a message—the built-in <code>error</code> interface\n\n\n    allows Go programmers to add whatever information they desire. All it requires\n\n\n    is a type that implements an <code>Error</code> method:\n  </p>\n  \n\n  \n  <div><pre>type QueryError struct {\n    Query string\n    Err   error\n}\n\nfunc (e *QueryError) Error() string { return e.Query + \": \" + e.Err.Error() }</pre></div>\n  \n\n  \n  <p>\n    Error types like this one are ubiquitous, and the information they store varies\n\n\n    widely, from timestamps to filenames to server addresses. Often, that\n\n\n    information includes another, lower-level error to provide additional context.\n  </p>\n  \n\n  \n  <p>\n    The pattern of one error containing another is so pervasive in Go code that,\n\n\n    after <a href=\"https://golang.org/issue/29934\" rel=\"noopener noreferrer\">extensive discussion</a>, Go 1.13 added\n\n\n    explicit support for it. This post describes the additions to the standard\n\n\n    library that provide that support: three new functions in the <code>errors</code> package,\n\n\n    and a new formatting verb for <code>fmt.Errorf</code>.\n  </p>\n  \n\n  \n  <p>\n    Before describing the changes in detail, let\'s review how errors are examined\n\n\n    and constructed in previous versions of the language.\n  </p>\n  \n\n\n    \n      \n  <h4>Errors before Go 1.13</h4>\n  \n  <h4>Examining errors</h4>\n  \n  \n  <p>\n    Go errors are values. Programs make decisions based on those values in a few\n\n\n    ways. The most common is to compare an error to <code>nil</code> to see if an operation\n\n\n    failed.\n  </p>\n  \n\n  \n  <div><pre>if err != nil {\n    // something went wrong\n}</pre></div>\n  \n\n  \n  <p>\n    Sometimes we compare an error to a known <i>sentinel</i> value, to see if a specific error has occurred.\n  </p>\n  \n\n  \n  <div><pre>var ErrNotFound = errors.New(\"not found\")\n\nif err == ErrNotFound {\n    // something wasn\'t found\n}</pre></div>\n  \n\n  \n  <p>\n    An error value may be of any type which satisfies the language-defined <code>error</code>\n\n\n    interface. A program can use a type assertion or type switch to view an error\n\n\n    value as a more specific type.\n  </p>\n  \n\n  \n  <div><pre>type NotFoundError struct {\n    Name string\n}\n\nfunc (e *NotFoundError) Error() string { return e.Name + \": not found\" }\n\nif e, ok := err.(*NotFoundError); ok {\n    // e.Name wasn\'t found\n}</pre></div>\n  \n\n\n  <h4>Adding information</h4>\n  \n  \n  <p>\n    Frequently a function passes an error up the call stack while adding information\n\n\n    to it, like a brief description of what was happening when the error occurred. A\n\n\n    simple way to do this is to construct a new error that includes the text of the\n\n\n    previous one:\n  </p>\n  \n\n  \n  <div><pre>if err != nil {\n    return fmt.Errorf(\"decompress %v: %v\", name, err)\n}</pre></div>\n  \n\n  \n  <p>\n    Creating a new error with <code>fmt.Errorf</code> discards everything from the original\n\n\n    error except the text. As we saw above with <code>QueryError</code>, we may sometimes want\n\n\n    to define a new error type that contains the underlying error, preserving it for\n\n\n    inspection by code. Here is <code>QueryError</code> again:\n  </p>\n  \n\n  \n  <div><pre>type QueryError struct {\n    Query string\n    Err   error\n}</pre></div>\n  \n\n  \n  <p>\n    Programs can look inside a <code>*QueryError</code> value to make decisions based on the\n\n\n    underlying error. You\'ll sometimes see this referred to as \"unwrapping\" the\n\n\n    error.\n  </p>\n  \n\n  \n  <div><pre>if e, ok := err.(*QueryError); ok &amp;&amp; e.Err == ErrPermission {\n    // query failed because of a permission problem\n}</pre></div>\n  \n\n  \n  <p>\n    The <code>os.PathError</code> type in the standard library is another example of one error which contains another.\n  </p>\n  \n\n\n\n    \n      \n  <h4>Errors in Go 1.13</h4>\n  \n  <h4>The Unwrap method</h4>\n  \n  \n  <p>\n    Go 1.13 introduces new features to the <code>errors</code> and <code>fmt</code> standard library\n\n\n    packages to simplify working with errors that contain other errors. The most\n\n\n    significant of these is a convention rather than a change: an error which\n\n\n    contains another may implement an <code>Unwrap</code> method returning the underlying\n\n\n    error. If <code>e1.Unwrap()</code> returns <code>e2</code>, then we say that <code>e1</code> <i>wraps</i> <code>e2</code>, and\n\n\n    that you can <i>unwrap</i> <code>e1</code> to get <code>e2</code>.\n  </p>\n  \n\n  \n  <p>\n    Following this convention, we can give the <code>QueryError</code> type above an <code>Unwrap</code>\n\n\n    method that returns its contained error:\n  </p>\n  \n\n  \n  <div><pre>func (e *QueryError) Unwrap() error { return e.Err }</pre></div>\n  \n\n  \n  <p>\n    The result of unwrapping an error may itself have an <code>Unwrap</code> method; we call\n\n\n    the sequence of errors produced by repeated unwrapping the <i>error chain</i>.\n  </p>\n  \n\n\n  <h4>Examining errors with Is and As</h4>\n  \n  \n  <p>\n    The Go 1.13 <code>errors</code> package includes two new functions for examining errors: <code>Is</code> and <code>As</code>. \n  </p>\n  \n\n  \n  <p>\n    The <code>errors.Is</code> function compares an error to a value.\n  </p>\n  \n\n  \n  <div><pre>// Similar to:\n//   if err == ErrNotFound { … }\nif errors.Is(err, ErrNotFound) {\n    // something wasn\'t found\n}</pre></div>\n  \n\n  \n  <p>\n    The <code>As</code> function tests whether an error is a specific type.\n  </p>\n  \n\n  \n  <div><pre>// Similar to:\n//   if e, ok := err.(*QueryError); ok { … }\nvar e *QueryError\nif errors.As(err, &amp;e) {\n    // err is a *QueryError, and e is set to the error\'s value\n}</pre></div>\n  \n\n  \n  <p>\n    In the simplest case, the <code>errors.Is</code> function behaves like a comparison to a\n\n\n    sentinel error, and the <code>errors.As</code> function behaves like a type assertion. When\n\n\n    operating on wrapped errors, however, these functions consider all the errors in\n\n\n    a chain. Let\'s look again at the example from above of unwrapping a <code>QueryError</code>\n\n\n    to examine the underlying error:\n  </p>\n  \n\n  \n  <div><pre>if e, ok := err.(*QueryError); ok &amp;&amp; e.Err == ErrPermission {\n    // query failed because of a permission problem\n}</pre></div>\n  \n\n  \n  <p>\n    Using the <code>errors.Is</code> function, we can write this as:\n  </p>\n  \n\n  \n  <div><pre>if errors.Is(err, ErrPermission) {\n    // err, or some error that it wraps, is a permission problem\n}</pre></div>\n  \n\n  \n  <p>\n    The <code>errors</code> package also includes a new <code>Unwrap</code> function which returns the\n\n\n    result of calling an error\'s <code>Unwrap</code> method, or <code>nil</code> when the error has no\n\n\n    <code>Unwrap</code> method. It is usually better to use <code>errors.Is</code> or <code>errors.As</code>,\n\n\n    however, since these functions will examine the entire chain in a single call.\n  </p>\n  \n\n\n  <h4>Wrapping errors with %w</h4>\n  \n  \n  <p>\n    As mentioned earlier, it is common to use the <code>fmt.Errorf</code> function to add additional information to an error.\n  </p>\n  \n\n  \n  <div><pre>if err != nil {\n    return fmt.Errorf(\"decompress %v: %v\", name, err)\n}</pre></div>\n  \n\n  \n  <p>\n    In Go 1.13, the <code>fmt.Errorf</code> function supports a new <code>%w</code> verb. When this verb\n\n\n    is present, the error returned by <code>fmt.Errorf</code> will have an <code>Unwrap</code> method\n\n\n    returning the argument of <code>%w</code>, which must be an error. In all other ways, <code>%w</code>\n\n\n    is identical to <code>%v</code>.\n  </p>\n  \n\n  \n  <div><pre>if err != nil {\n    // Return an error which unwraps to err.\n    return fmt.Errorf(\"decompress %v: %w\", name, err)\n}</pre></div>\n  \n\n  \n  <p>\n    Wrapping an error with <code>%w</code> makes it available to <code>errors.Is</code> and <code>errors.As</code>:\n  </p>\n  \n\n  \n  <div><pre>err := fmt.Errorf(\"access denied: %w\", ErrPermission)\n...\nif errors.Is(err, ErrPermission) ...</pre></div>\n  \n\n\n  <h4>Whether to Wrap</h4>\n  \n  \n  <p>\n    When adding additional context to an error, either with <code>fmt.Errorf</code> or by\n\n\n    implementing a custom type, you need to decide whether the new error should wrap\n\n\n    the original. There is no single answer to this question; it depends on the\n\n\n    context in which the new error is created. Wrap an error to expose it to\n\n\n    callers. Do not wrap an error when doing so would expose implementation details.\n  </p>\n  \n\n  \n  <p>\n    As one example, imagine a <code>Parse</code> function which reads a complex data structure\n\n\n    from an <code>io.Reader</code>. If an error occurs, we wish to report the line and column\n\n\n    number at which it occurred. If the error occurs while reading from the\n\n\n    <code>io.Reader</code>, we will want to wrap that error to allow inspection of the\n\n\n    underlying problem. Since the caller provided the <code>io.Reader</code> to the function,\n\n\n    it makes sense to expose the error produced by it.\n  </p>\n  \n\n  \n  <p>\n    In contrast, a function which makes several calls to a database probably should\n\n\n    not return an error which unwraps to the result of one of those calls. If the\n\n\n    database used by the function is an implementation detail, then exposing these\n\n\n    errors is a violation of abstraction. For example, if the <code>LookupUser</code> function\n\n\n    of your package <code>pkg</code> uses Go\'s <code>database/sql</code> package, then it may encounter a\n\n\n    <code>sql.ErrNoRows</code> error. If you return that error with\n\n\n    <code>fmt.Errorf(\"accessing DB: %v\", err)</code>\n\n\n    then a caller cannot look inside to find the <code>sql.ErrNoRows</code>. But if\n\n\n    the function instead returns <code>fmt.Errorf(\"accessing DB: %w\", err)</code>, then a\n\n\n    caller could reasonably write\n  </p>\n  \n\n  \n  <div><pre>err := pkg.LookupUser(...)\nif errors.Is(err, sql.ErrNoRows) …</pre></div>\n  \n\n  \n  <p>\n    At that point, the function must always return <code>sql.ErrNoRows</code> if you don\'t want\n\n\n    to break your clients, even if you switch to a different database package. In\n\n\n    other words, wrapping an error makes that error part of your API. If you don\'t\n\n\n    want to commit to supporting that error as part of your API in the future, you\n\n\n    shouldn\'t wrap the error.\n  </p>\n  \n\n  \n  <p>\n    It’s important to remember that whether you wrap or not, the error text will be\n\n\n    the same. A <i>person</i> trying to understand the error will have the same information\n\n\n    either way; the choice to wrap is about whether to give <i>programs</i> additional\n\n\n    information so they can make more informed decisions, or to withhold that\n\n\n    information to preserve an abstraction layer.\n  </p>\n  \n\n\n\n    \n      \n  <h4>Customizing error tests with Is and As methods</h4>\n  \n  \n  <p>\n    The <code>errors.Is</code> function examines each error in a chain for a match with a\n\n\n    target value. By default, an error matches the target if the two are equal. In\n\n\n    addition, an error in the chain may declare that it matches a target by\n\n\n    implementing an <code>Is</code> <i>method</i>.\n  </p>\n  \n\n  \n  <p>\n    As an example, consider this error inspired by the\n\n\n    <a href=\"https://commandcenter.blogspot.com/2017/12/error-handling-in-upspin.html\" rel=\"noopener noreferrer\">Upspin error package</a>\n\n\n    which compares an error against a template, considering only fields which are\n\n\n    non-zero in the template:\n  </p>\n  \n\n  \n  <div><pre>type Error struct {\n    Path string\n    User string\n}\n\nfunc (e *Error) Is(target error) bool {\n    t, ok := target.(*Error)\n    if !ok {\n        return false\n    }\n    return (e.Path == t.Path || t.Path == \"\") &amp;&amp;\n           (e.User == t.User || t.User == \"\")\n}\n\nif errors.Is(err, &amp;Error{User: \"someuser\"}) {\n    // err\'s User field is \"someuser\".\n}</pre></div>\n  \n\n  \n  <p>\n    The <code>errors.As</code> function similarly consults an <code>As</code> method when present.\n  </p>\n  \n\n\n    \n      \n  <h4>Errors and package APIs</h4>\n  \n  \n  <p>\n    A package which returns errors (and most do) should describe what properties of\n\n\n    those errors programmers may rely on. A well-designed package will also avoid\n\n\n    returning errors with properties that should not be relied upon.\n  </p>\n  \n\n  \n  <p>\n    The simplest specification is to say that operations either succeed or fail,\n\n\n    returning a nil or non-nil error value respectively. In many cases, no further\n\n\n    information is needed.\n  </p>\n  \n\n  \n  <p>\n    If we wish a function to return an identifiable error condition, such as \"item\n\n\n    not found,\" we might return an error wrapping a sentinel.\n  </p>\n  \n\n  \n  <div><pre>var ErrNotFound = errors.New(\"not found\")\n\n// FetchItem returns the named item.\n//\n// If no item with the name exists, FetchItem returns an error\n// wrapping ErrNotFound.\nfunc FetchItem(name string) (*Item, error) {\n    if itemNotFound(name) {\n        return nil, fmt.Errorf(\"%q: %w\", name, ErrNotFound)\n    }\n    // ...\n}</pre></div>\n  \n\n  \n  <p>\n    There are other existing patterns for providing errors which can be semantically\n\n\n    examined by the caller, such as directly returning a sentinel value, a specific\n\n\n    type, or a value which can be examined with a predicate function.\n  </p>\n  \n\n  \n  <p>\n    In all cases, care should be taken not to expose internal details to the user.\n\n\n    As we touched on in \"Whether to Wrap\" above, when you return\n\n\n    an error from another package you should convert the error to a form that does\n\n\n    not expose the underlying error, unless you are willing to commit to returning\n\n\n    that specific error in the future.\n  </p>\n  \n\n  \n  <div><pre>f, err := os.Open(filename)\nif err != nil {\n    // The *os.PathError returned by os.Open is an internal detail.\n    // To avoid exposing it to the caller, repackage it as a new\n    // error with the same text. We use the %v formatting verb, since\n    // %w would permit the caller to unwrap the original *os.PathError.\n    return fmt.Errorf(\"%v\", err)\n}</pre></div>\n  \n\n  \n  <p>\n    If a function is defined as returning an error wrapping some sentinel or type,\n\n\n    do not return the underlying error directly.\n  </p>\n  \n\n  \n  <div><pre>var ErrPermission = errors.New(\"permission denied\")\n\n// DoSomething returns an error wrapping ErrPermission if the user\n// does not have permission to do something.\nfunc DoSomething() error {\n    if !userHasPermission() {\n        // If we return ErrPermission directly, callers might come\n        // to depend on the exact error value, writing code like this:\n        //\n        //     if err := pkg.DoSomething(); err == pkg.ErrPermission { … }\n        //\n        // This will cause problems if we want to add additional\n        // context to the error in the future. To avoid this, we\n        // return an error wrapping the sentinel so that users must\n        // always unwrap it:\n        //\n        //     if err := pkg.DoSomething(); errors.Is(err, pkg.ErrPermission) { ... }\n        return fmt.Errorf(\"%w\", ErrPermission)\n    }\n    // ...\n}</pre></div>\n  \n\n\n    \n      \n  <h4>Conclusion</h4>\n  \n  \n  <p>\n    Although the changes we’ve discussed amount to just three functions and a\n\n\n    formatting verb, we hope they will go a long way toward improving how errors are\n\n\n    handled in Go programs. We expect that wrapping to provide additional context\n\n\n    will become commonplace, helping programs to make better decisions and helping\n\n\n    programmers to find bugs more quickly.\n  </p>\n  \n\n  \n  <p>\n    As Russ Cox said in his <a href=\"https://blog.golang.org/experiment\" rel=\"noopener noreferrer\">GopherCon 2019 keynote</a>,\n\n\n    on the path to Go 2 we experiment, simplify and ship. Now that we’ve\n\n\n    shipped these changes, we look forward to the experiments that will follow.\n  </p>\n  \n\n\n    \n  \n",
        ),
        media_type: None,
        media_link: None,
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/v2-go-modules",
        link: "https://blog.golang.org/v2-go-modules",
        title: "Go Modules: v2 and Beyond",
        date: 2019-11-07T11:00:00Z,
        summary: Some(
            "This post is part 4 in a series.\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n  <h4>Introduction</h4>\n  \n  \n  <p>\n    This post is part 4 in a series.\n  </p>\n  \n\n  <ul>\n  \n    <li>Part 1 — <a href=\"https://blog.golang.org/using-go-modules\" rel=\"noopener noreferrer\">Using Go Modules</a></li>\n  \n    <li>Part 2 — <a href=\"https://blog.golang.org/migrating-to-go-modules\" rel=\"noopener noreferrer\">Migrating To Go Modules</a></li>\n  \n    <li>Part 3 — <a href=\"https://blog.golang.org/publishing-go-modules\" rel=\"noopener noreferrer\">Publishing Go Modules</a></li>\n  \n    <li><b>Part 4 — Go Modules: v2 and Beyond</b> (this post)</li>\n  \n  </ul>\n\n  \n  <p>\n    As a successful project matures and new requirements are added, past features\n\n\n    and design decisions might stop making sense. Developers may want to integrate\n\n\n    lessons they\'ve learned by removing deprecated functions, renaming types, or\n\n\n    splitting complicated packages into manageable pieces. These kinds of changes\n\n\n    require effort by downstream users to migrate their code to the new API, so they\n\n\n    should not be made without careful consideration that the benefits outweigh the\n\n\n    costs.\n  </p>\n  \n\n  \n  <p>\n    For projects that are still experimental — at major version <code>v0</code> — occasional\n\n\n    breaking changes are expected by users. For projects which are declared stable\n\n\n    — at major version <code>v1</code> or higher — breaking changes must be done in a new major\n\n\n    version. This post explores major version semantics, how to create and publish a new\n\n\n    major version, and how to maintain multiple major versions of a module.\n  </p>\n  \n\n\n    \n      \n  <h4>Major versions and module paths</h4>\n  \n  \n  <p>\n    Modules formalized an important principle in Go, the\n\n\n    <a href=\"https://research.swtch.com/vgo-import\" rel=\"noopener noreferrer\"><b>import compatibility rule</b></a>:\n  </p>\n  \n\n  \n  <div><pre>If an old package and a new package have the same import path,\nthe new package must be backwards compatible with the old package.</pre></div>\n  \n\n  \n  <p>\n    By definition, a new major version of a package is not backwards compatible with\n\n\n    the previous version. This means a new major version of a module must have a\n\n\n    different module path than the previous version. Starting with <code>v2</code>, the major\n\n\n    version must appear at the end of the module path (declared in the <code>module</code>\n\n\n    statement in the <code>go.mod</code> file). For example, when the authors of the module\n\n\n    <code>github.com/googleapis/gax-go</code> developed <code>v2</code>, they used the new module path\n\n\n    <code>github.com/googleapis/gax-go/v2</code>. Users who wanted to use <code>v2</code> had to change\n\n\n    their package imports and module requirements to <code>github.com/googleapis/gax-go/v2</code>.\n  </p>\n  \n\n  \n  <p>\n    The need for major version suffixes is one of the ways Go modules differs from\n\n\n    most other dependency management systems. Suffixes are needed to solve\n\n\n    the <a href=\"https://research.swtch.com/vgo-import#dependency_story\" rel=\"noopener noreferrer\">diamond dependency problem</a>.\n\n\n    Before Go modules, <a href=\"http://gopkg.in/\" rel=\"noopener noreferrer\">gopkg.in</a> allowed package maintainers to\n\n\n    follow what we now refer to as the import compatibility rule. With gopkg.in, if\n\n\n    you depend on a package that imports <code>gopkg.in/yaml.v1</code> and another package that\n\n\n    imports <code>gopkg.in/yaml.v2</code>, there is no conflict because the two <code>yaml</code> packages\n\n\n    have different import paths — they use a version suffix, as with Go modules.\n\n\n    Since gopkg.in shares the same version suffix methodology as Go modules, the Go\n\n\n    command accepts the <code>.v2</code> in <code>gopkg.in/yaml.v2</code> as a valid major version suffix.\n\n\n    This is a special case for compatibility with gopkg.in: modules hosted at other\n\n\n    domains need a slash suffix like <code>/v2</code>.\n  </p>\n  \n\n\n    \n      \n  <h4>Major version strategies</h4>\n  \n  \n  <p>\n    The recommended strategy is to develop <code>v2+</code> modules in a directory named after\n\n\n    the major version suffix.\n  </p>\n  \n\n  \n  <div><pre>github.com/googleapis/gax-go @ master branch\n/go.mod    → module github.com/googleapis/gax-go\n/v2/go.mod → module github.com/googleapis/gax-go/v2</pre></div>\n  \n\n  \n  <p>\n    This approach is compatible with tools that aren\'t aware of modules: file paths\n\n\n    within the repository match the paths expected by <code>go get</code> in <code>GOPATH</code> mode.\n\n\n    This strategy also allows all major versions to be developed together in\n\n\n    different directories.\n  </p>\n  \n\n  \n  <p>\n    Other strategies may keep major versions on separate branches. However, if\n\n\n    <code>v2+</code> source code is on the repository\'s default branch (usually <code>master</code>),\n\n\n    tools that are not version-aware — including the <code>go</code> command in <code>GOPATH</code> mode\n\n\n    — may not distinguish between major versions.\n  </p>\n  \n\n  \n  <p>\n    The examples in this post will follow the major version subdirectory strategy,\n\n\n    since it provides the most compatibility. We recommend that module authors\n\n\n    follow this strategy as long as they have users developing in <code>GOPATH</code> mode.\n  </p>\n  \n\n\n    \n      \n  <h4>Publishing v2 and beyond</h4>\n  \n  \n  <p>\n    This post uses <code>github.com/googleapis/gax-go</code> as an example:\n  </p>\n  \n\n  \n  <div><pre>$ pwd\n/tmp/gax-go\n$ ls\nCODE_OF_CONDUCT.md  call_option.go  internal\nCONTRIBUTING.md     gax.go          invoke.go\nLICENSE             go.mod          tools.go\nREADME.md           go.sum          RELEASING.md\nheader.go\n$ cat go.mod\nmodule github.com/googleapis/gax-go\n\ngo 1.9\n\nrequire (\n    github.com/golang/protobuf v1.3.1\n    golang.org/x/exp v0.0.0-20190221220918-438050ddec5e\n    golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3\n    golang.org/x/tools v0.0.0-20190114222345-bf090417da8b\n    google.golang.org/grpc v1.19.0\n    honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099\n)\n$</pre></div>\n  \n\n  \n  <p>\n    To start development on <code>v2</code> of <code>github.com/googleapis/gax-go</code>, we\'ll create a\n\n\n    new <code>v2/</code> directory and copy our package into it.\n  </p>\n  \n\n  \n  <div><pre>$ mkdir v2\n$ cp *.go v2/\nbuilding file list ... done\ncall_option.go\ngax.go\nheader.go\ninvoke.go\ntools.go\n\nsent 10588 bytes  received 130 bytes  21436.00 bytes/sec\ntotal size is 10208  speedup is 0.95\n$</pre></div>\n  \n\n  \n  <p>\n    Now, let\'s create a v2 <code>go.mod</code> file by copying the current <code>go.mod</code> file and\n\n\n    adding a <code>v2/</code> suffix to the module path:\n  </p>\n  \n\n  \n  <div><pre>$ cp go.mod v2/go.mod\n$ go mod edit -module github.com/googleapis/gax-go/v2 v2/go.mod\n$</pre></div>\n  \n\n  \n  <p>\n    Note that the <code>v2</code> version is treated as a separate module from the <code>v0 / v1</code>\n\n\n    versions: both may coexist in the same build. So, if your <code>v2+</code> module has\n\n\n    multiple packages, you should update them to use the new <code>/v2</code> import path:\n\n\n    otherwise, your <code>v2+</code> module will depend on your <code>v0 / v1</code> module. For example,\n\n\n    to update all <code>github.com/my/project</code> references to <code>github.com/my/project/v2</code>,\n\n\n    you can use <code>find</code> and <code>sed</code>:\n  </p>\n  \n\n  \n  <div><pre>$ find . -type f \\\n    -name \'*.go\' \\\n    -exec sed -i -e \'s,github.com/my/project,github.com/my/project/v2,g\' {} \\;\n$</pre></div>\n  \n\n  \n  <p>\n    Now we have a <code>v2</code> module, but we want to experiment and make changes before\n\n\n    publishing a release. Until we release <code>v2.0.0</code> (or any version without a\n\n\n    pre-release suffix), we can develop and make breaking changes as we decide on\n\n\n    the new API. If we want users to be able to experiment with the new API before\n\n\n    we officially make it stable, we can publish a <code>v2</code> pre-release version:\n  </p>\n  \n\n  \n  <div><pre>$ git tag v2.0.0-alpha.1\n$ git push origin v2.0.0-alpha.1\n$</pre></div>\n  \n\n  \n  <p>\n    Once we are happy with our <code>v2</code> API and are sure we don\'t need any other breaking\n\n\n    changes, we can tag <code>v2.0.0</code>:\n  </p>\n  \n\n  \n  <div><pre>$ git tag v2.0.0\n$ git push origin v2.0.0\n$</pre></div>\n  \n\n  \n  <p>\n    At that point, there are now two major versions to maintain. Backwards\n\n\n    compatible changes and bug fixes will lead to new minor and patch releases\n\n\n    (for example, <code>v1.1.0</code>, <code>v2.0.1</code>, etc.).\n  </p>\n  \n\n\n    \n      \n  <h4>Conclusion</h4>\n  \n  \n  <p>\n    Major version changes result in development and maintenance overhead and\n\n\n    require investment from downstream users to migrate. The larger the project,\n\n\n    the larger these overheads tend to be. A major version change should only come\n\n\n    after identifying a compelling reason. Once a compelling reason has been\n\n\n    identified for a breaking change, we recommend developing multiple major\n\n\n    versions in the master branch because it is compatible with a wider variety of\n\n\n    existing tools.\n  </p>\n  \n\n  \n  <p>\n    Breaking changes to a <code>v1+</code> module should always happen in a new, <code>vN+1</code> module.\n\n\n    When a new module is released, it means additional work for the maintainers and\n\n\n    for the users who need to migrate to the new package. Maintainers should\n\n\n    therefore validate their APIs before making a stable release, and consider\n\n\n    carefully whether breaking changes are really necessary beyond <code>v1</code>.\n  </p>\n  \n\n\n    \n  \n",
        ),
        media_type: None,
        media_link: None,
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/10years",
        link: "https://blog.golang.org/10years",
        title: "Go Turns 10",
        date: 2019-11-08T11:00:00Z,
        summary: Some(
            "Happy birthday, Go!\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n        \n  \n  <p>\n    Happy birthday, Go!\n  </p>\n  \n\n      \n        \n  \n  <p>\n    This weekend we celebrate the 10th anniversary of\n\n\n    <a href=\"https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html\" rel=\"noopener noreferrer\">the Go release</a>,\n\n\n    marking the 10th birthday of Go as an open-source programming language\n\n\n    and ecosystem for building modern networked software.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    To mark the occasion,\n\n\n    <a href=\"https://twitter.com/reneefrench\" rel=\"noopener noreferrer\">Renee French</a>,\n\n\n    the creator of the\n\n\n    <a href=\"https://blog.golang.org/gopher\" rel=\"noopener noreferrer\">Go gopher</a>,\n\n\n    painted this delightful scene:\n  </p>\n  \n\n      \n        <a href=\"https://blog.golang.org/10years/gopher10th-large.jpg\" rel=\"noopener noreferrer\">\n\n      \n        \n<div>\n  <img src=\"https://blog.golang.org/10years/gopher10th-small.jpg\" width=\"850\" alt=\"\">\n</div>\n\n      \n        </a>\n\n      \n        \n  \n  <p>\n    Celebrating 10 years of Go makes me think back to early November 2009,\n\n\n    when we were getting ready to share Go with the world.\n\n\n    We didn’t know what kind of reaction to expect,\n\n\n    whether anyone would care about this little language.\n\n\n    I hoped that even if no one ended up using Go,\n\n\n    we would at least have drawn attention to some good ideas,\n\n\n    especially Go’s approach to concurrency and interfaces,\n\n\n    that could influence follow-on languages.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Once it became clear that people were excited about Go,\n\n\n    I looked at the history of popular languages\n\n\n    like C, C++, Perl, Python, and Ruby,\n\n\n    examining how long each took to gain widespread adoption.\n\n\n    For example, Perl seemed to me to have appeared fully-formed\n\n\n    in the mid-to-late 1990s, with CGI scripts and the web,\n\n\n    but it was first released in 1987.\n\n\n    This pattern repeated for almost every language I looked at:\n\n\n    it seems to take roughly a decade of quiet, steady improvement\n\n\n    and dissemination before a new language really takes off.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    I wondered: where would Go be after a decade?\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Today, we can answer that question:\n\n\n    Go is everywhere, used by at least <a href=\"https://research.swtch.com/gophercount\" rel=\"noopener noreferrer\">a million developers worldwide</a>.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Go’s original target was networked system infrastructure,\n\n\n    what we now call cloud software.\n\n\n    Every major cloud provider today uses core cloud infrastructure written in Go,\n\n\n    such as Docker, Etcd, Istio, Kubernetes, Prometheus, and Terraform;\n\n\n    the majority of the\n\n\n    <a href=\"https://www.cncf.io/projects/\" rel=\"noopener noreferrer\">Cloud Native Computing Foundation’s projects</a>\n\n\n    are written in Go.\n\n\n    Countless companies are using Go to move their own work to the cloud as well,\n\n\n    from startups building from scratch\n\n\n    to enterprises modernizing their software stack.\n\n\n    Go has also found adoption well beyond its original cloud target,\n\n\n    with uses ranging\n\n\n    from\n\n\n    controlling tiny embedded systems with\n\n\n    <a href=\"https://gobot.io/\" rel=\"noopener noreferrer\">GoBot</a> and <a href=\"https://tinygo.org/\" rel=\"noopener noreferrer\">TinyGo</a>\n\n\n    to detecting cancer with\n\n\n    <a href=\"https://medium.com/grail-eng/bigslice-a-cluster-computing-system-for-go-7e03acd2419b\" rel=\"noopener noreferrer\">massive big data analysis and machine learning at GRAIL</a>,\n\n\n    and everything in between.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    All this is to say that Go has succeeded beyond our wildest dreams.\n\n\n    And Go’s success isn’t just about the language.\n\n\n    It’s about the language, the ecosystem, and especially the community working together.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    In 2009, the language was a good idea with a working sketch of an implementation.\n\n\n    The <code>go</code> command did not exist:\n\n\n    we ran commands like <code>6g</code> to compile and <code>6l</code> to link binaries,\n\n\n    automated with makefiles.\n\n\n    We typed semicolons at the ends of statements.\n\n\n    The entire program stopped during garbage collection,\n\n\n    which then struggled to make good use of two cores.\n\n\n    Go ran only on Linux and Mac, on 32- and 64-bit x86 and 32-bit ARM.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Over the last decade, with the help of Go developers all over the world,\n\n\n    we have evolved this idea and sketch into a productive language\n\n\n    with fantastic tooling,\n\n\n    a production-quality implementation,\n\n\n    a\n\n\n    <a href=\"https://blog.golang.org/ismmkeynote\" rel=\"noopener noreferrer\">state-of-the-art garbage collector</a>,\n\n\n    and <a href=\"https://golang.org/doc/install/source#introduction\" rel=\"noopener noreferrer\">ports to 12 operating systems and 10 architectures</a>.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Any programming language needs the support of a thriving ecosystem.\n\n\n    The open source release was the seed for that ecosystem,\n\n\n    but since then, many people have contributed their time and talent\n\n\n    to fill the Go ecosystem with great tutorials, books, courses, blog posts,\n\n\n    podcasts, tools, integrations, and of course reusable Go packages importable with <code>go</code> <code>get</code>.\n\n\n    Go could never have succeeded without the support of this ecosystem.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Of course, the ecosystem needs the support of a thriving community.\n\n\n    In 2019 there are dozens of Go conferences all over the world,\n\n\n    along with\n\n\n    <a href=\"https://www.meetup.com/pro/go\" rel=\"noopener noreferrer\">over 150 Go meetup groups with over 90,000 members</a>.\n\n\n    <a href=\"https://golangbridge.org/\" rel=\"noopener noreferrer\">GoBridge</a>\n\n\n    and\n\n\n    <a href=\"https://medium.com/@carolynvs/www-loves-gobridge-ccb26309f667\" rel=\"noopener noreferrer\">Women Who Go</a>\n\n\n    help bring new voices into the Go community,\n\n\n    through mentoring, training, and conference scholarships.\n\n\n    This year alone, they have taught\n\n\n    hundreds of people from traditionally underrepresented groups\n\n\n    at workshops where community members teach and mentor those new to Go.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    There are\n\n\n    <a href=\"https://research.swtch.com/gophercount\" rel=\"noopener noreferrer\">over a million Go developers</a>\n\n\n    worldwide,\n\n\n    and companies all over the globe are looking to hire more.\n\n\n    In fact, people often tell us that learning Go\n\n\n    helped them get their first jobs in the tech industry.\n\n\n    In the end, what we’re most proud of about Go\n\n\n    is not a well-designed feature or a clever bit of code\n\n\n    but the positive impact Go has had in so many people’s lives.\n\n\n    We aimed to create a language that would help us be better developers,\n\n\n    and we are thrilled that Go has helped so many others.\n  </p>\n  \n\n      \n        \n  \n  <p>\n    As\n\n\n    <a href=\"https://twitter.com/search?q=%23GoTurns10\" rel=\"noopener noreferrer\">#GoTurns10</a>,\n\n\n    I hope everyone will take a moment to celebrate\n\n\n    the Go community and all we have achieved.\n\n\n    On behalf of the entire Go team at Google,\n\n\n    thank you to everyone who has joined us over the past decade.\n\n\n    Let’s make the next one even more incredible!\n  </p>\n  \n\n      \n        <div>\n<center>\n<a href=\"https://blog.golang.org/10years/gopher10th-pin-large.jpg\" rel=\"noopener noreferrer\">\n\n      \n        \n<div>\n  <img src=\"https://blog.golang.org/10years/gopher10th-pin-small.jpg\" width=\"150\" alt=\"\">\n</div>\n\n      \n        </a></center><a href=\"https://blog.golang.org/10years/gopher10th-pin-large.jpg\" rel=\"noopener noreferrer\">\n</a></div><a href=\"https://blog.golang.org/10years/gopher10th-pin-large.jpg\" rel=\"noopener noreferrer\">\n\n      \n    \n  \n</a>",
        ),
        media_type: Some(
            MediaType {
                mime: "image/*",
            },
        ),
        media_link: Some(
            "https://blog.golang.org/10years/gopher10th-small.jpg",
        ),
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/go.dev",
        link: "https://blog.golang.org/go.dev",
        title: "Go.dev: a new hub for Go developers",
        date: 2019-11-13T11:00:00Z,
        summary: Some(
            "Over the last two years,\nas we’ve spoken with users at companies of all sizes,\nwe’ve heard three questions repeatedly:\nwho else is using Go,\nwhat do they use it for,\nand how can I find useful Go packages?\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n        \n  \n  <p>\n    Over the last two years,\n\n\n    as we’ve spoken with users at companies of all sizes,\n\n\n    we’ve heard three questions repeatedly:\n\n\n    who else is using Go,\n\n\n    what do they use it for,\n\n\n    and how can I find useful Go packages?\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Today we are launching <a href=\"https://go.dev/\" rel=\"noopener noreferrer\">go.dev</a>, a new hub for Go developers,\n\n\n    to help answer those questions.\n\n\n    There you will find a wealth of learning resources to get started with the language,\n\n\n    featured use cases, and case studies of companies using Go.\n  </p>\n  \n\n      \n        \n<div>\n  <img src=\"https://blog.golang.org/go.dev/home.png\" width=\"850\" alt=\"\">\n</div>\n\n      \n        \n  \n  <p>\n    (Note that <a href=\"https://golang.org/\" rel=\"noopener noreferrer\">golang.org</a> is still the home for the\n\n\n    open source Go project and the Go distribution.\n\n\n    Go.dev is a companion site to provide these supporting resources.)\n  </p>\n  \n\n      \n        \n  \n  <p>\n    Clicking on Explore brings you to <a href=\"https://pkg.go.dev/\" rel=\"noopener noreferrer\">pkg.go.dev</a>,\n\n\n    a central source of information about Go packages and modules.\n\n\n    Like <a href=\"https://godoc.org/\" rel=\"noopener noreferrer\">godoc.org</a>, pkg.go.dev serves Go documentation.\n\n\n    However, it also understands modules and has information\n\n\n    about all versions of a package, including\n\n\n    <a href=\"https://pkg.go.dev/std?tab=versions\" rel=\"noopener noreferrer\">all releases of the standard library</a>!\n\n\n    And it detects and displays licenses and has a better search algorithm.\n\n\n    You can follow\n\n\n    <a href=\"https://golang.org/issue/33654\" rel=\"noopener noreferrer\">Go issue 33654</a> for future developments.\n  </p>\n  \n\n      \n        \n<div>\n  <img src=\"https://blog.golang.org/go.dev/http.png\" width=\"850\" alt=\"\">\n</div>\n\n      \n        \n  \n  <p>\n    Today’s launch is our minimum viable product for go.dev,\n\n\n    so we can share what we’ve built to help the community and get feedback.\n\n\n    We intend to expand the site over time.\n\n\n    If you have any ideas, suggestions or issues,\n\n\n    please let us know via the “Share Feedback” and “Report an Issue” links at the bottom of every page.\n\n\n    Or you can send your bugs, ideas, feature requests, and questions to\n\n\n    <a href=\"mailto:go-discovery-feedback@google.com\" rel=\"noopener noreferrer\">go-discovery-feedback@google.com</a>.\n  </p>\n  \n\n      \n    \n  \n",
        ),
        media_type: Some(
            MediaType {
                mime: "image/*",
            },
        ),
        media_link: Some(
            "https://blog.golang.org/go.dev/home.png",
        ),
        comments_link: None,
    },
    Post {
        id: -1,
        unique_id: "tag:blog.golang.org,2013:blog.golang.org/survey2019",
        link: "https://blog.golang.org/survey2019",
        title: "Announcing the 2019 Go Developer Survey",
        date: 2019-11-20T11:00:00Z,
        summary: Some(
            "Since 2016, thousands of Gophers around the world have helped the Go project by sharing your thoughts via our annual Go Developer Survey. Your feedback has played an enormous role in driving changes to our language, ecosystem, and community, including the gopls language server, new error-handling mechanics, the module mirror, and so much more from the latest Go 1.13 release. And of course, we publicly share each year\'s results, so we can all benefit from the community\'s insights.\n",
        ),
        content: Some(
            "\n  \n  \n    \n      \n  <h4>Help shape the future of Go</h4>\n  \n  \n  <p>\n    Since 2016, thousands of Gophers around the world have helped the Go project by sharing your thoughts via our annual Go Developer Survey. Your feedback has played an enormous role in driving changes to our language, ecosystem, and community, including <a href=\"https://about.sourcegraph.com/go/gophercon-2019-go-pls-stop-breaking-my-editor\" rel=\"noopener noreferrer\">the gopls language server</a>, new <a href=\"https://blog.golang.org/go1.13-errors\" rel=\"noopener noreferrer\">error-handling mechanics</a>, the <a href=\"https://blog.golang.org/module-mirror-launch\" rel=\"noopener noreferrer\">module mirror</a>, and so much more from the latest <a href=\"https://blog.golang.org/go1.13\" rel=\"noopener noreferrer\">Go 1.13 release</a>. And of course, we publicly share <a href=\"https://blog.golang.org/survey2016-results\" rel=\"noopener noreferrer\">each</a> <a href=\"https://blog.golang.org/survey2017-results\" rel=\"noopener noreferrer\">year\'s</a> <a href=\"https://blog.golang.org/survey2018-results\" rel=\"noopener noreferrer\">results</a>, so we can all benefit from the community\'s insights.\n  </p>\n  \n\n  \n  <p>\n    Today we are launching the 2019 Go Developer Survey. We\'d love to hear from everyone who uses Go, used to use Go, or is interested in using Go, to help ensure the language, community, and ecosystem fit the needs of the people closest to it. Please help us shape Go\'s future by participating in this 15-minute survey by December 15th: <a href=\"https://google.qualtrics.com/jfe/form/SV_b1xqnBCMpZAhJZ3\" rel=\"noopener noreferrer\">Take the 2019 Go Developer Survey</a>.\n  </p>\n  \n\n\n    \n      \n  <h4>Spread the word!</h4>\n  \n  \n  <p>\n    We need as many Gophers as possible to participate in this survey to help us better understand our global user base. We\'d be grateful if you would spread the word by sharing this post on your social network feeds, around the office, at meet-ups, and in other communities. Thank you!\n  </p>\n  \n\n\n    \n  \n",
        ),
        media_type: None,
        media_link: None,
        comments_link: None,
    },
]
