From e3227ec340b1d5a29dd6d47fa97c90ea4e2fbddc Mon Sep 17 00:00:00 2001 From: Denis Isaev Date: Sat, 16 May 2020 23:09:06 +0300 Subject: [PATCH] docs: add articles about contributing --- .github/renovate.json | 3 + README.md | 2 +- docs/gatsby-config.js | 2 + docs/package-lock.json | 551 ++++++++++++++++++ docs/package.json | 8 +- docs/src/components/ResponsiveContainer.js | 15 + docs/src/config/sidebar.yml | 20 +- docs/src/docs/contributing/architecture.mdx | 316 ++++++++++ .../docs/{usage => contributing}/debug.mdx | 0 docs/src/docs/contributing/faq.mdx | 29 + docs/src/docs/contributing/new-linters.mdx | 82 +++ docs/src/docs/contributing/website.mdx | 76 +++ docs/src/docs/contributing/workflow.mdx | 58 ++ docs/src/docs/index.mdx | 2 +- docs/src/docs/product/trusted-by.mdx | 1 + docs/src/docs/usage/faq.mdx | 12 +- docs/src/docs/usage/linters.mdx | 64 -- 17 files changed, 1160 insertions(+), 81 deletions(-) create mode 100644 .github/renovate.json create mode 100644 docs/src/components/ResponsiveContainer.js create mode 100644 docs/src/docs/contributing/architecture.mdx rename docs/src/docs/{usage => contributing}/debug.mdx (100%) create mode 100644 docs/src/docs/contributing/faq.mdx create mode 100644 docs/src/docs/contributing/new-linters.mdx create mode 100644 docs/src/docs/contributing/website.mdx create mode 100644 docs/src/docs/contributing/workflow.mdx diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 00000000..80235d66 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,3 @@ +{ + "ignorePaths": ["docs/**"] +} diff --git a/README.md b/README.md index e9aac7c1..fdca5792 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Documentation is hosted at https://golangci-lint.run. ## Contributors -This project exists thanks to all the people who contribute. +This project exists thanks to all the people who contribute. [How to contribute](https://golangci-lint.run/contributing/workflow/). diff --git a/docs/gatsby-config.js b/docs/gatsby-config.js index 78f88491..020daa6a 100644 --- a/docs/gatsby-config.js +++ b/docs/gatsby-config.js @@ -62,11 +62,13 @@ module.exports = { }, `gatsby-remark-responsive-iframe`, `gatsby-remark-copy-linked-files`, + `gatsby-remark-mermaid`, ], plugins: [ `gatsby-remark-autolink-headers`, `gatsby-remark-external-links`, `gatsby-remark-images`, + `gatsby-remark-mermaid`, ], }, }, diff --git a/docs/package-lock.json b/docs/package-lock.json index 7c2196a8..fab82f8d 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1007,6 +1007,11 @@ "to-fast-properties": "^2.0.0" } }, + "@braintree/sanitize-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-3.1.0.tgz", + "integrity": "sha512-GcIY79elgB+azP74j8vqkiXz8xLFfIzbQJdlwOPisgbKT00tviJQuEghOXSMVxJ00HoYJbGswr4kcllUc4xCcg==" + }, "@emotion/babel-plugin-jsx-pragmatic": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin-jsx-pragmatic/-/babel-plugin-jsx-pragmatic-0.1.5.tgz", @@ -2338,6 +2343,15 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@types/yoga-layout": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.1.tgz", @@ -2607,6 +2621,11 @@ "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, "aggregate-error": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", @@ -4510,6 +4529,21 @@ } } }, + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -5250,6 +5284,11 @@ } } }, + "css-b64-images": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/css-b64-images/-/css-b64-images-0.2.5.tgz", + "integrity": "sha1-QgBdgyBLK0pdk7axpWRBM7WSegI=" + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", @@ -5531,6 +5570,290 @@ "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" }, + "d3": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-5.16.0.tgz", + "integrity": "sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw==", + "requires": { + "d3-array": "1", + "d3-axis": "1", + "d3-brush": "1", + "d3-chord": "1", + "d3-collection": "1", + "d3-color": "1", + "d3-contour": "1", + "d3-dispatch": "1", + "d3-drag": "1", + "d3-dsv": "1", + "d3-ease": "1", + "d3-fetch": "1", + "d3-force": "1", + "d3-format": "1", + "d3-geo": "1", + "d3-hierarchy": "1", + "d3-interpolate": "1", + "d3-path": "1", + "d3-polygon": "1", + "d3-quadtree": "1", + "d3-random": "1", + "d3-scale": "2", + "d3-scale-chromatic": "1", + "d3-selection": "1", + "d3-shape": "1", + "d3-time": "1", + "d3-time-format": "2", + "d3-timer": "1", + "d3-transition": "1", + "d3-voronoi": "1", + "d3-zoom": "1" + } + }, + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "d3-axis": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", + "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" + }, + "d3-brush": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.5.tgz", + "integrity": "sha512-rEaJ5gHlgLxXugWjIkolTA0OyMvw8UWU1imYXy1v642XyyswmI1ybKOv05Ft+ewq+TFmdliD3VuK0pRp1VT/5A==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "d3-chord": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz", + "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==", + "requires": { + "d3-array": "1", + "d3-path": "1" + } + }, + "d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" + }, + "d3-color": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", + "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" + }, + "d3-contour": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz", + "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==", + "requires": { + "d3-array": "^1.1.1" + } + }, + "d3-dispatch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", + "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==" + }, + "d3-drag": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz", + "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==", + "requires": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "d3-dsv": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz", + "integrity": "sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g==", + "requires": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + } + }, + "d3-ease": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.6.tgz", + "integrity": "sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ==" + }, + "d3-fetch": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz", + "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==", + "requires": { + "d3-dsv": "1" + } + }, + "d3-force": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", + "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", + "requires": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "d3-format": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz", + "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw==" + }, + "d3-geo": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.0.tgz", + "integrity": "sha512-NalZVW+6/SpbKcnl+BCO67m8gX+nGeJdo6oGL9H6BRUGUL1e+AtPcP4vE4TwCQ/gl8y5KE7QvBzrLn+HsKIl+w==", + "requires": { + "d3-array": "1" + } + }, + "d3-hierarchy": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", + "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==" + }, + "d3-interpolate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz", + "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==", + "requires": { + "d3-color": "1" + } + }, + "d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "d3-polygon": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz", + "integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ==" + }, + "d3-quadtree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz", + "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==" + }, + "d3-random": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz", + "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==" + }, + "d3-scale": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz", + "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==", + "requires": { + "d3-array": "^1.2.0", + "d3-collection": "1", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + }, + "d3-scale-chromatic": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz", + "integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==", + "requires": { + "d3-color": "1", + "d3-interpolate": "1" + } + }, + "d3-selection": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.1.tgz", + "integrity": "sha512-BTIbRjv/m5rcVTfBs4AMBLKs4x8XaaLkwm28KWu9S2vKNqXkXt2AH2Qf0sdPZHjFxcWg/YL53zcqAz+3g4/7PA==" + }, + "d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "requires": { + "d3-path": "1" + } + }, + "d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" + }, + "d3-time-format": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz", + "integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==", + "requires": { + "d3-time": "1" + } + }, + "d3-timer": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", + "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" + }, + "d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==", + "requires": { + "d3-color": "1", + "d3-dispatch": "1", + "d3-ease": "1", + "d3-interpolate": "1", + "d3-selection": "^1.1.0", + "d3-timer": "1" + } + }, + "d3-voronoi": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz", + "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==" + }, + "d3-zoom": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz", + "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "dagre": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz", + "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==", + "requires": { + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, + "dagre-d3": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.6.4.tgz", + "integrity": "sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ==", + "requires": { + "d3": "^5.14", + "dagre": "^0.8.5", + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, "damerau-levenshtein": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", @@ -6677,6 +7000,11 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "escaper": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/escaper/-/escaper-2.5.3.tgz", + "integrity": "sha512-QGb9sFxBVpbzMggrKTX0ry1oiI4CSDAl9vIL702hzl1jGW8VZs7qfqTRX7WDOjoNDoEVGcEtu1ZOQgReSfT2kQ==" + }, "eslint": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", @@ -7644,6 +7972,27 @@ } } }, + "extract-zip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.0.tgz", + "integrity": "sha512-i42GQ498yibjdvIhivUsRslx608whtGoFIhF26Z7O4MYncBxp8CwalOs1lnHy21A9sIohWO2+uiE4SRtC9JXDg==", + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -9740,6 +10089,33 @@ } } }, + "gatsby-remark-mermaid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gatsby-remark-mermaid/-/gatsby-remark-mermaid-2.0.0.tgz", + "integrity": "sha512-VqCNjtvThhY/4j0So/suki8gACPmW7sQ8UhWBVvh/LHi/vSwgH2ud4xpJX5X9FMYbbFsVbmFB5PjSX7cs4hawQ==", + "requires": { + "mermaid": "^8.0.0", + "unist-util-visit": "^1.4.0" + }, + "dependencies": { + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "requires": { + "unist-util-is": "^3.0.0" + } + } + } + }, "gatsby-remark-responsive-iframe": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/gatsby-remark-responsive-iframe/-/gatsby-remark-responsive-iframe-2.4.2.tgz", @@ -10480,6 +10856,14 @@ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, + "graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "requires": { + "lodash": "^4.17.15" + } + }, "graphql": { "version": "14.6.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.6.0.tgz", @@ -10875,6 +11259,11 @@ "space-separated-tokens": "^1.0.0" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, "header-case": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", @@ -10975,6 +11364,27 @@ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==" }, + "html-minifier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", + "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "requires": { + "camel-case": "^3.0.0", + "clean-css": "^4.2.1", + "commander": "^2.19.0", + "he": "^1.2.0", + "param-case": "^2.1.1", + "relateurl": "^0.2.7", + "uglify-js": "^3.5.1" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, "html-tag-names": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/html-tag-names/-/html-tag-names-1.1.5.tgz", @@ -11075,6 +11485,15 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + } + }, "human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -13511,6 +13930,34 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" }, + "mermaid": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.5.0.tgz", + "integrity": "sha512-fZf4GAzkqWuSwo5L+BmzaBwWPudHkxL3M/t1RmS9Dvc2mcnv6hdhMaeC7poARpHaSGwkpb74LL81qXj+vAsVBg==", + "requires": { + "@braintree/sanitize-url": "^3.1.0", + "crypto-random-string": "^3.0.1", + "d3": "^5.7.0", + "dagre": "^0.8.4", + "dagre-d3": "^0.6.4", + "graphlib": "^2.1.7", + "he": "^1.2.0", + "lodash": "^4.17.11", + "minify": "^4.1.1", + "moment-mini": "^2.22.1", + "scope-css": "^1.2.1" + }, + "dependencies": { + "crypto-random-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-3.2.0.tgz", + "integrity": "sha512-8vPu5bsKaq2uKRy3OL7h1Oo7RayAWB8sYexLKAqvCXVib8SxgbmoF1IN4QMKjBv8uI8mp5gPPMbiRah25GMrVQ==", + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -13697,6 +14144,20 @@ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz", "integrity": "sha512-zd6KCAyXgmq6FV1mR10oKXYtvmA9vRoB6xPSTUJTbFApCtkefDnYueVR1gkof3KcdLZo1Y8mjF2DFmQMIxsHNQ==" }, + "minify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/minify/-/minify-4.1.3.tgz", + "integrity": "sha512-ykuscavxivSmVpcCzsXmsVTukWYLUUtPhHj0w2ILvHDGqC+hsuTCihBn9+PJBd58JNvWTNg9132J9nrrI2anzA==", + "requires": { + "clean-css": "^4.1.6", + "css-b64-images": "~0.2.5", + "debug": "^4.1.0", + "html-minifier": "^4.0.0", + "terser": "^4.0.0", + "try-catch": "^2.0.0", + "try-to-catch": "^1.0.2" + } + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -13810,6 +14271,11 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.25.3.tgz", "integrity": "sha512-PuYv0PHxZvzc15Sp8ybUCoQ+xpyPWvjOuK72a5ovzp2LI32rJXOiIfyoFoYvG3s6EwwrdkMyWuRiEHSZRLJNdg==" }, + "moment-mini": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.24.0.tgz", + "integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -15985,6 +16451,11 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -16055,6 +16526,33 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" }, + "puppeteer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-3.0.4.tgz", + "integrity": "sha512-1QEb4tJXXbNId7WSHlcDkS3B4GklTIebKn8Y9D6B7tAdUjQncb+8QlTjbQsAgGX5dhRG32Qycuk5XKzJgLs0sg==", + "requires": { + "debug": "^4.1.0", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -16843,6 +17341,11 @@ } } }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + }, "remark": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", @@ -17297,6 +17800,11 @@ "aproba": "^1.1.1" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, "rx": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", @@ -17432,6 +17940,16 @@ "ajv-keywords": "^3.4.1" } }, + "scope-css": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/scope-css/-/scope-css-1.2.1.tgz", + "integrity": "sha512-UjLRmyEYaDNiOS673xlVkZFlVCtckJR/dKgr434VMm7Lb+AOOqXKdAcY7PpGlJYErjXXJzKN7HWo4uRPiZZG0Q==", + "requires": { + "escaper": "^2.5.3", + "slugify": "^1.3.1", + "strip-css-comments": "^3.0.0" + } + }, "scroll-behavior": { "version": "0.9.12", "resolved": "https://registry.npmjs.org/scroll-behavior/-/scroll-behavior-0.9.12.tgz", @@ -18678,6 +19196,14 @@ "babel-plugin-transform-object-rest-spread": "^6.26.0" } }, + "strip-css-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-css-comments/-/strip-css-comments-3.0.0.tgz", + "integrity": "sha1-elYl7/iisibPiUehElTaluE9rok=", + "requires": { + "is-regexp": "^1.0.0" + } + }, "strip-dirs": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", @@ -19465,6 +19991,16 @@ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" }, + "try-catch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/try-catch/-/try-catch-2.0.1.tgz", + "integrity": "sha512-LsOrmObN/2WdM+y2xG+t16vhYrQsnV8wftXIcIOWZhQcBJvKGYuamJGwnU98A7Jxs2oZNkJztXlphEOoA0DWqg==" + }, + "try-to-catch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/try-to-catch/-/try-to-catch-1.1.1.tgz", + "integrity": "sha512-ikUlS+/BcImLhNYyIgZcEmq4byc31QpC+46/6Jm5ECWkVFhf8SM2Fp/0pMVXPX6vk45SMCwrP4Taxucne8I0VA==" + }, "ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", @@ -19546,6 +20082,21 @@ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" }, + "uglify-js": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.3.tgz", + "integrity": "sha512-r5ImcL6QyzQGVimQoov3aL2ZScywrOgBXGndbWrdehKoSvGe/RmiE5Jpw/v+GvxODt6l2tpBXwA7n+qZVlHBMA==", + "requires": { + "commander": "~2.20.3" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, "unbzip2-stream": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz", diff --git a/docs/package.json b/docs/package.json index d9e173c1..aca3df29 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,6 +11,7 @@ "@mdx-js/mdx": "^1.5.5", "@mdx-js/react": "^1.5.5", "emotion-theming": "^10.0.27", + "gatsby": "^2.19.10", "gatsby-alias-imports": "^1.0.4", "gatsby-plugin-canonical-urls": "^2.1.19", "gatsby-plugin-catch-links": "^2.1.24", @@ -18,8 +19,8 @@ "gatsby-plugin-google-analytics": "^2.1.34", "gatsby-plugin-manifest": "^2.2.37", "gatsby-plugin-mdx": "^1.0.68", - "gatsby-plugin-netlify-cache": "^1.2.0", "gatsby-plugin-netlify": "^2.3.2", + "gatsby-plugin-netlify-cache": "^1.2.0", "gatsby-plugin-offline": "^3.0.32", "gatsby-plugin-react-helmet": "^3.1.16", "gatsby-plugin-react-svg": "^3.0.0", @@ -30,21 +31,22 @@ "gatsby-remark-embedder": "^1.8.0", "gatsby-remark-external-links": "0.0.4", "gatsby-remark-images": "^3.1.42", + "gatsby-remark-mermaid": "^2.0.0", "gatsby-remark-responsive-iframe": "^2.2.31", "gatsby-source-filesystem": "^2.1.46", "gatsby-transformer-remark": "^2.8.8", "gatsby-transformer-sharp": "^2.3.13", "gatsby-transformer-yaml": "^2.2.23", - "gatsby": "^2.19.10", "polished": "^3.4.2", "prism-react-renderer": "^1.0.2", "prop-types": "^15.7.2", + "puppeteer": "^3.0.4", + "react": "^16.12.0", "react-dom": "^16.12.0", "react-headroom": "^3.0.0", "react-helmet": "^5.2.1", "react-icons": "^3.10.0", "react-live": "^2.2.2", - "react": "^16.12.0", "url-join": "^4.0.1" }, "devDependencies": {}, diff --git a/docs/src/components/ResponsiveContainer.js b/docs/src/components/ResponsiveContainer.js new file mode 100644 index 00000000..cb5a96bd --- /dev/null +++ b/docs/src/components/ResponsiveContainer.js @@ -0,0 +1,15 @@ +/** @jsx jsx */ +import { css, jsx } from "@emotion/core"; + +const ResponsiveContainer = ({ children }) => ( +
+ {children} +
+); + +export default ResponsiveContainer; diff --git a/docs/src/config/sidebar.yml b/docs/src/config/sidebar.yml index 4d407101..5519e301 100644 --- a/docs/src/config/sidebar.yml +++ b/docs/src/config/sidebar.yml @@ -16,12 +16,10 @@ link: "/usage/configuration/" - label: "False Positives" link: "/usage/false-positives/" - - label: "FAQ" - link: "/usage/faq/" - label: "Performance" link: "/usage/performance/" - - label: "Debug" - link: "/usage/debug/" + - label: "FAQ" + link: "/usage/faq/" - label: Product items: - label: "Roadmap" @@ -32,3 +30,17 @@ link: "/product/comparison/" - label: "GitHub" link: "https://github.com/golangci/golangci-lint" +- label: Contributing + items: + - label: Workflow + link: /contributing/workflow/ + - label: Architecture + link: /contributing/architecture/ + - label: New Linters + link: /contributing/new-linters/ + - label: "Debug" + link: "/contributing/debug/" + - label: FAQ + link: /contributing/faq/ + - label: This Website + link: /contributing/website/ diff --git a/docs/src/docs/contributing/architecture.mdx b/docs/src/docs/contributing/architecture.mdx new file mode 100644 index 00000000..7dd5952b --- /dev/null +++ b/docs/src/docs/contributing/architecture.mdx @@ -0,0 +1,316 @@ +--- +title: Architecture +--- + +import ResponsiveContainer from "components/ResponsiveContainer"; + +There are the following `golangci-lint` execution steps: + + + +```mermaid +graph LR + init[Init] + loadPackages[Load packages] + runLinters[Run linters] + postprocess[Postprocess issues] + print[Print issues] + + init --> loadPackages --> runLinters --> postprocess --> print + +``` + + + +## Init + +The execution starts here: + +```go title=cmd/golangci-lint/main.go +func main() { + e := commands.NewExecutor(version, commit, date) + + if err := e.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "failed executing command with error %v\n", err) + os.Exit(exitcodes.Failure) + } +} +``` + +The **executer** is our abstraction: + +```go title=pkg/commands/executor.go +type Executor struct { + rootCmd *cobra.Command + runCmd *cobra.Command + lintersCmd *cobra.Command + + exitCode int + + cfg *config.Config + log logutils.Log + reportData report.Data + DBManager *lintersdb.Manager + EnabledLintersSet *lintersdb.EnabledSet + contextLoader *lint.ContextLoader + goenv *goutil.Env + fileCache *fsutils.FileCache + lineCache *fsutils.LineCache + pkgCache *pkgcache.Cache + debugf logutils.DebugFunc + sw *timeutils.Stopwatch + + loadGuard *load.Guard + flock *flock.Flock +} +``` + +We use dependency injection and all root dependencies are stored in this executor. + +In the function `NewExecutor` we do the following: + +1. init dependencies +2. init [cobra](https://github.com/spf13/cobra) commands +3. parse config file using [viper](https://github.com/spf13/viper) and merge it with command line args. + +The following execution is controlled by `cobra`. If user a user executes `golangci-lint run` +then `cobra` executes `e.runCmd`. + +Different `cobra` commands have different runners, e.g. a `run` command is configured in the following way: + +```go title=pkg/commands/run.go +func (e *Executor) initRun() { + e.runCmd = &cobra.Command{ + Use: "run", + Short: welcomeMessage, + Run: e.executeRun, + PreRun: func(_ *cobra.Command, _ []string) { + if ok := e.acquireFileLock(); !ok { + e.log.Fatalf("Parallel golangci-lint is running") + } + }, + PostRun: func(_ *cobra.Command, _ []string) { + e.releaseFileLock() + }, + } + e.rootCmd.AddCommand(e.runCmd) + e.runCmd.SetOutput(logutils.StdOut) // use custom output to properly color it in Windows terminals + e.initRunConfiguration(e.runCmd) +} +``` + +The primary execution function of the `run` command is `executeRun`. + +## Load Packages + +Loading packages is listing all packages and their recursive dependencies for analysis. +Also, depending from enabled linters set some parsing of a source code can be performed +at this step. + +Packages loading stars here: + +```go title=pkg/lint/load.go +func (cl *ContextLoader) Load(ctx context.Context, linters []*linter.Config) (*linter.Context, error) { + loadMode := cl.findLoadMode(linters) + pkgs, err := cl.loadPackages(ctx, loadMode) + if err != nil { + return nil, err + } + + // ... + ret := &linter.Context{ + // ... + } + return ret, nil +} +``` + +First, we find a load mode as union of load modes for all enabled linters. +We use [go/packages](https://godoc.org/golang.org/x/tools/go/packages) for packages loading and use it's enum `packages.Need*` for load modes. +Load mode sets which data does a linter needs for execution. + +A linter that works only with AST need minimum of information: only filenames and AST. There is no need for +packages dependencies or type information. AST is built during `go/analysis` execution to reduce memory usage. +Such AST-based linters are configured with the following code: + +```go title=pkg/lint/linter/config.go +func (lc *Config) WithLoadFiles() *Config { + lc.LoadMode |= packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles + return lc +} +``` + +If a linter uses `go/analysis` and needs type information, we need to extract more data by `go/packages`: + +```go title=/pkg/lint/linter/config.go +func (lc *Config) WithLoadForGoAnalysis() *Config { + lc = lc.WithLoadFiles() + lc.LoadMode |= packages.NeedImports | packages.NeedDeps | packages.NeedExportsFile | packages.NeedTypesSizes + return lc +} +``` + +After finding a load mode we run `go/packages`: the library get list of dirs (or `./...` as the default value) as input +and outputs list of packages and requested information about them: filenames, type information, AST, etc. + +## Run Linters + +First, we need to find all enaled linters. All linters are registered here: + +```go title=pkg/lint/lintersdb/manager.go +func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { + // ... + lcs := []*linter.Config{ + linter.NewConfig(golinters.NewGovet(govetCfg)). + WithLoadForGoAnalysis(). + WithPresets(linter.PresetBugs). + WithAlternativeNames("vet", "vetshadow"). + WithURL("https://golang.org/cmd/vet/"), + linter.NewConfig(golinters.NewBodyclose()). + WithLoadForGoAnalysis(). + WithPresets(linter.PresetPerformance, linter.PresetBugs). + WithURL("https://github.com/timakin/bodyclose"), + // ... + } + // ... +} +``` + +We filter requested in config and command-line linters in `EnabledSet`: + +```go title=pkg/lint/lintersdb/enabled_set.go +func (es EnabledSet) GetEnabledLintersMap() (map[string]*linter.Config, error) +``` + +We merge enabled linters into one `MetaLinter` to improve execution time if we can: + +```go title=pkg/lint/lintersdb/enabled_set.go +// GetOptimizedLinters returns enabled linters after optimization (merging) of multiple linters +// into a fewer number of linters. E.g. some go/analysis linters can be optimized into +// one metalinter for data reuse and speed up. +func (es EnabledSet) GetOptimizedLinters() ([]*linter.Config, error) { + // ... + es.combineGoAnalysisLinters(resultLintersSet) + // ... +} +``` + +The `MetaLinter` just stores all merged linters inside to run them at once: + +```go title=pkg/golinters/goanalysis/metalinter.go +type MetaLinter struct { + linters []*Linter + analyzerToLinterName map[*analysis.Analyzer]string +} +``` + +Currently, all linters except `unused` can be merged into this meta linter. +The `unused` isn't merged because it has high memory usage. + +Linters execution starts in `runAnalyzers`. It's the most complex part of the `golangci-lint`. +We use custom [go/analysis](https://godoc.org/golang.org/x/tools/go/analysis) runner there. It runs as much as it can in parallel. It lazy-loads as much as it can +to reduce memory usage. Also, it set all heavyweight data to `nil` as becomes unneeded to save memory. + +We don't use existing [multichecker](https://godoc.org/golang.org/x/tools/go/analysis/multichecker) because +it doesn't use caching and doesn't have some important performance optimizations. + +All found by linters issues are represented with `result.Issue` struct: + +```go title=pkg/result/issue.go +type Issue struct { + FromLinter string + Text string + + // Source lines of a code with the issue to show + SourceLines []string + + // If we know how to fix the issue we can provide replacement lines + Replacement *Replacement + + // Pkg is needed for proper caching of linting results + Pkg *packages.Package `json:"-"` + + LineRange *Range `json:",omitempty"` + + Pos token.Position + + // HunkPos is used only when golangci-lint is run over a diff + HunkPos int `json:",omitempty"` + + // If we are expecting a nolint (because this is from nolintlint), record the expected linter + ExpectNoLint bool + ExpectedNoLintLinter string +} +``` + +## Postprocess Issues + +We have an abstraction of `result.Processor` to postprocess found issues: + +```bash +$ tree -L 1 ./pkg/result/processors/ +./pkg/result/processors/ +├── autogenerated_exclude.go +├── autogenerated_exclude_test.go +├── cgo.go +├── diff.go +├── exclude.go +├── exclude_rules.go +├── exclude_rules_test.go +├── exclude_test.go +├── filename_unadjuster.go +├── fixer.go +├── identifier_marker.go +├── identifier_marker_test.go +├── max_from_linter.go +├── max_from_linter_test.go +├── max_per_file_from_linter.go +├── max_per_file_from_linter_test.go +├── max_same_issues.go +├── max_same_issues_test.go +├── nolint.go +├── nolint_test.go +├── path_prettifier.go +├── path_shortener.go +├── processor.go +├── skip_dirs.go +├── skip_files.go +├── skip_files_test.go +├── source_code.go +├── testdata +├── uniq_by_line.go +├── uniq_by_line_test.go +└── utils.go +``` + +The abstraction is simple: + +```go title=pkg/result/processors/processor.go +type Processor interface { + Process(issues []result.Issue) ([]result.Issue, error) + Name() string + Finish() +} +``` + +A processor can hide issues (`nolint`, `exclude`) or change issues (`path_shortener`). + +## Print Issues + +We have an abstraction for printint found issues. + +```bash +$ tree -L 1 ./pkg/printers/ +./pkg/printers/ +├── checkstyle.go +├── codeclimate.go +├── github.go +├── github_test.go +├── json.go +├── junitxml.go +├── printer.go +├── tab.go +└── text.go +``` + +Needed printer is selected by command line option `--out-format`. diff --git a/docs/src/docs/usage/debug.mdx b/docs/src/docs/contributing/debug.mdx similarity index 100% rename from docs/src/docs/usage/debug.mdx rename to docs/src/docs/contributing/debug.mdx diff --git a/docs/src/docs/contributing/faq.mdx b/docs/src/docs/contributing/faq.mdx new file mode 100644 index 00000000..05ca5e45 --- /dev/null +++ b/docs/src/docs/contributing/faq.mdx @@ -0,0 +1,29 @@ +--- +title: Contributing FAQ +--- + +## How to write a custom linter + +See [there](/contributing/new-linters#how-to-write-a-custom-linter). + +## How to add a new open-source linter to `golangci-lint` + +See [there](/contributing/new-linters#how-to-add-a-public-linter-to-golangci-lint). + +## How to add a new private linter to `golangci-lint` + +See [there](/contributing/new-linters#how-to-add-a-private-linter-to-golangci-lint). + +## How to update existing linter + +Just update it's version in `go.mod`. + +## How to add configuration option to existing linter + +Add a new field to a [config struct](https://github.com/golangci/golangci-lint/blob/master/pkg/config/config.go). +Document it in [.golangci.example.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml). +Pass it to a linter. + +## How to see `INFO` or `DEBUG` logs + +See [tutorial about debugging](/contributing/debug/). diff --git a/docs/src/docs/contributing/new-linters.mdx b/docs/src/docs/contributing/new-linters.mdx new file mode 100644 index 00000000..2e61bfb6 --- /dev/null +++ b/docs/src/docs/contributing/new-linters.mdx @@ -0,0 +1,82 @@ +--- +title: New linters +--- + +## How to write a custom linter + +Use `go/analysis` and take a look at [this tutorial](https://disaev.me/p/writing-useful-go-analysis-linter/): it shows how to write `go/analysis` linter +from scratch and integrate it into `golangci-lint`. + +## How to add a public linter to `golangci-lint` + +You need to implement a new linter using `go/analysis` API. We don't accept not `go/analysis` linters. + +After that: + +1. Implement functional tests for the linter: add one file into directory [`test/testdata`](https://github.com/golangci/golangci-lint/tree/master/test/testdata). + Run `T=yourlintername.go make test_linters` to ensure that test fails. +2. Add a new file `pkg/golinters/{yourlintername}.go`. Look at other linters in this directory. Implement linter integration and check that test passes. +3. Add the new struct for the linter (which you've implemented in `pkg/golinters/{yourlintername}.go`) to the + list of all supported linters in [`pkg/lint/lintersdb/lintersdb.go`](https://github.com/golangci/golangci-lint/blob/master/pkg/lint/lintersdb/lintersdb.go) + to the function `GetAllSupportedLinterConfigs`. Enable it by default only if you are sure. +4. Find out what options do you need to configure for the linter. For example, `govet` has + only 1 option: [`check-shadowing`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml#L20). + Choose default values to not being annoying for users of golangci-lint. Add configuration options to: + +- [.golangci.example.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml) - the example of a configuration file. You can also add + them to [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) if you think + that this project needs not default values. +- [config struct](https://github.com/golangci/golangci-lint/blob/master/pkg/config/config.go#L61) - don't forget + about `mapstructure` tag for proper configuration files parsing by [pflag](https://github.com/spf13/pflag). + +5. Take a look at the example of [Pull Request with new linter support](https://github.com/golangci/golangci-lint/pull/850). + +## How to add a private linter to `golangci-lint` + +Some people and organizations may choose to have custom made linters run as a part of `golangci-lint`. +Typically, these linters can't be open-sourced or too specific. +Such linters can be added through Go's plugin library. + +### Configure a Plugin + +If you already have a linter plugin available, you can follow these steps to define it's usage in a projects +`.golangci.yml` file. An example linter can be found at [here](https://github.com/golangci/example-plugin-linter). If you're looking for +instructions on how to configure your own custom linter, they can be found further down. + +1. If the project you want to lint does not have one already, copy the [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) to the root directory. +2. Adjust the yaml to appropriate `linters-settings:custom` entries as so: + +```yaml +linters-settings: + custom: + example: + path: /example.so + description: The description of the linter + original-url: github.com/golangci/example-linter +``` + +That is all the configuration that is required to run a custom linter in your project. Custom linters are enabled by default, +but abide by the same rules as other linters. If the disable all option is specified either on command line or in +`.golangci.yml` files `linters:disable-all: true`, custom linters will be disabled; they can be re-enabled by adding them +to the `linters:enable` list, or providing the enabled option on the command line, `golangci-lint run -Eexample`. + +### Create a Plugin + +Your linter must implement one or more `golang.org/x/tools/go/analysis.Analyzer` structs. +Your project should also use `go.mod`. All versions of libraries that overlap `golangci-lint` (including replaced +libraries) MUST be set to the same version as `golangci-lint`. You can see the versions by running `go version -m golangci-lint`. + +You'll also need to create a go file like `plugin/example.go`. This MUST be in the package `main`, and define a +variable of name `AnalyzerPlugin`. The `AnalyzerPlugin` instance MUST implement the following interface: + +```go +type AnalyzerPlugin interface { + GetAnalyzers() []*analysis.Analyzer +} +``` + +The type of `AnalyzerPlugin` is not important, but is by convention `type analyzerPlugin struct {}`. See +[plugin/example.go](https://github.com/golangci/example-plugin-linter/plugin/example.go) for more info. + +To build the plugin, from the root project directory, run `go build -buildmode=plugin plugin/example.go`. This will create a plugin `*.so` +file that can be copied into your project or another well known location for usage in golangci-lint. diff --git a/docs/src/docs/contributing/website.mdx b/docs/src/docs/contributing/website.mdx new file mode 100644 index 00000000..3b53de8f --- /dev/null +++ b/docs/src/docs/contributing/website.mdx @@ -0,0 +1,76 @@ +--- +title: Website architecture +--- + +## Technology + +We use [Gatsby](https://www.gatsbyjs.org/) for static site generation because sites built with it +are very fast. + +This framework uses React and JavaScript/TypeScript. + +## Source Code + +The website lives in `docs/` directory of [golangci-lint repository](https://github.com/golangci/golangci-lint). + +## Theme + +Initially the site is based on [@rocketseat](https://rocketdocs.netlify.app/) theme. +Later we've merged it's code into `src/@rocketseat` because we needed too much changes +and [gatsby shadowing](https://www.gatsbyjs.org/docs/themes/shadowing/) doesn't +allow shadowing `gatsby-node.js` or `gatsby-config.js`. + +## Navigation + +Left menu is configured in `src/config/sidebar.yml`. + +## Articles + +Articles are located in `src/docs/` in `*.mdx` files. [MDX](https://mdxjs.com/getting-started/gatsby) is markdown +allowing to use `React` components. + +## Templating + +We use templates like `{.SomeField}` inside our `mdx` files. There templates are expanded +by running `make expand_website_templates` in the root of the repository. +It runs script `scripts/expand_website_templates/main.go` that rewrites `mdx` files with replaced templates. + +## CDN and DNS + +We use [CloudFlare](https://www.cloudflare.com/) for CDN, proxying and DNS management. + +## Hosting + +We use [Netlify](https://www.netlify.com/) as static website hosting and CD. +It's integrated into our pull requests: if `docs/` directory has changes Netlify +will trigger website rebuild and deploy it's preview for a branch. You can view +it to ensure that everything ok. + +Netlify deploys the website to production after merging anything to a `master` branch. + +## Local Testing + +Run: + +```bash +npm install +npm run start +``` + +And navigate to `http://localhost:8000` after successfull Gatsby build. +There is no need to restart Gatsby server almost for all changes: it supports hot reload. +Also, there is no need to refresh a webpage: hot reload updates changed content on the open page. + +## Trigger Website Rebuild + +Currently, Netlify triggers rebuild only if anything has changes in `docs/` directory. +But we can add a new linter and need to change a documentation to list the linter. + +To do it run + +```bash +go run ./scripts/expand_website_templates/main.go -only-state +``` + +It saves a hash of template replacements (that include all linters, configs, etc) +into `docs/template_data.state`. diff --git a/docs/src/docs/contributing/workflow.mdx b/docs/src/docs/contributing/workflow.mdx new file mode 100644 index 00000000..8e60e8a0 --- /dev/null +++ b/docs/src/docs/contributing/workflow.mdx @@ -0,0 +1,58 @@ +--- +title: Contributing Workflow +--- + +# Contributing + +By participating to this project, you agree to abide our [code of +conduct](https://github.com/golangci/golangci-lint/blob/master/CODE_OF_CONDUCT.md). + +## Setup your machine + +`golangci-lint` is written in [Go](https://golang.org/). + +Prerequisites: + +- `make` +- [Go 1.13+](https://golang.org/doc/install) + +Fork and clone [golangci-lint](https://github.com/golangci/golangci-lint) repository. + +A good way of making sure everything is all right is running the following: + +```bash +make build +./golangci-lint run -v +``` + +## Test your change + +When you are satisfied with the changes, we suggest you run: + +```bash +$ make test +``` + +Which runs all the linters and tests. + +## Submit a pull request + +Push your branch to your `golangci-lint` fork and open a pull request against the +`master` branch. + +## Pull request checks + +First, please, accept [CLA](https://gist.github.com/jirfag/26a39fd375da84b2d5ad4296fecb0668) - [cla assistant](https://cla-assistant.io/) will +make a comment on the pull request about it. + +Also, we run a few checks in CI by using GitHub actions, you can see them [here](https://github.com/golangci/golangci-lint/blob/master/.github/workflows/pr.yml). + +## Credits + +### Contributors + +Thank you to all the people who have already contributed to `golangci-lint`! + +[![golangci-lint contributors](https://contributors-img.web.app/image?repo=golangci/golangci-lint)](https://github.com/golangci/golangci-lint/graphs/contributors) + + diff --git a/docs/src/docs/index.mdx b/docs/src/docs/index.mdx index 39563949..0b9a35d8 100644 --- a/docs/src/docs/index.mdx +++ b/docs/src/docs/index.mdx @@ -44,7 +44,7 @@ Short 1.5 min video demo of analyzing [beego](https://github.com/astaxie/beego). ## Contributors -This project exists thanks to all the people who contribute. +This project exists thanks to all the people who contribute. [How to contribute](/contributing/workflow/). [![golangci-lint contributors](https://contributors-img.web.app/image?repo=golangci/golangci-lint)](https://github.com/golangci/golangci-lint/graphs/contributors) diff --git a/docs/src/docs/product/trusted-by.mdx b/docs/src/docs/product/trusted-by.mdx index 3a8e53f0..c3b3268e 100644 --- a/docs/src/docs/product/trusted-by.mdx +++ b/docs/src/docs/product/trusted-by.mdx @@ -25,3 +25,4 @@ The following companies/products use `golangci-lint`: - [Yahoo](https://github.com/yahoo/yfuzz) And thousands of other great companies use `golangci-lint` too. +You can find them by [this GitHub search query](https://github.com/search?q=golangci-lint&type=Code). diff --git a/docs/src/docs/usage/faq.mdx b/docs/src/docs/usage/faq.mdx index 46f8e21e..258343fb 100644 --- a/docs/src/docs/usage/faq.mdx +++ b/docs/src/docs/usage/faq.mdx @@ -7,20 +7,16 @@ title: FAQ You can integrate it yourself, see this [manual](/usage/linters#how-to-add-a-linter-to-golangci-lint-). Or you can create a [GitHub Issue](https://github.com/golangci/golangci-lint/issues/new) and we will integrate when time permits. -## It's cool to use `golangci-lint` when starting a project, but what about existing projects with large codebase? It will take days to fix all found issues +## How to integrate `golangci-lint` into large project with thousands of issues We are sure that every project can easily integrate `golangci-lint`, even the large one. The idea is to not fix all existing issues. Fix only newly added issue: issues in new code. To do this setup CI (or better use [GolangCI](https://golangci.com)) to run `golangci-lint` with option `--new-from-rev=HEAD~1`. Also, take a look at option `--new`, but consider that CI scripts that generate unstaged files will make `--new` only point out issues in those files and not in the last commit. In that regard `--new-from-rev=HEAD~1` is safer. By doing this you won't create new issues in your code and can choose fix existing issues (or not). -## How to use `golangci-lint` in CI (Continuous Integration)? +## How to use `golangci-lint` in CI Run `golangci-lint` in CI and check the exit code. If it's non-zero - fail the build. -We don't recommend vendoring `golangci-lint` in your repo: you will get troubles updating `golangci-lint`. Please, use recommended way to install with the shell script: it's very fast. - -## Do I need to run `go install`? - -No, you don't need to do it anymore. +See [how to properly install `golangci-lint` in CI](/usage/install#ci-installation) ## Which go versions are supported @@ -40,7 +36,7 @@ Long answer: 2. Run it with `-v` option and check the output. 3. If it doesn't help create a [GitHub issue](https://github.com/golangci/golangci-lint/issues/new) with the output from the error and #2 above. -## Why running with `--fast` is slow on the first run? +## Why running with `--fast` is slow on the first run Because the first run caches type information. All subsequent runs will be fast. Usually this options is used during development on local machine and compilation was already performed. diff --git a/docs/src/docs/usage/linters.mdx b/docs/src/docs/usage/linters.mdx index 0ae17ebe..5fc545da 100644 --- a/docs/src/docs/usage/linters.mdx +++ b/docs/src/docs/usage/linters.mdx @@ -15,67 +15,3 @@ golangci-lint help linters ## Disabled By Default Linters (`-E/--enable`) {.DisabledByDefaultLinters} - -## How to add a linter to `golangci-lint` - -You need to implement a new linter using `go/analysis` API. After that: - -1. Implement functional tests for the linter: add one file into directory [`test/testdata`](https://github.com/golangci/golangci-lint/tree/master/test/testdata). Run `T=yourlintername.go make test_linters` to ensure that test fails. -2. Add a new file `pkg/golinters/{yourlintername}.go`. Look at other linters in this directory. Implement linter integration and check that test passes. -3. Add the new struct for the linter (which you've implemented in `pkg/golinters/{yourlintername}.go`) to the list of all supported linters in [`pkg/lint/lintersdb/lintersdb.go`](https://github.com/golangci/golangci-lint/blob/master/pkg/lint/lintersdb/lintersdb.go) to the function `GetAllSupportedLinterConfigs`. Enable it by default only if you are sure. -4. Find out what options do you need to configure for the linter. For example, `govet` has only 1 option: [`check-shadowing`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml#L20). Choose default values to not being annoying for users of golangci-lint. Add configuration options to: - -- [.golangci.example.yml](.golangci.example.yml) - the example of a configuration file. You can also add them to [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) if you think that this project needs not default values. -- [config struct](https://github.com/golangci/golangci-lint/blob/master/pkg/config/config.go#L61) - don't forget about `mapstructure` tag for proper configuration files parsing by [pflag](https://github.com/spf13/pflag). - -5. Take a look at the example of [Pull Request with new linter support](https://github.com/golangci/golangci-lint/pull/135). - -## How to add a private linter - -Some people and organizations may choose to have custom made linters run as a part of `golangci-lint`. -Typically, these linters can't be open-sourced or too specific. -Such linters can be added through Go's plugin library. - -### Configure a Plugin - -If you already have a linter plugin available, you can follow these steps to define it's usage in a projects -`.golangci.yml` file. An example linter can be found at [here](https://github.com/golangci/example-plugin-linter). If you're looking for -instructions on how to configure your own custom linter, they can be found further down. - -1. If the project you want to lint does not have one already, copy the [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) to the root directory. -2. Adjust the yaml to appropriate `linters-settings:custom` entries as so: - -```yaml -linters-settings: - custom: - example: - path: /example.so - description: The description of the linter - original-url: github.com/golangci/example-linter -``` - -That is all the configuration that is required to run a custom linter in your project. Custom linters are enabled by default, -but abide by the same rules as other linters. If the disable all option is specified either on command line or in -`.golangci.yml` files `linters:disable-all: true`, custom linters will be disabled; they can be re-enabled by adding them -to the `linters:enable` list, or providing the enabled option on the command line, `golangci-lint run -Eexample`. - -### Create a Plugin - -Your linter must implement one or more `golang.org/x/tools/go/analysis.Analyzer` structs. -Your project should also use `go.mod`. All versions of libraries that overlap `golangci-lint` (including replaced -libraries) MUST be set to the same version as `golangci-lint`. You can see the versions by running `go version -m golangci-lint`. - -You'll also need to create a go file like `plugin/example.go`. This MUST be in the package `main`, and define a -variable of name `AnalyzerPlugin`. The `AnalyzerPlugin` instance MUST implement the following interface: - -```go -type AnalyzerPlugin interface { - GetAnalyzers() []*analysis.Analyzer -} -``` - -The type of `AnalyzerPlugin` is not important, but is by convention `type analyzerPlugin struct {}`. See -[plugin/example.go](https://github.com/golangci/example-plugin-linter/plugin/example.go) for more info. - -To build the plugin, from the root project directory, run `go build -buildmode=plugin plugin/example.go`. This will create a plugin `*.so` -file that can be copied into your project or another well known location for usage in golangci-lint.