text:
# UI Frameworks

[![Build Status](https://api.travis-ci.org/cdleon/ui-frameworks.svg?branch=master)](https://travis-ci.org/cdleon/ui-frameworks)

## CSS

- [960 Grid System](https://github.com/nathansmith/960-Grid-System) - The 960 Grid System is an effort to streamline web development workflow. [http://960.gs](http://960.gs)
- [Amaze UI](https://github.com/amazeui/amazeui) - Amaze UI, a mobile-first and modular front-end framework. [http://amazeui.org/](http://amazeui.org/)
- [Blueprint](https://github.com/joshuaclayton/blueprint-css) - A CSS framework that aims to cut down on your CSS development time [http://www.blueprintcss.org](http://www.blueprintcss.org)
- [Bootmetro](https://github.com/aozora/bootmetro) - Simple and flexible web framework to create elegant and modern web applications
with the same look & feel of Windows 8 [http://www.marcellop.com/bootmetro/](http://www.marcellop.com/bootmetro/)
- [Bootsrap](https://github.com/twbs/bootstrap) - The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web. [http://getbootstrap.com](http://getbootstrap.com)
- [Material Design for Bootstrap](https://github.com/FezVrasta/bootstrap-material-design) - Material design theme for Bootstrap 3 and 4. [https://fezvrasta.github.io/bootstrap-material-design/](https://fezvrasta.github.io/bootstrap-material-design/)
- [Bulma](https://github.com/jgthms/bulma) - Modern CSS framework based on Flexbox. [http://bulma.io](http://bulma.io)
- [Cascade](https://github.com/jslegers/cascadeframework/) Cascade Framework. [http://cascade-framework.com/](http://cascade-framework.com/)
- [ConciseCSS](https://github.com/ConciseCSS/concise.css) A CSS framework that's lightweight and easy-to-use. Give up the bloat. Stop tripping over your classes. Be Concise. [http://concisecss.com/](http://concisecss.com/)
- [Cutestrap](https://github.com/tylerchilds/cutestrap) - A strong, independent CSS Framework. Only 2.7KB minified & gzipped. [https://www.cutestrap.com](https://www.cutestrap.com)
- [Foundation](https://github.com/zurb/foundation-sites) - The most advanced responsive front-end framework in the world. Quickly create prototypes and production code for sites that work on any kind of device. [http://foundation.zurb.com](http://foundation.zurb.com)
- [Grd](https://github.com/1000ch/grd) - A CSS grid framework using Flexbox. Only 321 bytes (Gzipped). [https://1000ch.github.io/grd/](https://1000ch.github.io/grd/)
- [Gumby](https://github.com/GumbyFramework/Gumby) - A Flexible, Responsive CSS Framework - Powered by Sass. [http://www.gumbyframework.com/](http://www.gumbyframework.com/)
- [Kube](https://github.com/imperavi/kube) - Kube is a minimalistic Web framework for professional developers and designers. [https://imperavi.com/kube/](https://imperavi.com/kube/)
- [Less Framework](https://github.com/jonikorpi/Less-Framework) - An adaptive CSS grid system. [http://www.jonikorpi.com/less-framework/](http://www.jonikorpi.com/less-framework/)
- [Material Design Lite](https://github.com/google/material-design-lite) - Material Design Lite (MDL) lets you add a Material Design look and feel to your static content websites. It doesn't rely on any JavaScript frameworks or libraries. [https://getmdl.io/](https://getmdl.io/)
- [Materialize](https://github.com/Dogfalo/materialize) - CSS Framework based on Material Design. [http://materializecss.com](http://materializecss.com)
- [Metro UI](https://github.com/olton/Metro-UI-CSS) - CSS styles for build Windows 8 Metro UI stylable interface.[http://metroui.org.ua/](http://metroui.org.ua/)
- [Miligram](https://github.com/milligram/milligram) A minimalist CSS framework. [https://milligram.github.io/](https://milligram.github.io/)
- [MUI](https://github.com/muicss/mui) - MUI is a lightweight CSS framework that follows Google's Material Design guidelines. [https://www.muicss.com](https://www.muicss.com)
- [NES](https://github.com/nostalgic-css/NES.css) - NES-style CSS Framework. [https://nostalgic-css.github.io/NES.css/](https://nostalgic-css.github.io/NES.css/)
- [Office UI Fabric](https://github.com/OfficeDev/office-ui-fabric-core) - The front-end framework for building experiences for Office 365. [https://developer.microsoft.com/en-us/fluentui](https://developer.microsoft.com/en-us/fluentui)
- [Pills](https://github.com/rohitkrai03/pills) - A simple responsive CSS Grid for humans. [http://arkpod.in/pills/](http://arkpod.in/pills/)
- [Primer](https://github.com/primer/primer) - The base coat of GitHub. Our internal CSS toolkit and guidelines. [https://github.com/primer/primer](https://github.com/primer/primer)
- [Pure](https://github.com/yahoo/pure/) - A set of small, responsive CSS modules that you can use in every web project. [http://purecss.io/](http://purecss.io/)
- [Pure CSS Components](https://github.com/LFeh/css-components) - A set of common UI Components using the power of CSS and without Javascript. [https://www.felipefialho.com/css-components/](https://www.felipefialho.com/css-components/)
- [Responsive](https://github.com/ResponsiveBP/Responsive) - A powerful, accessible, developer friendly framework for building responsive websites. [http://responsivebp.com](http://responsivebp.com)
- [Sakura](https://github.com/oxalorg/sakura) - A minimal css framework/theme. [https://oxal.org/projects/sakura](https://oxal.org/projects/sakura)
- [Semantic UI](https://github.com/Semantic-Org/Semantic-UI) - Semantic is a UI component framework based around useful principles from natural language. [http://semantic-ui.com/](http://semantic-ui.com/)
- [Skeleton](https://github.com/dhg/Skeleton) - A Dead Simple, Responsive Boilerplate for Mobile-Friendly Development. [http://getskeleton.com/](http://getskeleton.com/)
- [Spectre](https://github.com/picturepan2/spectre) - A lightweight, responsive and modern CSS framework. [https://picturepan2.github.io/spectre/](https://picturepan2.github.io/spectre/)
- [Topcoat](https://github.com/topcoat/topcoat) - CSS for clean and fast web apps. [http://topcoat.io](http://topcoat.io)
- [Tufte-css](https://github.com/edwardtufte/tufte-css) - Style your webpage like Edward Tufte's handouts. [https://edwardtufte.github.io/tufte-css/](https://edwardtufte.github.io/tufte-css/)
- [Tailwind.css](https://github.com/tailwindcss/tailwindcss) - A utility-first CSS framework for rapid UI development. [https://tailwindcss.com/](https://tailwindcss.com/)
- [Typebase.css](https://github.com/devinhunt/typebase.css) - A starting point for good typography on the web. [http://devinhunt.github.io/typebase.css/](http://devinhunt.github.io/typebase.css/)
- [UIKit](https://github.com/uikit/uikit) - A lightweight and modular front-end framework for developing fast and powerful web interfaces. [http://getuikit.com](http://getuikit.com)
- [Unnamed](https://github.com/smakosh/unnamed-css-framework) - A simple colorful css framework [https://unnamed.smakosh.com](https://unnamed.smakosh.com)
- [U.S. Web Design System](https://github.com/uswds/uswds) The U.S. Web Design System is a design system for building fast, accessible, mobile-friendly federal government websites. [https://designsystem.digital.gov](https://designsystem.digital.gov)
- [Water.css](https://github.com/kognise/water.css) - A just-add-css collection of styles to make simple websites just a little nicer. [https://watercss.netlify.com/](https://watercss.netlify.com/)
- [Yaml](https://github.com/yamlcss/yaml) - YAML (Yet Another Multicolumn Layout) is a modular CSS framework for truly flexible, accessible and responsive websites. It is based on Sass and has a very slim framework core that weights only ~6kB. [http://www.yaml.de](http://www.yaml.de)
- [Yahoo User Interface Library](https://github.com/yui/yui3) - YUI is a free, open source JavaScript and CSS framework for building richly interactive web applications. [http://yuilibrary.com/](http://yuilibrary.com/)

## HTML

* [Mavo](https://github.com/mavoweb/mavo) - Create web applications entirely by writing HTML and CSS! [https://mavo.io](https://mavo.io)

## JS

* [Amp HTML](https://github.com/ampproject/amphtml) - AMP HTML is a way to build web pages for static content that render with reliable, fast performance. It is our attempt at fixing what many perceive as painfully slow page load times – especially when reading content on the mobile web. [https://www.ampproject.org/](https://www.ampproject.org/)
* [Angular](https://github.com/angular/angular.js) - HTML enhanced for web apps. [https://angularjs.org/](https://angularjs.org/)
* [App.js](https://github.com/kikinteractive/app) - App.js is a lightweight JavaScript UI library for creating mobile webapps that behave like native apps, sacrificing neither performance nor polish. [http://code.kik.com/app/3/index.html](http://code.kik.com/app/3/index.html)
* [Aurelia](https://github.com/aurelia/framework) - The aurelia framework brings together all the required core aurelia libraries into a ready-to-go application-building platform. [http://aurelia.io/](http://aurelia.io/)
* [Backbone.js](https://github.com/jashkenas/backbone) - Backbone supplies structure to JavaScript-heavy applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface. [http://backbonejs.org/](http://backbonejs.org/)
* [Bacon.js](https://github.com/baconjs/bacon.js/) - FRP (functional reactive programming) library for Javascript. [https://baconjs.github.io/](https://baconjs.github.io/)
* [Brunch](https://github.com/brunch/brunch) - Fast front-end web app build tool with simple declarative config, seamless incremental compilation for rapid development, an opinionated pipeline and workflow, and core support for source maps. [http://brunch.io/](http://brunch.io/)
* [Cash](https://github.com/kenwheeler/cash) - An absurdly small jQuery alternative for modern browsers. [https://github.com/kenwheeler/cash](https://github.com/kenwheeler/cash)
* [Can.js](https://github.com/canjs/canjs) - CanJS is a MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy. [https://canjs.com/](https://canjs.com/)
* [Choo](https://github.com/yoshuawuyts/choo) - sturdy 4kb frontend framework. [https://choo.io/](https://choo.io/)
* [Composer.js](https://github.com/lyonbros/composer.js) - Composer is a library for building complex single-page applications. [http://lyonbros.github.io/composer.js/](http://lyonbros.github.io/composer.js/)
* [Dojo](https://github.com/dojo) - A JavaScript toolkit that saves you time and scales with your development process. Provides everything you need to build a Web app. Language utilities, UI components, and more, all in one place, designed to work together perfectly. [https://github.com/dojo](https://github.com/dojo)
* [Flapjax](https://github.com/brownplt/flapjax) - functional reactive programming for JavaScript [http://www.flapjax-lang.org/](http://www.flapjax-lang.org/)
* [Flight](https://github.com/flightjs/flight) - A component-based, event-driven JavaScript framework from Twitter. [http://flightjs.github.io/](http://flightjs.github.io/)
* [Fn.js](https://github.com/CrowdHailer/fn.js) - A JavaScript library built to encourage a functional programming style & strategy [http://eliperelman.com/fn.js/](http://eliperelman.com/fn.js/)
* [Handlebars.js](https://github.com/wycats/handlebars.js) - Handlebars.js is an extension to the Mustache templating language created by Chris Wanstrath. Handlebars.js and Mustache are both logicless templating languages that keep the view and the code separated like we all know they should be. [http://handlebarsjs.com/](http://handlebarsjs.com/)
* [Hilo](https://github.com/hiloteam/Hilo) - A Cross-end HTML5 Game development solution developed by Alibaba Group [https://hiloteam.github.io/](https://hiloteam.github.io/)
* [Hyperapp](https://github.com/hyperapp/hyperapp) - 1 KB JavaScript library for building frontend applications. [https://hyperapp.glitch.me)
* [Inferno](https://github.com/trueadm/inferno) - An extremely fast, React-like JavaScript library for building modern user interfaces. [http://infernojs.org/](http://infernojs.org/)
* [jQuery](https://github.com/jquery/jquery) - jQuery JavaScript Library. [https://jquery.com/](https://jquery.com/)
* [jQuery Mobile](https://github.com/jquery/jquery-mobile) - jQuery Mobile is a unified, HTML5-based user interface system for all popular mobile device platforms, built on the rock-solid jQuery and jQuery UI foundation. [https://jquerymobile.com/](https://jquerymobile.com/)
* [JsBlocks](https://github.com/astoilkov/jsblocks) - Better MV-ish Framework. [http://jsblocks.com/](http://jsblocks.com/)
* [Knockout.js](https://github.com/knockout/knockout) - Knockout makes it easier to create rich, responsive UIs with JavaScript. [http://knockoutjs.com/](http://knockoutjs.com/)
* [Lazy.js](https://github.com/dtao/lazy.js) - Lazy.js is a functional utility library for JavaScript, similar to Underscore and Lo-Dash, but with an underlying engine that supports many more use cases than those libraries, while offering comparable or superior performance in most scenarios. [http://danieltao.com/lazy.js/](http://danieltao.com/lazy.js/)
* [LayerJS](https://github.com/layerJS/layerJS) - Javascript UI composition framework. [https://layerjs.org/](https://layerjs.org/)
* [Lodash](https://github.com/lodash/lodash) - A JavaScript utility library delivering consistency, modularity, performance, & extras. [https://lodash.com/](https://lodash.com/)
* [Marko.js](https://github.com/marko-js/marko) - A friendly (and fast!) UI library from eBay that makes building web apps fu. [https://markojs.com/](https://markojs.com/)
* [Min.js](https://github.com/remy/min.js) - Super minimal selector and event library. [https://github.com/remy/min.js](https://github.com/remy/min.js)
* [Mithril.js](https://github.com/MithrilJS/mithril.js) - A JavaScript Framework for Building Brilliant Applications [https://mithril.js.org](https://mithril.js.org)
* [Moon](https://github.com/kbrsh/moon) - A minimal, blazing fast UI library. [http://moonjs.ga/](http://moonjs.ga/)
* [MooTools](http://mootools.net/) - MooTools is a collection of JavaScript utilities designed for the intermediate to advanced JavaScript developer. It allows you to write powerful and flexible code with its elegant, well documented, and coherent APIs. [http://mootools.net/](http://mootools.net/)
* [Mustache.js](https://github.com/janl/mustache.js/) - Minimal templating with {{mustaches}} in JavaScript. [http://mustache.github.io/](http://mustache.github.io/)
* [Nerv](https://github.com/NervJS/nerv) - A blazing fast React alternative, compatible with IE8 and React 16. [https://nerv.aotu.io/](https://nerv.aotu.io/)
* [Omi](https://github.com/Tencent/omi) - Next generation web framework in 4kb JavaScript (Web Components + JSX + Proxy + Store + Path Updating). [http://omijs.org](http://omijs.org)
* [Polymer](https://github.com/Polymer/polymer) - Polymer lets you build encapsulated, re-usable elements that work just like HTML elements, to use in building web applications. [https://www.polymer-project.org/1.0/](https://www.polymer-project.org/1.0/)
* [Preact](https://github.com/developit/preact) - Fast 3kb React alternative with the same ES6 API. Components & Virtual DOM. [https://preactjs.com](https://preactjs.com)
* [Prototype](https://github.com/sstephenson/prototype) - Prototype is a JavaScript framework that aims to ease development of dynamic web applications. It offers a familiar class-style OO framework, extensive Ajax support, higher-order programming constructs, and easy DOM manipulation. [http://prototypejs.org/](http://prototypejs.org/)
* [Radioactive](https://github.com/radioactive/radioactive) - Radioactive is a Native FRP ( Functional Reactive Programming ) environment for Javascript. [https://github.com/radioactive/radioactive](https://github.com/radioactive/radioactive)
* [React](https://github.com/facebook/react) - React is a JavaScript library for building user interfaces. [https://facebook.github.io/react/](https://facebook.github.io/react/)
* [Serverless](https://github.com/serverless/serverless) - The Server-less Application Framework. Uses bleeding-edge AWS services to redefine how to build massively scalable (and cheap) apps! [https://serverless.com/](https://serverless.com/)
* [Skel](https://github.com/ajlkn/skel) - A lightweight responsive framework for the www. [https://github.com/ajlkn/skel](https://github.com/ajlkn/skel)
* [Sprint](https://github.com/bendc/sprint) - A tiny, lightning fast jQuery-like library for modern browsers. [https://github.com/bendc/sprint](https://github.com/bendc/sprint)
* [Slate](https://github.com/ianstormtaylor/slate) - A completely customizable framework for building rich text editors. [http://slatejs.org](http://slatejs.org)
* [Riot.js](https://github.com/riot/riot) - A React-like, user interface library. [http://riotjs.com/](http://riotjs.com/)
* [t3js](https://github.com/box/t3js/) - T3 is a client-side JavaScript framework for building large-scale web applications. [http://t3js.org/](http://t3js.org/)
* [Trine](https://github.com/jussi-kalliokoski/trine) - Trine is a utility library geared at tapping the full potential of functional programming in JS, in the vein of lodash, underscore and Ramda. [https://github.com/jussi-kalliokoski/trine](https://github.com/jussi-kalliokoski/trine)
* [Two.js](https://github.com/jonobr1/two.js) - A two-dimensional drawing api meant for modern browsers. It is renderer agnostic enabling the same api to render in multiple contexts: webgl, canvas2d, and svg. [http://jonobr1.github.io/two.js/](http://jonobr1.github.io/two.js/)
* [Vue.js](https://github.com/vuejs/vue) - Simple yet powerful library for building modern web interfaces. [http://vuejs.org/](http://vuejs.org/)
* [Way.js](https://github.com/gwendall/way.js) - Simple, lightweight, persistent two-way databinding. [http://gwendall.github.io/way/](http://gwendall.github.io/way/)
* [Zepto.js](https://github.com/madrobby/zepto) - Zepto.js is a minimalist JavaScript library for modern browsers, with a jQuery-compatible API. [http://zeptojs.com/](http://zeptojs.com/)

## React

* [Chakra UI](https://github.com/chakra-ui/chakra-ui) - ⚡ Simple, Modular & Accessible UI Components for your React Applications. [https://chakra-ui.com/](https://chakra-ui.com/)
* [CSS Blocks](https://github.com/linkedin/css-blocks) - High performance, maintainable stylesheets. [http://css-blocks.com/](http://css-blocks.com/)
* [Draft.js](https://github.com/facebook/draft-js) - A React framework for building text editors. [https://facebook.github.io/draft-js/](https://facebook.github.io/draft-js/)
* [Elemental UI](https://github.com/elementalui/elemental) - A UI Toolkit for React.js Websites and Apps. [http://elemental-ui.com/](http://elemental-ui.com/)
* [Essential](http://pheuter.github.io/essential-react/) - A minimal skeleton for building testable React apps using ES6. [https://github.com/pheuter/essential-react](https://github.com/pheuter/essential-react)
* [Evergreen](https://github.com/segmentio/evergreen) - Evergreen React UI Framework by Segment [https://evergreen.surge.sh/](https://evergreen.surge.sh/)
* [Flux](https://github.com/facebook/flux) - An application architecture for React utilizing a unidirectional data flow. [http://facebook.github.io/flux/](http://facebook.github.io/flux/)
* [Grommet](https://github.com/grommet/grommet) - A react-based framework that provides accessibility, modularity, responsiveness, and theming in a tidy package [https://grommet.io](https://grommet.io)
* [Ink](https://github.com/vadimdemedes/ink) - React for interactive command-line apps.
* [Maple.js](https://github.com/Wildhoney/Maple.js) - Maple.js is a React webcomponents based framework mixing ES6 with Custom Elements, HTML Imports and Shadow DOM. It has in-built support for SASS and JSX, including a Gulp task for vulcanizing your project. [http://maple-app.herokuapp.com/](http://maple-app.herokuapp.com/)
- [Material UI](https://github.com/callemall/material-ui) - React Components that Implement Google's Material Design. [http://www.material-ui.com](http://www.material-ui.com)
* [Polaris](https://polaris.shopify.com/) - Our design system helps us work together to build a great experience for all of Shopify’s merchants.
* [React95](https://github.com/arturbien/React95) - Refreshed Windows 95 style UI components for your React app [https://react95.io/](https://react95.io/)
* [React Toolbox](https://github.com/react-toolbox/react-toolbox) - A set of React components implementing Google's Material Design specification with the power of CSS Modules.
* [React-MDL](https://github.com/react-mdl/react-mdl) - React Components for Material Design Lite. [https://tleunen.github.io/react-mdl](https://tleunen.github.io/react-mdl)
* [React Static](https://github.com/nozzle/react-static) - A progressive static-site framework for React. [https://medium.com/@tannerlinsley/%EF%B8%8F-introducing-react-static-a-progressive-static-site-framework-for-react-3470d2a51ebc](https://medium.com/@tannerlinsley/%EF%B8%8F-introducing-react-static-a-progressive-static-site-framework-for-react-3470d2a51ebc)
* [React Transform Boilerplate](https://github.com/gaearon/react-transform-boilerplate) - A new Webpack boilerplate with hot reloading React components, and error handling on module and component level.
* [ReactXP](https://github.com/Microsoft/reactxp) Library for cross-platform app development. [https://microsoft.github.io/reactxp](https://microsoft.github.io/reactxp/)
* [Reapp](https://github.com/reapp/reapp) - Reapp - next gen hybrid apps. [https://github.com/reapp/reapp](https://github.com/reapp/reapp)
* [Relay](https://github.com/facebook/relay) - Relay is a JavaScript framework for building data-driven React applications. [https://facebook.github.io/relay/](https://facebook.github.io/relay/)
* [Rebass](https://github.com/rebassjs/rebass) - React primitive UI components built with styled-system. [https://rebassjs.org](https://rebassjs.org)
* [Ring UI](https://github.com/JetBrains/ring-ui) - A collection of JetBrains Web UI components. [https://jetbrains.org/ring-ui](https://jetbrains.org/ring-ui)
* [Uiw](https://github.com/uiw-react/uiw) - A high quality UI Toolkit, A Component Library for React 16+. [https://uiwjs.github.io](https://uiwjs.github.io)
* [wired-elements](https://github.com/wiredjs/wired-elements) - Collection of elements that appear hand drawn. Great for wireframes. [https://wiredjs.com](https://wiredjs.com)
* [Yoshino](https://github.com/Yoshino-UI/Yoshino) - A themable React component library！Flexible Lightweight PC UI Components built on React! Anyone can generate easily all kinds of themes by it! [https://yoshino-ui.github.io](https://yoshino-ui.github.io)

## Vue

- [at-ui](https://github.com/at-ui/at-ui) - A fresh and flat UI-Kit specially for desktop application, made with ♥ by Vue.js 2.0. [https://at.aotu.io](https://at.aotu.io)
- [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) - Implementation of [bootstrap-4](https://getbootstrap.com/) grid and components for Vue.js 2. [https://bootstrap-vue.js.org/](https://bootstrap-vue.js.org/)
- [buefy](https://github.com/buefy/buefy) - Components based on Bulma framework. [https://buefy.org/](https://buefy.org/)
- [cube-ui](https://github.com/didi/cube-ui) - A fantastic mobile ui lib implement by Vue. [https://didi.github.io/cube-ui/](https://didi.github.io/cube-ui/)
- [Element](https://github.com/ElemeFE/element) - A Vue.js 2.0 UI Toolkit for Web [https://element.eleme.io/](https://element.eleme.io/)
- [element-ui](https://github.com/ElemeFE/element) - A Vue.js 2.0 UI Toolkit for Web. [http://element.eleme.io/](http://element.eleme.io/)
- [fish-ui](https://github.com/myliang/fish-ui) - A Vue.js 2.0 UI Toolkit for Web. [https://myliang.github.io/fish-ui](https://myliang.github.io/fish-ui)
- [Framework7](https://github.com/framework7io/framework7/) - Full featured HTML framework for building iOS & Android apps [http://framework7.io](http://framework7.io)
- [iview-ui](https://github.com/iview/iview) - A Vue.js 2.0 UI Framework for web. [https://www.iviewui.com](https://www.iviewui.com)
- [Keen-UI](https://github.com/JosephusPaye/Keen-UI) - A lightweight Vue.js UI library with a simple API, inspired by Google's Material Design. [https://josephuspaye.github.io/Keen-UI/](https://josephuspaye.github.io/Keen-UI/)
- [material-components-vue](https://github.com/matsp/material-components-vue) - wrapper around [material-components-web](https://github.com/material-components/material-components-web) for Vue.js. [https://matsp.github.io/material-components-vue/](https://matsp.github.io/material-components-vue/)
- [mint-ui](https://github.com/ElemeFE/mint-ui) - Mobile UI elements for Vue.js. [https://mint-ui.github.io](https://mint-ui.github.io)
- [muse-ui](https://github.com/museui/muse-ui) - Material Design UI library for Vuejs 2.0. [https://museui.github.io](https://museui.github.io)
- [OnsenUI](https://github.com/OnsenUI/OnsenUI) - Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js. [https://onsen.io/](https://onsen.io/)
- [PrimeVue](https://github.com/primefaces/primevue) - A Vue.js 2.0 UI Component library for Web. [https://github.com/primefaces/primevue](https://github.com/primefaces/primevue)
- [Quasar Framework](https://github.com/quasarframework/quasar) - Quasar Framework. Build responsive websites, hybrid mobile Apps (that look native on Android and iOS) and Electron apps using same code, with VueJs 2. [http://quasar-framework.org/](http://quasar-framework.org/)
- [Semantic UI Vue](https://github.com/Semantic-UI-Vue/Semantic-UI-Vue) - Semantic UI integration for Vue [https://semantic-ui-vue.github.io](https://semantic-ui-vue.github.io)
- [v-semantic](https://github.com/eddow/v-semantic) - Implementation of [semantic-ui](https://semantic-ui.com/) for Vue. [https://semantic-ui.com/](https://semantic-ui.com/)
- [vue-blu](https://github.com/chenz24/vue-blu) - UI Component Library Base on Vue.js(2.x) and Bulma. [https://chenz24.github.io/vue-blu](https://chenz24.github.io/vue-blu)
- [vue-bulma-components](https://github.com/vouill/vue-bulma-components) - Easily use bulma class syntax with vue components. [https://codesandbox.io/s/wk2w3z0zk5](https://codesandbox.io/s/wk2w3z0zk5)
- [vue-material](https://github.com/vuematerial/vue-material) - Material design for Vue.js. [https://vuematerial.io/](https://vuematerial.io/)
- [vue-strap](https://github.com/yuche/vue-strap) - Bootstrap components built with Vue.js [http://yuche.github.io/vue-strap/]](http://yuche.github.io/vue-strap/)
- [vuikit](https://github.com/vuikit/vuikit) - A responsive Vue UI library for web site interfaces [https://vuikit.js.org](https://vuikit.js.org)
- [vuesax](https://github.com/lusaxweb/vuesax) - Frontend vue Components for Vue.js. [https://lusaxweb.github.io/vuesax/](https://lusaxweb.github.io/vuesax/)
- [vuetify](https://github.com/vuetifyjs/vuetify) - Material Component Framework for Vue.js 2 [https://vuetifyjs.com](https://vuetifyjs.com)
- [Zircle UI](https://github.com/zircleui/zircleUI) - A lightweight front-end library for developing zoomable user interfaces. [https://zircleui.github.io/zircleUI/](https://zircleui.github.io/zircleUI/)

repo_name: cdleon/ui-frameworks


text:
from functools import reduce
from itertools import cycle
from math import factorial

import numpy as np
import scipy.sparse as sp

def difference(derivative, accuracy=1):
    # Central differences implemented based on the article here:
    # http://web.media.mit.edu/~crtaylor/calculator.html
    derivative += 1
    radius = accuracy + derivative // 2 - 1
    points = range(-radius, radius + 1)
    coefficients = np.linalg.inv(np.vander(points))
    return coefficients[-derivative] * factorial(derivative - 1), points

def operator(shape, *differences):
    # Credit to Philip Zucker for figuring out
    # that kronsum's argument order is reversed.
    # Without that bit of wisdom I'd have lost it.
    differences = zip(shape, cycle(differences))
    factors = (sp.diags(*diff, shape=(dim,) * 2) for dim, diff in differences)
    return reduce(lambda a, f: sp.kronsum(f, a, format='csc'), factors)

repo_name: GregTJ/stable-fluids

repo_language: Python


text:
import numpy as np
from PIL import Image
from scipy.special import erf

from fluid import Fluid

RESOLUTION = 500, 500
DURATION = 200

INFLOW_PADDING = 50
INFLOW_DURATION = 60
INFLOW_RADIUS = 8
INFLOW_VELOCITY = 1
INFLOW_COUNT = 5

print('Generating fluid solver, this may take some time.')
fluid = Fluid(RESOLUTION, 'dye')

center = np.floor_divide(RESOLUTION, 2)
r = np.min(center) - INFLOW_PADDING

points = np.linspace(-np.pi, np.pi, INFLOW_COUNT, endpoint=False)
points = tuple(np.array((np.cos(p), np.sin(p))) for p in points)
normals = tuple(-p for p in points)
points = tuple(r * p + center for p in points)

inflow_velocity = np.zeros_like(fluid.velocity)
inflow_dye = np.zeros(fluid.shape)
for p, n in zip(points, normals):
    mask = np.linalg.norm(fluid.indices - p[:, None, None], axis=0) <= INFLOW_RADIUS
    inflow_velocity[:, mask] += n[:, None] * INFLOW_VELOCITY
    inflow_dye[mask] = 1

frames = []
for f in range(DURATION):
    print(f'Computing frame {f + 1} of {DURATION}.')
    if f <= INFLOW_DURATION:
        fluid.velocity += inflow_velocity
        fluid.dye += inflow_dye

    curl = fluid.step()[1]
    # Using the error function to make the contrast a bit higher.
    # Any other sigmoid function e.g. smoothstep would work.
    curl = (erf(curl * 2) + 1) / 4

    color = np.dstack((curl, np.ones(fluid.shape), fluid.dye))
    color = (np.clip(color, 0, 1) * 255).astype('uint8')
    frames.append(Image.fromarray(color, mode='HSV').convert('RGB'))

print('Saving simulation result.')
frames[0].save('example.gif', save_all=True, append_images=frames[1:], duration=20, loop=0)


text:
# Py Stable Fluids
A minimal Stable Fluids inspired fluid solver with Python and NumPy.
![](example.gif)

Citations:\
[Philip Zucker's blog post on fluid simulation](http://www.philipzucker.com/annihilating-my-friend-will-with-a-python-fluid-simulation-like-the-cur-he-is/)\
[GPUGems fast fluid simulation guide](http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch38.html)\
[Jos Stam's legendary paper](https://d2f99xq7vri1nk.cloudfront.net/legacy_app_files/pdf/ns.pdf)\
[Cameron Taylor's finite difference coefficient calculator and derivation](http://web.media.mit.edu/~crtaylor/calculator.html)


text:
import numpy as np
from scipy.ndimage import map_coordinates, spline_filter
from scipy.sparse.linalg import factorized

from numerical import difference, operator

class Fluid:
    def __init__(self, shape, *quantities, pressure_order=1, advect_order=3):
        self.shape = shape
        self.dimensions = len(shape)

        # Prototyping is simplified by dynamically
        # creating advected quantities as needed.
        self.quantities = quantities
        for q in quantities:
            setattr(self, q, np.zeros(shape))

        self.indices = np.indices(shape)
        self.velocity = np.zeros((self.dimensions, *shape))

        laplacian = operator(shape, difference(2, pressure_order))
        self.pressure_solver = factorized(laplacian)

        self.advect_order = advect_order

    def step(self):
        # Advection is computed backwards in time as described in Stable Fluids.
        advection_map = self.indices - self.velocity

        # SciPy's spline filter introduces checkerboard divergence.
        # A linear blend of the filtered and unfiltered fields based
        # on some value epsilon eliminates this error.
        def advect(field, filter_epsilon=10e-2, mode='constant'):
            filtered = spline_filter(field, order=self.advect_order, mode=mode)
            field = filtered * (1 - filter_epsilon) + field * filter_epsilon
            return map_coordinates(field, advection_map, prefilter=False, order=self.advect_order, mode=mode)

        # Apply advection to each axis of the
        # velocity field and each user-defined quantity.
        for d in range(self.dimensions):
            self.velocity[d] = advect(self.velocity[d])

        for q in self.quantities:
            setattr(self, q, advect(getattr(self, q)))

        # Compute the jacobian at each point in the
        # velocity field to extract curl and divergence.
        jacobian_shape = (self.dimensions,) * 2
        partials = tuple(np.gradient(d) for d in self.velocity)
        jacobian = np.stack(partials).reshape(*jacobian_shape, *self.shape)

        divergence = jacobian.trace()

        # If this curl calculation is extended to 3D, the y-axis value must be negated.
        # This corresponds to the coefficients of the levi-civita symbol in that dimension.
        # Higher dimensions do not have a vector -> scalar, or vector -> vector,
        # correspondence between velocity and curl due to differing isomorphisms
        # between exterior powers in dimensions != 2 or 3 respectively.
        curl_mask = np.triu(np.ones(jacobian_shape, dtype=bool), k=1)
        curl = (jacobian[curl_mask] - jacobian[curl_mask.T]).squeeze()

        # Apply the pressure correction to the fluid's velocity field.
        pressure = self.pressure_solver(divergence.flatten()).reshape(self.shape)
        self.velocity -= np.gradient(pressure)

        return divergence, curl, pressure


text:
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
sw@netcetera.org.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

repo_name: simonwhitaker/gibo

repo_language: Shell

mime_type: text/x-shellscript


text:
# To release a new version automatically

Just push a version tag (e.g. `v3.0.1-beta.1`) to Github

## To release a new version manually

1. Install [GoReleaser](https://goreleaser.com/):

    ```sh
    brew install goreleaser/tap/goreleaser
    ```

2. Create a new release tag:

    ```sh
    git tag -am 'vX.X.X' vX.X.X
    git push --tags
    ```

NB! Tags of the form `vX.X.X-alpha.X` will fail to upload to Chocolatey with a 504 GatewayTimeout error. The final dot is the problem; use `vX.X.X-alphaX` instead.

3. Run GoReleaser:

    GoReleaser requires `GITHUB_TOKEN` to be set. If you have the `gh` tool installed you can probably re-use the token it uses, by calling `gh auth token`:

    ```sh
    GITHUB_TOKEN=$(gh auth token) goreleaser release --clean
    ```


text:
module github.com/simonwhitaker/gibo

go 1.20

require (
	github.com/go-git/go-git/v5 v5.3.0
	github.com/spf13/cobra v1.7.0
	golang.org/x/term v0.10.0
)

require (
	github.com/Microsoft/go-winio v0.6.1 // indirect
	github.com/emirpasic/gods v1.18.1 // indirect
	github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
	github.com/go-git/go-billy/v5 v5.4.1 // indirect
	github.com/imdario/mergo v0.3.16 // indirect
	github.com/inconshreveable/mousetrap v1.1.0 // indirect
	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
	github.com/kevinburke/ssh_config v1.2.0 // indirect
	github.com/mitchellh/go-homedir v1.1.0 // indirect
	github.com/sergi/go-diff v1.3.1 // indirect
	github.com/spf13/pflag v1.0.5 // indirect
	github.com/xanzy/ssh-agent v0.3.3 // indirect
	golang.org/x/crypto v0.11.0 // indirect
	golang.org/x/mod v0.12.0 // indirect
	golang.org/x/net v0.12.0 // indirect
	golang.org/x/sys v0.10.0 // indirect
	golang.org/x/tools v0.11.0 // indirect
	gopkg.in/warnings.v0 v0.1.2 // indirect
)


text:
package main

import "github.com/simonwhitaker/gibo/cmd"

func main() {
	cmd.Execute()
}


text:
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=


text:
# syntax=docker/dockerfile:1

FROM golang:1.20.6-alpine AS build

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -o /gibo

FROM alpine:3.18.2

WORKDIR /

COPY --from=build /gibo /gibo
RUN /gibo update

ENTRYPOINT [ "/gibo" ]


text:
# gibo: fast access to .gitignore boilerplates

**gibo** (short for .gitignore boilerplates) is a command-line tool to help you easily access .gitignore boilerplates from [github.com/github/gitignore](https://github.com/github/gitignore).

## Typical usage

```console
$ gibo dump Swift Xcode >> .gitignore
```

For additional usage instructions, run `gibo help`.

## Installation

### Using Homebrew

```sh
brew install gibo
```

Or use the tap, which may be slightly more up-to-date:

```sh
brew install simonwhitaker/tap/gibo
```

### Using Scoop

On Windows, you can install gibo using [Scoop](https://scoop.sh/#/apps?q=gibo):

```sh
scoop bucket add main
scoop install main/gibo
```

### Using Chocolatey

```
choco install gibo
```

### Using the Go toolchain

```sh
go install github.com/simonwhitaker/gibo@latest
```

### Building from source

Clone the repo, then:

```sh
cd gibo
go install .
```

### Downloading a binary

Download the latest [release](https://github.com/simonwhitaker/gibo/releases) for your platform, then put `gibo` (or `gibo.exe`) somewhere on your path.

### Installation on Docker

```sh
docker run --rm simonwhitaker/gibo
```

## Tab completion in bash, zsh, fish and Powershell

See the instructions at:

```
gibo completion
```

## Use gibo to generate .hgignore files

The `glob` .hgignore syntax for Mercurial is compatible with .gitignore syntax. This means that you can use gibo to generate .hgignore files, as long as the .hgignore files use the `glob` syntax:

```sh
echo 'syntax: glob' > .hgignore
gibo dump Python >> .hgignore
```

## Credits

gibo was written by Simon Whitaker ([@s1mn](http://twitter.com/s1mn))


text:
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: "CI: Go build and test"

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version-file: go.mod

      - name: Build
        run: go build -v ./...

      - name: Test
        run: go test -v ./...


text:
name: Deployment

on:
  push:
    # run only against version tags
    tags:
      - "v*"

permissions:
  contents: write
  # packages: write
  # issues: write

jobs:
  goreleaser:
    # Generates the Github release, and updates the simonwhitaker/tap/gibo
    # Homebrew formula
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - run: git fetch --force --tags
      - uses: actions/setup-go@v4
        with:
          go-version-file: go.mod
      # More assembly might be required: Docker logins, GPG, etc. It all depends
      # on your needs.
      - uses: goreleaser/goreleaser-action@v4
        with:
          # either 'goreleaser' (default) or 'goreleaser-pro':
          distribution: goreleaser
          version: latest
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.PUBLISHER_TOKEN }}
  goreleaser-windows:
    # Generates the Windows artefacts for the release, updates the gibo
    # chocolatey package
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - run: git fetch --force --tags
      - uses: actions/setup-go@v4
        with:
          go-version: stable
      # More assembly might be required: Docker logins, GPG, etc. It all depends
      # on your needs.
      - uses: goreleaser/goreleaser-action@v4
        with:
          # either 'goreleaser' (default) or 'goreleaser-pro':
          distribution: goreleaser
          version: latest
          args: release -f .goreleaser.windows.yaml --clean
        env:
          GITHUB_TOKEN: ${{ secrets.PUBLISHER_TOKEN }}
          CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
  homebrew_core:
    runs-on: ubuntu-latest
    steps:
      - name: Bump Homebrew formula
        uses: dawidd6/action-homebrew-bump-formula@v3
        with:
          token: ${{ secrets.HOMEBREW_CORE_GITHUB_API_TOKEN }}
          formula: gibo
  docker_hub:
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repo
        uses: actions/checkout@v3

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: simonwhitaker/gibo

      - name: Build and push Docker image
        uses: docker/build-push-action@v4
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          file: ./Dockerfile
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}


text:
# To release a new version

Update the version number, currently found in [gibo](./gibo) and [com.github.simonwhitaker.Gibo.appdata.xml](misc/com.github.simonwhitaker.Gibo.appdata.xml). Then:

```sh
export GIBO_VERSION=0.0.1 # replace with the updated version number
git tag -a -m $GIBO_VERSION $GIBO_VERSION
git push --tags
```

A new [Docker build](https://hub.docker.com/repository/docker/simonwhitaker/gibo/builds) will be triggered automatically.

## To update Homebrew

```sh
export GIBO_VERSION=0.0.1 # replace with the updated version number
export GIBO_URL=https://github.com/simonwhitaker/gibo/archive/${GIBO_VERSION}.tar.gz
export GIBO_SHA=$(curl -sSL $GIBO_URL | shasum -a 256 | cut -d' ' -f1)
brew bump-formula-pr gibo --url $GIBO_URL --sha256 $GIBO_SHA
```


text:
@rem #!/dos/rocks!
@setlocal EnableDelayedExpansion
@echo off

rem Script for easily accessing gitignore boilerplates from
rem https://github.com/github/gitignore
rem
rem Change log
rem v1.0    1-May-2012  First public release
rem v1.0.01 16-Aug-2014 Added batch file for DOS by Kody Brown ^<thewizard@wasatchwizard.com^>
rem v2.0.00 11-Jun-2018 Updated to v2; subcommand model by Simon Whitaker ^<sw@netcetera.org^>
rem v2.0.01 13-Jun-2018 Added optional parameter for list subcommand, added search subcommand, added support for GIBO_BOILERPLATES by Kody Brown ^<thewizard@wasatchwizard.com^>

goto :setup

:version
    echo %basename% 2.2 by Simon Whitaker ^<sw@netcetera.org^>
    echo https://github.com/simonwhitaker/gibo
    goto :eof

:usage
    call :version
    echo.
    echo Fetches gitignore boilerplates from github.com/github/gitignore
    echo.
    echo Usage:
    echo     %basename% [command]
    echo.
    echo Example:
    echo     %basename% dump Python NotepadPP ^>^> .gitignore
    echo.
    echo Options:
    echo     dump expr...  Dump boilerplate(s) to stdout
    echo     help          Display this help text
    echo     list          List available boilerplates
    echo     root          Show the directory where gibo stores its boilerplates
    echo     search expr   Search inside boilerplates for expr
    echo     update        Update list of available boilerplates
    echo     version       Display current script version

    goto :eof

:setup
    set "basename=%~n0"
    set "baseext=%~x0"
    set "basepath=%~dp0"

    set "__cloned="

    set "dumping="

    set "remote_repo=https://github.com/github/gitignore.git"

    rem Allow using the `GIBO_BOILERPLATES` system envar
    rem for specifying the boilerplates directory.
    if defined GIBO_BOILERPLATES set "local_repo=%GIBO_BOILERPLATES%"
    if not defined GIBO_BOILERPLATES set "local_repo=%AppData%\.gitignore-boilerplates"

    rem No args passed in, so show usage.
    if "%~1"=="" call :usage && goto :end

:parse
    rem Parse comand-line options.

    if "%~1"=="" goto :end

    set a=%~1

    rem The batch file's equivalent 'Sanity check' is that any
    rem options (-, --, and / for Windows) are executed then
    rem the batch file exits, ignoring any other commands, such
    rem as Python, etc.

    if /i "%a%"=="help"     call :usage         & goto :end
    if /i "%a%"=="/?"       call :usage         & goto :end
    if /i "%a%"=="version"  call :version       & goto :end
    if /i "%a%"=="/v"       call :version       & goto :end
    if /i "%a%"=="list"     call :list "%~2"    & goto :end
    if /i "%a%"=="root"     call :root          & goto :end
    if /i "%a%"=="search"   call :search "%~2"  & goto :end
    if /i "%a%"=="update"   call :update        & goto :end

    if /i "%a%"=="dump"     set "dumping=1"     & shift & goto :parse

    if defined dumping      call :dump "%a%"    & shift & goto :parse

    goto :invalid_argument "%a%"

:end
    @endlocal && exit /B 0

:invalid_argument "arg"
    echo Invalid argument: %~1
    echo Did you mean:

    rem Is there a .gitignore file?
    set "_foundfile="
    if exist "%local_repo%\%~1.gitignore" set "_foundfile=yes"
    if exist "%local_repo%\Global\%~1.gitignore" set "_foundfile=yes"
    if defined _foundfile (
        echo     `%basename% dump %*`
        echo     `%basename% list %*`
    )

    rem Did the user mean to search within .gitignore files?
    echo     `%basename% search %*`

    endlocal && exit /B 1

:clone [--silently]
    if "%~1"=="--silently" ( set "opt=-q" ) else ( set "opt=" )
    git clone %opt% "%remote_repo%" "%local_repo%"
    goto :eof

:init [--silently]
    if not exist "%local_repo%\.git" set "__cloned=yes" && call :clone "%~1"
    goto :eof

:list
    call :init

    echo === Languages ===
    echo.
    for /f %%G in ('dir /b /on "%local_repo%\*%~1*.gitignore"') do (
        echo %%~nG
    )

    echo.
    echo === Global ===
    echo.
    for /f %%G in ('dir /b /on "%local_repo%\Global\*%~1*.gitignore"') do (
        echo %%~nG
    )

    goto :eof

:root
    echo %local_repo%
    goto :eof

:search
    if "%~1"=="" echo %basename%: missing search expr.. && goto :eof

    call :init

    rem `findstr` options:
    rem   /R         Uses search strings as regular expressions.
    rem   /S         Searches for matching files in the current directory and all
    rem              subdirectories.
    rem   /I         Specifies that the search is not to be case-sensitive.
    rem   /N         Prints the line number before each line that matches.
    rem   /P         Skip files with non-printable characters.
    rem   /A:attr    Specifies color attribute with two hex digits. See "color /?"
    rem   strings    Text to be searched for.
    rem   [drive:][path]filename
    rem              Specifies a file or files to search.

    pushd "%local_repo%"
    findstr /S /R /I /N /P /A:03 "%~1" *.gitignore
    popd

    goto :eof

:update
    call :init

    rem If the repo was just cloned, don't perform a `pull`
    if not defined __cloned (
        echo updating..
        pushd "%local_repo%"
        git pull -q --ff origin main
        popd
    )

    goto :eof

:dump
    call :init --silently

    set "language_file=%local_repo%\%~1.gitignore"
    set "global_file=%local_repo%\Global\%~1.gitignore"

    if exist "%language_file%" (
        echo ### Generated by gibo ^(https://github.com/simonwhitaker/gibo^)
        echo ### %~1
        echo.
        type "%language_file%"
        echo.
        echo.
    ) else if exist "%global_file%" (
        echo ### %~1
        echo.
        type "%global_file%"
        echo.
        echo.
    ) else (
        echo Unknown argument: %~1
    )

    goto :eof


text:
#!/bin/sh
#
# Script for easily accessing gitignore boilerplates from
# https://github.com/github/gitignore

remote_repo=https://github.com/github/gitignore.git
local_repo=${GIBO_BOILERPLATES:-"$HOME/.gitignore-boilerplates"}
current_repo_rev=$(cd "$local_repo" 2>/dev/null && git rev-parse HEAD)
remote_web_root=https://raw.github.com/github/gitignore/$current_repo_rev

version() {
    echo "$(basename "$0") 2.2.8 by Simon Whitaker"
    echo "https://github.com/simonwhitaker/gibo"
}

usage() {
    version
cat << EOF >&2

Fetches gitignore boilerplates from https://github.com/github/gitignore

Usage:
    $(basename "$0") [command]

Example:
    $(basename "$0") dump Swift Xcode >> .gitignore

Commands:
    dump BOILERPLATE...   Write boilerplate(s) to STDOUT
    help                  Display this help text
    list                  List available boilerplates
    root                  Show the directory where gibo stores its boilerplates
    search STR            Search for boilerplates with STR in the name
    update                Update list of available boilerplates
    version               Display current script version
EOF
}

clone() {
    if [ "$1" ] && [ "$1" = '--silently' ]; then
        git clone --depth 1 --quiet "$remote_repo" "$local_repo"
    else
        echo "Cloning $remote_repo to $local_repo"
        git clone --depth 1 "$remote_repo" "$local_repo"
    fi
}

init() {
    if [ ! -e "$local_repo/.git" ]; then
        clone "$1"
    fi
}

list() {
    init

    if [ -t 1 ]; then
        shape='column'
    else
        shape='cat'
    fi

    find "$local_repo" -name '*.gitignore' | sort -f \
      | sed -e 's@^.*/\([^/]*\)\.gitignore$@\1@' | eval ${shape}
}

root() {
    echo "$local_repo"
}

search() {
    init --silently
    for filename in $(find "$local_repo" -iname "*$**.gitignore" -exec basename \{\} .gitignore \; | sort); do
        echo "$filename"
    done
}

update() {
    if [ ! -e "$local_repo/.git" ]; then
        clone
    else
        cd "$local_repo" || exit
        git pull --ff origin main
        git checkout main
    fi
}

dump() {
    init --silently

    language_file=$(find "$local_repo" -iname "$1.gitignore" | head -n 1)
    language_file_relative=${language_file#"$local_repo/"}

    if [ -n "$language_file" ]; then
        echo "### $remote_web_root/$language_file_relative"
        echo
        cat "$language_file"
        echo
        echo
    else
        echo "Unknown argument: $1" >&2
        exit 1
    fi
}

# --- Main entry point ----------------------

if [ $# -eq 0 ]; then
    usage
    exit 1
fi

# Parse comand-line
should_dump=0
while [ $# -gt 0 ]; do
    case $1 in
        version )
            version
            exit 0
            ;;
        list )
            list
            exit 0
            ;;
        root )
            root
            exit 0
            ;;
        update )
            update
            exit 0
            ;;
        help )
            usage
            exit 0
            ;;
        dump )
            if [ $# -gt 1 ]; then
                echo "### Generated by gibo (https://github.com/simonwhitaker/gibo)"
                should_dump=1
            else
                usage
                exit 1
            fi
            ;;
        search )
            if [ $# -gt 1 ]; then
                shift
                search "$@"
                exit 0
            else
                usage
                exit 1
            fi
            ;;
        * ) # default case
            if [ $should_dump -eq 1 ]; then
                dump "$1"
            else
                usage
                exit 1
            fi
            ;;
    esac
    shift
done


text:
FROM alpine

COPY gibo gibo

# install requirements
RUN apk --no-cache --update add git && ./gibo update

ENTRYPOINT ["./gibo"]


text:
# gibo: fast access to .gitignore boilerplates

![CI](https://github.com/simonwhitaker/gibo/workflows/CI/badge.svg)

**gibo** (short for .gitignore boilerplates) is a shell script to help you easily access .gitignore boilerplates from [github.com/github/gitignore](https://github.com/github/gitignore).

## Typical usage

    $ gibo dump Swift Xcode >> .gitignore

For additional usage instructions, run `gibo help`.

## Installation

### Installation on OS X using [Homebrew](http://mxcl.github.com/homebrew/)

    brew install gibo

### Installation on Fedora Linux

`gibo` is avaiable as a [COPR repository](https://copr.fedorainfracloud.org/). It provides packages for main script and bash / zsh completions:

    dnf copr enable saschpe/gibo
    dnf install gibo gibo-bash-completion gibo-zsh-completion

### Installation on other (*nix) platforms

Just download `gibo` and put it somewhere on your $PATH. Then:

    chmod +x /path/to/gibo   # Make gibo executable
    gibo update              # Initialise gibo

You can automate this with the following one-liner (assuming ~/bin is on your $PATH).

    curl -L https://raw.github.com/simonwhitaker/gibo/master/gibo \
        -so ~/bin/gibo && chmod +x ~/bin/gibo && gibo update

### Installation on Windows

#### Using scoop

The easiest way to install `gibo` on Windows is to use [scoop](https://github.com/lukesampson/scoop), a PowerShell-based package-manager of sorts for Windows:

    scoop update
    scoop install gibo

A great benefit to using scoop, is that it provides an easy way to update its packages, including gibo:

    scoop update
    scoop update gibo

#### git installation

You can download the whole `gibo` repo directly from GitHub:

    md "C:\Users\<Your User>\bin"
    cd /D "C:\Users\<Your User>\bin"
    git clone https://github.com/simonwhitaker/gibo.git gibo

Then add the full gibo directory (`C:\Users\<Your User>\bin\gibo`) to your system's PATH environment variable.

#### Manual installation

To manually install only the `gibo.bat` file, download it to your computer and save it to any directory that is in your PATH.

Right-click [this link](https://raw.githubusercontent.com/simonwhitaker/gibo/master/gibo.bat) and select 'Save target as...' (or 'Save link as...' depending on your browser) to save it to your computer.

A good directory to put the file is `C:\Users\<Your User>\bin` and add that directory to your system's PATH environment variable. Where ever you put it, make sure the batch file is accessible via `where gibo`.

### Installation on Docker

Just type the following command.

    $ docker run --rm simonwhitaker/gibo

## Tab completion in bash, zsh and fish

bash, zsh and fish users can enjoy the deluxe gibo experience by enabling tab completion of available boilerplate names.

Sorry, there is no tab completion support in Windows.

### bash instructions

Copy `gibo-completion.bash` into a `bash_completion.d` folder:

* `/etc/bash_completion.d`
* `/usr/local/etc/bash_completion.d`
* `~/bash_completion.d`

or copy it somewhere (e.g. ~/.gibo-completion.bash) and put the following in your .bashrc:

    source ~/.gibo-completion.bash

### zsh instructions

Copy `gibo-completion.zsh` somewhere in your `$fpath`. The convention for autoloaded functions used in completion is that they start with an underscore, so I suggest you rename it to `_gibo`.

Alternatively, you can use `gibo-completion.zsh` as an [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) plugin by following [these instructions](https://github.com/simonwhitaker/gitignore-boilerplates/wiki/Using-gibo-as-an-ohmyzsh-plugin).

### fish instructions

Copy `gibo.fish` to somewhere in your `$fish_complete_path`.

## Use gibo to generate .hgignore files

The `glob` .hgignore syntax for Mercurial is compatible with .gitignore syntax. This means that you can use gibo to generate .hgignore files, as long as the .hgignore files use the `glob` syntax:

    echo 'syntax: glob' > .hgignore
    $ gibo dump Python TextMate >> .hgignore

## Feeling brave?

Want to help test gibo v3, re-written in Go?! Clone https://github.com/simonwhitaker/gibo-go, or:

```command
brew install simonwhitaker/tap/gibo-go
```

(It installs as `gibo-go`, so you can install it alongside classic gibo.)

## Credits

gibo was written by Simon Whitaker ([@s1mn](http://twitter.com/s1mn))

Thanks to [yevgenko](https://github.com/yevgenko) for adding the curl-based installation instructions.

Thanks to [kodybrown](https://github.com/kodybrown) for adding the gibo.bat batch file for Windows.


text:
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Check out source
        uses: actions/checkout@v2
      - name: Get version
        run: ./gibo version
      - name: Shellcheck
        run: shellcheck ./gibo tests/test.sh
      - name: Run test
        run: ./tests/test.sh

  test-windows:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v2
      - name: Get version
        run: .\gibo.bat version


text:
#!/bin/bash

GIBO_BOILERPLATES=$(dirname "$0")/mock-boilerplates
export GIBO_BOILERPLATES
gibo=$(dirname "$0")/../gibo

fail() {
    echo "$1"
    exit 1
}

# Create a dummy .git directory inside $GIBO_BOILERPLATES to placate gibo's
# clone function.
(cd "$GIBO_BOILERPLATES" && mkdir -p .git)

# Calling gibo without subcommand exits with non-zero exit status
if $gibo >/dev/null 2>&1; then
    fail "Got successful (zero) exit status when run without subcommand"
fi

# It fails when the boilerplate file doesn't exist
if $gibo dump UnknownBoilerplate >/dev/null 2>&1; then
    fail "Got successful (zero) exit status for unknown boilerplate"
fi

# It succeeds when the boilerplate file exists
if ! $gibo dump Foo >/dev/null; then
    fail "Got unsuccessful (non-zero) exit status for known boilerplate"
fi

# `gibo dump Foo` outputs 8 lines
expected=8
lines=$($gibo dump Foo | wc -l)
if [[ $lines -ne $expected ]]; then
    fail "Expected $expected lines in output of 'gibo dump Foo', got $lines"
fi

# `gibo dump Foo Bar` outputs 16 lines
expected=15
lines=$($gibo dump Foo Bar | wc -l)
if [[ $lines -ne $expected ]]; then
    fail "Expected $expected lines in output of 'gibo dump Foo Bar', got $lines"
fi


text:
# Fish completion for gibo
#
# INSTALLATION
#
# First install gibo from
# https://github.com/simonwhitaker/gitignore-boilerplates
#
# Then copy this file to somewhere in $fish_complete_path,
# e.g. ~/.config/fish/completions
#
# CREDITS
#
# Initial version written by Sebastian Schulz <https://github.com/yilazius>

function __gibo_wants_subcommand
    set cmd (commandline -opc)
    if test (count $cmd) -eq 1
        return 0
    end
    return 1
end

function __gibo_using_subcommand
    set cmd (commandline -opc)
    set subcommand $argv[1]
    if test (count $cmd) -ge 2
        and test $cmd[2] = $subcommand
        return 0
    end
    return 1
end

function __gibo_completion_list
    set gibo_home "$HOME/.gitignore-boilerplates"
    if set -q GIBO_BOILERPLATES
        set gibo_home $GIBO_BOILERPLATES
    end
    find "$gibo_home" -name "*.gitignore" -exec basename \{\} .gitignore \;
end

complete -c gibo -n "__gibo_wants_subcommand" -f -a "dump" -d 'Dump one or more boilerplates to STDOUT'
complete -c gibo -n "__gibo_wants_subcommand" -f -a "search" -d 'Search for boilerplates'
complete -c gibo -n "__gibo_wants_subcommand" -f -a "root" -d 'Show the directory where gibo stores its boilerplates'
complete -c gibo -n "__gibo_wants_subcommand" -f -a "help" -d 'Show help information'
complete -c gibo -n "__gibo_wants_subcommand" -f -a "list" -d 'Show the list of available boilerplates'
complete -c gibo -n "__gibo_wants_subcommand" -f -a "update" -d 'Update the list of available boilerplates'
complete -c gibo -n "__gibo_wants_subcommand" -f -a "version" -d 'Show the current version of gibo installed'
complete -c gibo -n "__gibo_using_subcommand dump" -f -a '(__gibo_completion_list)'


text:
# Bash completion for gibo
#
# INSTALLATION
#
# First install gibo from
# https://github.com/simonwhitaker/gitignore-boilerplates
#
# Then copy this file into a bash_completion.d folder:
#
#     /etc/bash_completion.d
#     /usr/local/etc/bash_completion.d
#     ~/bash_completion.d
#
# or copy it somewhere (e.g. ~/.gibo-completion.bash) and put the
# following in your .bashrc:
#
#     source ~/.gibo-completion.bash
#
# CREDITS
#
# Written by Simon Whitaker <sw@netcetera.org>

_gibo()
{
    local cur prev opts
    cur="${COMP_WORDS[COMP_CWORD]}"

    case $COMP_CWORD in
        1)
            COMPREPLY=($(compgen -W "dump help list root search update version" -- ${cur}))
            ;;
        *)
            subcommand="${COMP_WORDS[1]}"
            case $subcommand in
                dump)
                    opts=$( find ${GIBO_BOILERPLATES:-"$HOME/.gitignore-boilerplates"} -name "*.gitignore" -exec basename \{\} .gitignore \; )
                    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                    ;;
                *)
                    COMPREPLY=()
                    ;;
            esac
            ;;
    esac
}

complete -F _gibo gibo


text:
#compdef gibo
#
# Zsh completion for gibo
#
# INSTALLATION
#
# First install gibo from
# https://github.com/simonwhitaker/gitignore-boilerplates
#
# Make sure autocompletion is enabled in your shell, typically
# by adding this to your .zshrc:
#
#     autoload -U compinit && compinit
#
# Then copy this file somewhere (e.g. ~/.zsh/_gibo) and put the
# following in your .zshrc:
#
#     fpath=(~/.zsh $fpath)
#
#
# CONTRIBUTING
#
# See https://github.com/zsh-users/zsh-completions/blob/master/zsh-completions-howto.org
# for tips on writing and testing zsh completion functions.
#
# CREDITS
#
# Written by Simon Whitaker <sw@netcetera.org>

_gibo_commands()
{
    _gibo_commands=(
        'dump:Dump one or more boilerplates' \
        'help:Display this help text' \
        'list:List available boilerplates' \
        'root:Show the directory where gibo stores its boilerplates' \
        'search:Search for boilerplates' \
        'update:Update list of available boilerplates' \
        'version:Display current script version'
    )
    _describe 'command' _gibo_commands
}

_gibo_dump_commands()
{
    local local_repo=${GIBO_BOILERPLATES:-"$HOME/.gitignore-boilerplates"}
    local -a boilerplates
    if [ -e "$local_repo" ]; then
        boilerplates=($local_repo/**/*.gitignore(:r:t))
    fi

    _arguments "*:boilerplate:($boilerplates)"
}

_gibo()
{
    local ret=1

    _arguments -C \
        '1: :_gibo_commands' \
        '*::arg:->args' \
        && ret=0

    case $state in
        args )
            case $line[1] in
                dump )
                    _arguments \
                        '*: :_gibo_dump_commands' \
                        && ret=0
                    ;;
            esac
    esac
}


text:
package utils

import (
	"fmt"
	"testing"
)

func TestGetMaxLengthAndNumColumns(t *testing.T) {
	var tests = []struct {
		list []string
		terminalWidth,
		expectedMaxLength, expectedNumColumns int
	}{
		// Always get at least one column
		{[]string{"foo", "bar"}, 1, 3, 1},

		// Get multiple columns as soon as there is space
		{[]string{"foo", "bar"}, 6, 3, 1},
		{[]string{"foo", "bar"}, 7, 3, 2},

		// Rudimentary max width test
		{[]string{"a", "bbb", "cc"}, 1, 3, 1},
	}
	for _, tt := range tests {
		testName := fmt.Sprintf("%v,%v", tt.list, tt.terminalWidth)
		t.Run(testName, func(t *testing.T) {
			maxLength, numColumns := getMaxLengthAndNumColumns(tt.list, tt.terminalWidth)
			if maxLength != tt.expectedMaxLength {
				t.Errorf("Expected maxLength %v, got %v", tt.expectedMaxLength, maxLength)
			}

			if numColumns != tt.expectedNumColumns {
				t.Errorf("Expected numColumns %v, got %v", tt.expectedNumColumns, numColumns)
			}
		})
	}
}


text:
package utils

import "fmt"

// calculate returns
func getMaxLengthAndNumColumns(list []string, terminalWidth int) (int, int) {
	maxLength := 0
	for _, s := range list {
		if len(s) > maxLength {
			maxLength = len(s)
		}
	}

	// For n columns, we need enough room for n-1 spaces between the columns.
	//
	// For a list where the longest string is of length maxLength, the maximum
	// number of columns we can print is the largest number, n, where:
	//
	//    n * maxLength + n - 1 <= terminalWidth
	//
	// Rearranging:
	//
	//    n * maxLength + n <= terminalWidth + 1
	//    n * (maxLength - 1) <= terminalWidth + 1
	//    n <= (terminalWidth + 1) / (maxLength + 1)
	numColumns := (terminalWidth + 1) / (maxLength + 1)
	if numColumns == 0 {
		numColumns = 1
	}
	return maxLength, numColumns
}

func PrintInColumns(list []string, terminalWidth int) {
	maxLength, numColumns := getMaxLengthAndNumColumns(list, terminalWidth)
	fmtString := fmt.Sprintf("%%-%ds", maxLength)
	for i, s := range list {
		fmt.Printf(fmtString, s)
		if (i%numColumns == numColumns-1) || i == len(list)-1 {
			fmt.Print("\n")
		} else {
			fmt.Print(" ")
		}
	}
}


text:
package utils

import (
	"fmt"
	"io"
	"io/fs"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/go-git/go-git/v5"
)

func RepoDir() string {
	override := os.Getenv("GIBO_BOILERPLATES")
	if len(override) > 0 {
		return override
	}
	return filepath.Join(os.Getenv("HOME"), ".gitignore-boilerplates")
}

func cloneRepo(repo string) error {
	err := os.MkdirAll(repo, 0755)
	if err != nil && !os.IsExist(err) {
		return err
	}
	_, err = git.PlainClone(repo, false, &git.CloneOptions{
		URL:   "https://github.com/github/gitignore.git",
		Depth: 1,
	})
	if err != nil && err != git.ErrRepositoryAlreadyExists {
		return err
	}
	return nil
}

func cloneIfNeeded() error {
	fileInfo, err := os.Stat(RepoDir())
	if os.IsNotExist(err) {
		err = cloneRepo(RepoDir())
		if err != nil {
			return err
		}
	} else if !fileInfo.IsDir() {
		return fmt.Errorf("%v exists but is not a directory", RepoDir())
	}
	return nil
}

// pathForBoilerplate returns the filepath for a given boilerplate name. The
// search is case-insensitive; passing `python` to `name` will find the path to
// `Python.gitignore`, for example.
func pathForBoilerplate(name string) (string, error) {
	filename := name + ".gitignore"
	var result string = ""
	filepath.WalkDir(RepoDir(), func(path string, d fs.DirEntry, err error) error {
		if strings.ToLower(filepath.Base(path)) == strings.ToLower(filename) {
			result = path
			// Exit WalkDir early, we've found our match
			return filepath.SkipAll
		}
		return nil
	})
	if len(result) > 0 {
		return result, nil
	}
	return "", fmt.Errorf("%v: boilerplate not found", name)
}

func PrintBoilerplate(name string) error {
	if err := cloneIfNeeded(); err != nil {
		return err
	}
	path, err := pathForBoilerplate(name)
	if err != nil {
		return err
	}

	// Get the revision hash for the current head
	r, err := git.PlainOpen(RepoDir())
	if err != nil {
		return err
	}
	revision, err := r.Head()
	if err != nil {
		return err
	}
	remoteWebRoot := "https://raw.github.com/github/gitignore/" + revision.Hash().String()
	relativePath := strings.TrimPrefix(path, RepoDir())
	// On Windows, relativePath will use backslashes, but we need to append it to
	// a URL, which uses forward slashes.
	if os.PathSeparator == '\\' {
		relativePath = strings.ReplaceAll(relativePath, "\\", "/")
	}

	fmt.Println("### Generated by gibo (https://github.com/simonwhitaker/gibo)")
	fmt.Printf("### %v%v\n\n", remoteWebRoot, relativePath)
	if err != nil {
		return err
	}
	f, err := os.Open(path)
	if err != nil {
		return err
	}
	io.Copy(os.Stdout, f)
	return nil
}

func ListBoilerplates() ([]string, error) {
	var result []string
	if err := cloneIfNeeded(); err != nil {
		return nil, err
	}
	err := filepath.WalkDir(RepoDir(), func(path string, d fs.DirEntry, err error) error {
		base := filepath.Base(path)
		ext := filepath.Ext(base)
		if ext == ".gitignore" {
			name := strings.TrimSuffix(base, ext)
			result = append(result, name)
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	sort.Strings(result)
	return result, nil
}

func ListBoilerplatesNoError() []string {
	result, _ := ListBoilerplates()
	return result
}

func Update() (string, error) {
	cloneIfNeeded()
	r, err := git.PlainOpen(RepoDir())
	if err != nil {
		return "", err
	}
	w, err := r.Worktree()
	if err != nil {
		return "", err
	}
	err = w.Pull(&git.PullOptions{})
	if err != nil && err != git.NoErrAlreadyUpToDate {
		return "", err
	} else if err != nil {
		return "Already up to date", nil
	}
	return "Updated", nil
}


text:
package cmd

import (
	"fmt"

	"github.com/simonwhitaker/gibo/utils"
	"github.com/spf13/cobra"
)

func init() {
	giboCmd.AddCommand(rootCmd)
}

var rootCmd = &cobra.Command{
	Use:   "root",
	Short: "Show the directory where gibo stores its boilerplates",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println(utils.RepoDir())
	},
}


text:
package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// These vars are populated at build time via the `-ldflags` configured in
// `.gorelease.yml`. More info at https://www.digitalocean.com/community/tutorials/using-ldflags-to-set-version-information-for-go-applications
var (
	version = "dev"
)

func init() {
	giboCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Show the current version number of gibo",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println(version)
	},
}


text:
package cmd

import (
	"fmt"
	"log"

	"github.com/simonwhitaker/gibo/utils"
	"github.com/spf13/cobra"
)

func init() {
	giboCmd.AddCommand(updateCmd)
}

var updateCmd = &cobra.Command{
	Use:   "update",
	Short: "Update the gitignore boilerplate repository",
	Run: func(cmd *cobra.Command, args []string) {
		msg, err := utils.Update()
		if err != nil {
			log.Fatal(err)
		} else {
			fmt.Println(msg)
		}
	},
}


text:
package cmd

import (
	"fmt"
	"io/fs"
	"log"
	"path/filepath"
	"strings"

	"github.com/simonwhitaker/gibo/utils"
	"github.com/spf13/cobra"
)

func init() {
	giboCmd.AddCommand(searchCmd)
}

var searchCmd = &cobra.Command{
	Use:   "search",
	Short: "Search for boilerplates",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		searchTerm := args[0]
		err := filepath.WalkDir(utils.RepoDir(), func(path string, d fs.DirEntry, err error) error {
			base := filepath.Base(path)
			ext := filepath.Ext(base)
			if ext == ".gitignore" {
				filename := strings.TrimSuffix(base, ext)
				if strings.Contains(strings.ToLower(filename), strings.ToLower(searchTerm)) {
					fmt.Println(filename)
				}
			}
			return nil
		})
		if err != nil {
			log.Fatal(err)
		}
	},
}


text:
package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

var giboCmd = &cobra.Command{
	Use:   "gibo",
	Short: "gibo is a command-line tool for easily accessing gitignore boilerplates",
}

func Execute() {
	if err := giboCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}


text:
package cmd

import (
	"log"

	"github.com/simonwhitaker/gibo/utils"
	"github.com/spf13/cobra"
)

func init() {
	giboCmd.AddCommand(dumpCmd)
}

var dumpCmd = &cobra.Command{
	Use:       "dump",
	Short:     "Dump a boilerplate",
	Args:      cobra.MinimumNArgs(1),
	ValidArgs: utils.ListBoilerplatesNoError(),
	Run: func(cmd *cobra.Command, args []string) {
		for _, boilerplate := range args {
			if err := utils.PrintBoilerplate(boilerplate); err != nil {
				log.Fatalf("On dumping %v: %v", boilerplate, err)
			}
		}
	},
}


text:
package cmd

import (
	"fmt"
	"log"
	"os"

	"github.com/simonwhitaker/gibo/utils"
	"github.com/spf13/cobra"
	"golang.org/x/term"
)

func init() {
	giboCmd.AddCommand(listCmd)
}

var listCmd = &cobra.Command{
	Use:   "list",
	Short: "List available boilerplates",
	Run: func(cmd *cobra.Command, args []string) {
		list, err := utils.ListBoilerplates()
		if err != nil {
			log.Fatal(err)
		}
		if term.IsTerminal(int(os.Stdout.Fd())) {
			w, _, err := term.GetSize(int(os.Stdout.Fd()))
			if err == nil {
				utils.PrintInColumns(list, w)
				os.Exit(0)
			}
		}
		for _, el := range list {
			fmt.Println(el)
		}
	},
}


text:
#!/bin/bash

default_tag=$(git describe)
tag=${1:-$default_tag}

if [ -z "$1" ]; then
  echo "Defaulted to version $tag"
fi

# Quit early if the release doesn't exist
gh release view "$tag" >/dev/null || exit 1

gh release delete-asset -y "$tag" checksums.windows.txt
gh release delete-asset -y "$tag" gibo_Windows_x86_64.zip
gh release delete-asset -y "$tag" gibo_Windows_i386.zip
gh release delete-asset -y "$tag" gibo_Windows_arm64.zip