{"id":1439,"date":"2020-11-05T19:37:08","date_gmt":"2020-11-05T19:37:08","guid":{"rendered":"http:\/\/sophyonline.com\/blog\/?p=1439"},"modified":"2020-11-12T11:42:03","modified_gmt":"2020-11-12T11:42:03","slug":"creating-a-post-commit-hook-with-swiftlint-autocorrect","status":"publish","type":"post","link":"http:\/\/sophyonline.com\/blog\/2020\/11\/creating-a-post-commit-hook-with-swiftlint-autocorrect\/","title":{"rendered":"Creating a Post-commit hook with Swiftlint Autocorrect."},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Have you ever wondered if you could launch a git hook that triggers a certain script that could help you do some task?. Me too!. Well, not really, until I needed it \ud83d\ude00<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In my case, I work with Xcode (iOS dev here, indeed) and it&#8217;s well known between us, iOS developers, that Xcode doesn&#8217;t provide a IDE with an autocorrect functionality, like others have. We do use a tool called &#8220;<strong>SwiftLint<\/strong>&#8221; wich triggers a lint in our project to enforce Swift style and conventions. And it also provides a &#8220;Autocorrect&#8221; command. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Problem is, that I wanted to autocorrect automatically, without me needing to run <code><strong>swiftlint autocorrect<\/strong><\/code> everytime in terminal, since I tend to end up forgetting to do this kind of task manually.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you&#8217;re working on a big project with multiple devs at the same time, you need to improve somehow the way at least how autocorrect is triggered.  I started learning about git hooks, and they seem very handy to do this kind of work. Ok, so, I started to think about steps on what I wanted and how could I achieve it:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Run swiftlint autocorrect only in staged files, so I wouldn&#8217;t add more warnings to the project. <\/li><li>Since we use danger to pint point this missing lints in our PR&#8217;s, I wanted to skip this behaviour because it added a lot of noise and as human do, we&#8217;ll get used to the warnings and end up not fixing it :shruggs:<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Both of the steps above ended up in this final idea:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>When editing or creating files, run swiflint autocorrect after a commit is made over these files.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, I ended creating the next files:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1.- The bootstrap file which will copy the hook file inside .<strong>git\/hooks\/pre-commit path<\/strong>. I&#8217;ve called this file &#8220;<strong>bootstrap_hook<\/strong>.sh&#8221;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">\n#!\/usr\/bin\/env bash\n# Usage: scripts\/autocorrect\n\nset -eu\necho \"Configuring pre-commit hook...\"\nfile=\"..\/.git\/hooks\/pre-commit\"\npath=\".git\/hooks\"\necho $(pwd)\nrm -f $file\ncp -f pre-commit $file\necho \"Done coping pre-hook in $file\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2. And the code that will evaluate the files that are only in staging mode, so after you do a commit, these files will be autocorrected. If there&#8217;s anything to correct, then a new commit will be shown with these changes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">#!\/bin\/bash\necho \"post-commit started\"\n# Run SwiftLint\nSTART_DATE=$(date +\"%s\")\n\nSWIFT_LINT=\/usr\/local\/bin\/swiftlint\n\n# Run SwiftLint for given filename\nrun_swiftlint() {\n    local filename=\"${1}\"\n    echo \"File is: ${filename}\"\n    echo \"File with previous extension is: ${filename#*.}\"\n        if [[ \"${filename##*.}\" == \"swift\" ]]; then\n            if [[ \"${filename#*.}\" != \"generated.swift\" ]]; then\n            echo \"Autocorrecting...\"\n            ${SWIFT_LINT} autocorrect --path \"${filename}\"\n            ${SWIFT_LINT} lint --path \"${filename}\"\n            fi\n        fi\n}\n\nif [[ -e \"${SWIFT_LINT}\" ]]; then\n    echo \"SwiftLint version: $(${SWIFT_LINT} version)\"\n    # Run only if not merging\n    if ! git rev-parse -q --verify MERGE_HEAD; then \n        # Run for both staged and unstaged files\n        echo \"Enter merging\"\n        git diff --name-only | while read filename; do run_swiftlint \"${filename}\"; done\n        git diff --cached --name-only | while read filename; do run_swiftlint \"${filename}\"; done\n    fi\nelse\n    echo \"${SWIFT_LINT} is not installed. Please install it first from https:\/\/www.github.com\/realm\/SwiftLint\"\n    exit 0\nfi\n\nEND_DATE=$(date +\"%s\")\n\nDIFF=$(($END_DATE - $START_DATE))\necho \"SwiftLint took $(($DIFF \/ 60)) minutes and $(($DIFF % 60)) seconds to complete.\"\n\necho \"post-commit finished\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, to use it, the only thing you have to do is to run the bootstrap file and let git do his magic:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To run it: <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>$ sh bootstrap_hook.sh<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I have copied these files in my github account if you want to clone it, fork it or pull request it \ud83d\ude00 <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/phynet\/Pre-Hook-Swiftlint-Autocorrect\" data-type=\"URL\" data-id=\"https:\/\/github.com\/phynet\/Pre-Hook-Swiftlint-Autocorrect\" target=\"_blank\">https:\/\/github.com\/phynet\/Pre-Hook-Swiftlint-Autocorrect<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever wondered if you could launch a git hook that triggers a certain script that could help you do some task?. Me too!. Well, not really, until I needed it \ud83d\ude00 In my case, I work with Xcode (iOS dev here, indeed) and it&#8217;s well known between us, iOS developers, that Xcode doesn&#8217;t <a class=\"read-more\" href=\"http:\/\/sophyonline.com\/blog\/2020\/11\/creating-a-post-commit-hook-with-swiftlint-autocorrect\/\">&hellip;&nbsp;<span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","footnotes":""},"categories":[4,3,36],"tags":[35,37,34,38,39],"class_list":["post-1439","post","type-post","status-publish","format-standard","hentry","category-desarrollo-de-software","category-development","category-git","tag-git-hooks","tag-hooks","tag-swift-lint","tag-swiftlint","tag-swiftlint-autocorrect"],"_links":{"self":[{"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/posts\/1439","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/comments?post=1439"}],"version-history":[{"count":12,"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/posts\/1439\/revisions"}],"predecessor-version":[{"id":1467,"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/posts\/1439\/revisions\/1467"}],"wp:attachment":[{"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/media?parent=1439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/categories?post=1439"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/sophyonline.com\/blog\/wp-json\/wp\/v2\/tags?post=1439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}