├── .gitmodules ├── 0 - Sample ├── Sample.pdf ├── Sample.pptx ├── license.txt └── readme.md ├── 5 Tips for Cultivating Emotional Intelligence in the Workplace └── readme.md ├── 7 Languages in 7 Hours └── readme.md ├── A Crash Course on Building Microservice-based Architectures └── readme.md ├── A Math-Free Intorduction to Neural Networks └── readme.md ├── A Technical Tour of Real-World Web Application Vulnerabilities └── readme.md ├── A-new-storm-is-brewing-Spring-Data-Flow-Server-for-Kubernetes ├── license.txt ├── readme.md └── spring-data-flow-CM2017.pdf ├── AgileSwift └── AgileSwift.pdf ├── Asset Template Guides └── readme.md ├── Bash On Ubuntu On Windows ├── BashOnUbuntuOnWindows.pptx └── README.MD ├── Bedtime Stories └── readme.md ├── Beyond the language the importance of algorithms in programming └── readme.md ├── Big Data == Big Testing └── readme.md ├── Bringing Up Our Future - On Mentoring Junior Developers ├── Bringing Up Our Future - On Mentoring Junior Developers.pdf └── Readme.md ├── Building Lightsabers Workshop └── readme.md ├── Building Self-Defending Applications With AppSensor └── README.md ├── Building Serverless Applications in AWS Workshop └── readme.md ├── Building Serverless Software with AWS Lambda ├── presentation with notes.pdf ├── presentation.pdf └── readme.md ├── Building a Better Development Shop ├── Readme.md └── TheSoftwareGuild-HowToBuildABetterDevelopmentShop-CodeMash Presentation 1-9-17.pptx ├── Building failure resistant systems with circuit breakers ├── Building failure resistant systems with circuit breakers.pdf └── Readme.md ├── Building for the PHP Command Line Interface ├── .bowerrc ├── .editorconfig ├── .gitignore ├── .jshintrc ├── .yo-rc.json ├── Gruntfile.coffee ├── README.md ├── bower.json ├── css │ ├── source │ │ └── theme.scss │ └── theme.css ├── js │ └── loadhtmlslides.js ├── package.json ├── resources │ ├── .gitkeep │ ├── emily.jpg │ └── tim-lytle.jpg ├── slides │ ├── about-me.md │ ├── argc.md │ ├── args.md │ ├── argv.md │ ├── artisan.md │ ├── benefits.md │ ├── best-practices.md │ ├── composability.md │ ├── composability2.md │ ├── daemons.md │ ├── dont-assume-anything.md │ ├── drush.md │ ├── emily.md │ ├── environment-variables.md │ ├── environment-variables2.md │ ├── escapeshellcmd.md │ ├── escaping-arguments.md │ ├── escaping-shell-commands.md │ ├── example-symfony-console.md │ ├── example-symfony-console2.md │ ├── example-symfony-console3.md │ ├── example-symfony-console4.md │ ├── examples.md │ ├── exit-codes.md │ ├── exit-codes2.md │ ├── garbage-collection.md │ ├── getopt.md │ ├── how-does-it-run.md │ ├── in-the-wild.md │ ├── index.md │ ├── joomla-console.md │ ├── list.json │ ├── php-cli-tools-example.md │ ├── php-cli-tools-example2.md │ ├── php-cli-tools.md │ ├── php-sapi.md │ ├── symfony-console.md │ ├── system-commands.md │ ├── system-commands2.md │ ├── system-commands3.md │ ├── thank-you.md │ ├── types-of-arguments.md │ ├── verbosity.md │ ├── when-might-i-use-them.md │ ├── why-the-cli.md │ ├── wp-cli-example.md │ ├── wp-cli-example2.md │ ├── wp-cli-example3.md │ ├── wp-cli-example4.md │ ├── wp-cli.md │ └── writing-your-own-scripts.md └── templates │ ├── _index.html │ └── _section.html ├── Caching Made Bootiful └── readme.md ├── Can I Build a 12-Factor App in .Net └── Can I Build a 12-Factor App in .Net.pptx ├── Chipping away at the monolith with Go ├── demos │ ├── README.md │ ├── go-kit │ │ └── main.go │ ├── interfaces │ │ └── main.go │ └── server │ │ └── main.go └── readme.md ├── Clouds and Containers └── readme.md ├── Components-and-More-Effective-Angular-2-Testing-Strategies └── README.md ├── Containers for Windows Developers └── README.md ├── DDD for Beginners └── readme.md ├── Declarative testing for JavaScript applications ├── .jshintrc ├── Gruntfile.js ├── README.md ├── bs-config.json ├── dist │ ├── css │ │ ├── app.min.css │ │ └── bootstrap.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── index.html │ └── js │ │ ├── app.min.js │ │ ├── app.uglified.js.map │ │ └── ui-bootstrap-tpls.js ├── generators │ └── generator-my-app │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── generators │ │ ├── app │ │ │ ├── index.js │ │ │ └── templates │ │ │ │ └── dummyfile.txt │ │ └── display │ │ │ ├── index.js │ │ │ └── templates │ │ │ ├── display.expect.js.tmplt │ │ │ ├── display.html.tmplt │ │ │ ├── display.js.tmplt │ │ │ ├── display.spec.js.tmplt │ │ │ └── tab-summary.html.tmplt │ │ ├── gulpfile.js │ │ └── package.json ├── karma.conf.js ├── package.json ├── src │ ├── components │ │ └── project │ │ │ ├── display.html │ │ │ ├── display.js │ │ │ └── tab-summary.html │ ├── css │ │ └── index.less │ ├── index.html │ ├── js │ │ └── app.js │ └── tmp │ │ ├── app-components.js │ │ ├── app.annotated.js │ │ ├── app.max.css │ │ ├── app.min.js │ │ ├── app.uglified.js │ │ └── app.uglified.js.map └── test │ ├── Jhelpers.js │ └── structural │ └── components │ └── project │ ├── project.expect.js │ └── project.spec.js ├── Design Before Code └── readme.md ├── DevOps at Scale Greek Tragedy in 3 Acts └── shownotes.md ├── DevOps at Scale └── readme.md ├── Docker Container Lifecycles Problem or Opportunity └── shownotes.md ├── Docker and Kubernetes Recipes ├── docker-kubernetes-recipes.pdf └── readme.adoc ├── Dont Write Secure Code Design Secure Systems └── readme.md ├── Fat Controller CQRS Diet └── readme.md ├── Fragments - the solution to (and cause of) all of android's problems └── readme.md ├── From Zero to the Actor Model └── readme.md ├── Full Stack ASP.NET Performance └── readme.md ├── Functional Reactive Programming with JavaScript └── readme.md ├── GraphQL What it is and why you should care └── readme.md ├── Hacking and Hardening Java Web Applications └── readme.md ├── Horizontally Scaling Nodejs and WebSockets └── readme.md ├── How to Disclose a Security Vulnerability ├── README.md ├── license.txt └── slides.pdf ├── How to Have the Best Dates Ever ├── Readme.md └── readme.md ├── How to Hire Programmers You'll Want as Teammates └── readme.md ├── How to write Java web apps like a JS hipster └── readme.md ├── Implementing Binary Protocols With Elixir └── readme.md ├── Incredibly Strange Programming Languages └── readme.md ├── Integrating React Into A Legacy Web App └── readme.md ├── Introducing Managed Effects ├── README.md └── slides.pdf ├── Java 8 Puzzlers The strange the bizarre and the wonderful └── shownotes.md ├── JavaScript Robotics - Not a Bad Idea └── readme.md ├── Lets Write a Lambda Calculus in Haskell ├── LambdaCal.hs ├── Let's Write a Lambda Calculus in Haskell.pdf └── README.mkd ├── Life After Nil └── Readme.md ├── Mashing Up QA and Security └── readme.md ├── Migrating the Monolithic to the Microscopic └── README.md ├── Netflix Culture Freedome and Responsibility └── readme.md ├── Patterns of Effective Test Setup └── readme.md ├── Practical Data Science with R └── readme.md ├── PracticalAtdd └── Readme.md ├── Preparing for This Augmented Life └── readme.md ├── Programmers dont have to suck at UX and UI └── readme.md ├── README.md ├── React Everywhere └── readme.md ├── Real-time Server Telemetry-The downfall of logging and rise of data pipelines └── readme.md ├── Rules as an Architectural Pattern For Development └── readme.md ├── SQL Server Perfomance Tuning └── readme.md ├── Scale Your Node Application Skip the Infrastructure └── readme.md ├── Shiny Lets Be Bad Guys └── readme.md ├── Sowing-Seeds-of-STEM-thru-TechnoFashion ├── README.md └── Sowing the Seeds of STEM Through Techno-Fashion.pdf ├── Style Guides └── readme.md ├── Taming the JavaScript Dragon with TypeScript └── readme.md ├── Testing at the boundaries - using Consumer Driven Contracts to keep your microservices in sync └── README.md ├── The Evolution of Memory and Resource Management ├── Memory-and-Resource-Management-Slides.pdf └── readme.md ├── The Mindful Developer └── readme.md ├── The Rust Language - Memory, Ownership and Lifetimes ├── Rust-Language-Slides.pdf └── readme.md ├── Threat Modeling For Secure Software Design └── readme.md ├── Tips and Tricks for Testing Lambda Expressions in Android └── readme.md ├── Toward a Better Front-end Architecture Elm └── readme.md ├── What are Observables and why should I care └── readme.md ├── [KidzMash] You put the Object in, you take the Object out, … and you shake it all about. └── KidzMash2017-OOP.pdf ├── electron-desktop-development-for-web-developers ├── Electron Desktop Development for Web Developers.pptx └── Readme.md └── stranger-streams-howto-rxandroid └── readme.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "electron-desktop-development-for-web-developers/electron-demo"] 2 | path = electron-desktop-development-for-web-developers/electron-demo 3 | url = https://github.com/cwoodruff/electron-demo.git 4 | [submodule "electron-desktop-development-for-web-developers/electron-react-demo"] 5 | path = electron-desktop-development-for-web-developers/electron-react-demo 6 | url = https://github.com/cwoodruff/electron-react-demo.git 7 | [submodule "electron-desktop-development-for-web-developers/electron-photon-demo"] 8 | path = electron-desktop-development-for-web-developers/electron-photon-demo 9 | url = https://github.com/cwoodruff/electron-photon-demo.git 10 | -------------------------------------------------------------------------------- /0 - Sample/Sample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/0 - Sample/Sample.pdf -------------------------------------------------------------------------------- /0 - Sample/Sample.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/0 - Sample/Sample.pptx -------------------------------------------------------------------------------- /0 - Sample/license.txt: -------------------------------------------------------------------------------- 1 | All content in this directory is under a Creative Commons Attribution-ShareAlike 3.0 Unported License ( http://creativecommons.org/licenses/by-sa/3.0/ ) -------------------------------------------------------------------------------- /0 - Sample/readme.md: -------------------------------------------------------------------------------- 1 | This is the readme for the sample session 2 | ============ 3 | 4 | You can see my blog at http://www.kuemerle.com 5 | 6 | Follow me on Twitter at http://twitter.com/jkuemerle 7 | 8 | 9 | -------------------------------------------------------------------------------- /5 Tips for Cultivating Emotional Intelligence in the Workplace/readme.md: -------------------------------------------------------------------------------- 1 | From [@uckygirliegirl](https://twitter.com/uckygirliegirl) material for [5 Tips for Cultivating Emotional Intelligence in the Workplace](http://christinaaldan.com/5TIPS4EQ/) 2 | -------------------------------------------------------------------------------- /7 Languages in 7 Hours/readme.md: -------------------------------------------------------------------------------- 1 | [Repository](https://github.com/crebma/7-languages) (Note: Contains presentation) 2 | --- 3 | ##### 7 Languages in 7 Hours 4 | * 1/10/17 8:00 am 5 | * Speakers: Amber Conville 6 | * Room: Indigo Bay 7 | * Tags: Other, Ruby/Rails, Testing, Functional Programming 8 | * Category: Pre-Compiler 9 | --- 10 | 11 | Hands-on experience in seven different languages, ranging from object-oriented to functional, from the cozy and familiar to the eye-squintingly terse and foreign. You’ll work through a familiar kata in each of them, showing you how to approach an entirely new language. You’ll learn about the strengths and weaknesses of each language out in the real world. You’ll also see how each language’s quirks can teach us ways to improve the code we write every day. You may not come out of this pre-compiler an expert in all of these languages, but you’ll have learned a lot about how to get started with a new one. You may even discover a new passion! At the very least, the next time a new language comes along, you’ll have the tools you need to tackle it, and enough knowledge to help you push past the “what is this syntax even doing” barrier. Languages: Ruby, Clojure, Haskell, Rust, Scala, Elixir, Go 12 | © 2017 CodeMash Conference, an Ohio Non-Profit Organization 13 | -------------------------------------------------------------------------------- /A Crash Course on Building Microservice-based Architectures/readme.md: -------------------------------------------------------------------------------- 1 | [Repository and Presentation](https://github.com/shawnewallace/choreographed_process) 2 | --- 3 | ##### A Crash Course on Building Microservice-based Architectures 4 | * 1/13/17 12:15 pm 5 | * Speakers: Shawn Wallace 6 | * Room: Zambezi 7 | * Tags: Other 8 | * Category: General Session 9 | --- 10 | 11 | Driven by popular DevOps stories, many large and successful companies are implementing and singing the praises of microservice-based architectures. Is it time for your organization to get on board too? 12 | 13 | In this session, we’ll discuss: 14 | * Why implementing microservice-based architectures is something to consider 15 | * How this approach is different from “traditional” service-oriented architectures 16 | * How microserice-based applications are designed and implemented 17 | * Benefits and possible pitfalls to work around 18 | * Tooling tricks to give you a head start to “predictable” success 19 | 20 | We’ll also talk about topics such as state management, data persistence, transaction support and the role of the enterprise so you can better decide if you should stay with your current process or go forward with a microservice-based architecture. 21 | -------------------------------------------------------------------------------- /A Math-Free Intorduction to Neural Networks/readme.md: -------------------------------------------------------------------------------- 1 | From Slack, material for [A Math-Free Intorduction to Neural Networks](https://www.dropbox.com/s/nt11oo8v4wd9rzb/math-free-neural-nets.pdf?dl=0) 2 | -------------------------------------------------------------------------------- /A Technical Tour of Real-World Web Application Vulnerabilities/readme.md: -------------------------------------------------------------------------------- 1 | From slides of @presidentbeef [A Technical Tour of Real-World Web Application Vulnerabilities](https://docs.google.com/presentation/d/1Yh2ogUE5Z8m0bfy2b5Xr4F4t9d0OaWwlaQHooqY7K4s/pub?start=false&loop=false&delayms=3000&slide=id.p) 2 | 3 | 4 | -------------------------------------------------------------------------------- /A-new-storm-is-brewing-Spring-Data-Flow-Server-for-Kubernetes/license.txt: -------------------------------------------------------------------------------- 1 | All content in this directory is under a Creative Commons Attribution-ShareAlike 3.0 Unported License ( http://creativecommons.org/licenses/by-sa/3.0/ ) -------------------------------------------------------------------------------- /A-new-storm-is-brewing-Spring-Data-Flow-Server-for-Kubernetes/readme.md: -------------------------------------------------------------------------------- 1 | A new storm is brewing: Spring Data Flow Server for Kubernetes 2 | ============ 3 | 4 | This presentation was an introduction / overview to Spring Cloud Data Flow Server 5 | with a demonstration in a local developer environment and a Kubernetes minikube environment. 6 | 7 | [spring-data-flow-CM2017.pdf](spring-data-flow-CM2017.pdf) is a copy of the slides. 8 | 9 | For updated slides and scripts you can go to 10 | [https://github.com/lseinc/intro-spring-data-flow-CM2017](https://github.com/lseinc/intro-spring-data-flow-CM2017). 11 | 12 | Enjoy! 13 | 14 | David D Lucas 15 | @DavidDLucas 16 | 17 | -------------------------------------------------------------------------------- /A-new-storm-is-brewing-Spring-Data-Flow-Server-for-Kubernetes/spring-data-flow-CM2017.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/A-new-storm-is-brewing-Spring-Data-Flow-Server-for-Kubernetes/spring-data-flow-CM2017.pdf -------------------------------------------------------------------------------- /AgileSwift/AgileSwift.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/AgileSwift/AgileSwift.pdf -------------------------------------------------------------------------------- /Asset Template Guides/readme.md: -------------------------------------------------------------------------------- 1 | From [@nicetransition](https://twitter.com/nicetransition) material for [Asset Template Guides](http://nicetransition.com/Kevin-Mack_Asset-Template-Guides_CodeMash-01-12-17.pdf) 2 | -------------------------------------------------------------------------------- /Bash On Ubuntu On Windows/BashOnUbuntuOnWindows.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Bash On Ubuntu On Windows/BashOnUbuntuOnWindows.pptx -------------------------------------------------------------------------------- /Bash On Ubuntu On Windows/README.MD: -------------------------------------------------------------------------------- 1 | # Bash on Ubuntu on Windows # 2 | - 1/12/17 10:30 am 3 | ## Speakers: Paul DeCarlo 4 | - Room: Sagewood, Zebrawood 5 | - Tags: Cloud/Big Data, .NET, Other, JavaScript, Ruby/Rails 6 | - Category: General Session ## 7 | 8 | Windows 10 now provides developers with a familiar Bash environment. This environment will allow users to: 9 | 10 | 11 | 1. Run native Linux binaries including grep, sed, and awk 12 | 2. Navigate a new Linux based file system using these commands 13 | 3. Run bash shell scripts which rely on supported command line utilities 14 | 15 | Windows accomplishes this through the Windows Subsystem for Linux which allows Ubuntu user-mode binaries provided by Canonical to run on Windows 10. This means that the command line utilities are the same as those that run within a native Ubuntu environment. 16 | 17 | In this session we will showcase scripting, code editing / compilation, and execution of X11 apps compiled for Linux using a local X11 server from within the Bash on Ubuntu on Windows environment. 18 | 19 | We will then discuss the implications of these features as they relate to existing developer workflows. This will include a demonstration showcasing compilation of various programs using node.js, python, c++, asp.net, ruby and even a port of the original first person shooter Quake. 20 | 21 | We will also include a demonstration showing how to build and deploy a Ruby based web application from within Visual Studio Code using Bash on Ubuntu on Windows as an integrated terminal. Finally, we will show how to obtain the latest bits for Bash on Ubuntu on Windows that are shipped in the upcoming Windows 10 Anniversary update. -------------------------------------------------------------------------------- /Bedtime Stories/readme.md: -------------------------------------------------------------------------------- 1 | From [@sbastn](https://twitter.com/sbastn) material for [Bedtime Stories](http://yiddish.ninja/bedtime-stories/) 2 | -------------------------------------------------------------------------------- /Beyond the language the importance of algorithms in programming/readme.md: -------------------------------------------------------------------------------- 1 | From [@weppos](https://twitter.com/weppos) material for [Beyond the language: the importance of algorithms in programming](https://slidr.io/weppos/beyond-the-language-the-importance-of-algorithms-codemash-2017#1) 2 | -------------------------------------------------------------------------------- /Big Data == Big Testing/readme.md: -------------------------------------------------------------------------------- 1 | From Slack, material for [Big Data == Big Testing](https://docs.google.com/presentation/d/1uJXcmUO31kdwjaP8IotkGYmuMBIHZ-p6flNXMITNYNg/edit#slide=id.p4) 2 | -------------------------------------------------------------------------------- /Bringing Up Our Future - On Mentoring Junior Developers/Bringing Up Our Future - On Mentoring Junior Developers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Bringing Up Our Future - On Mentoring Junior Developers/Bringing Up Our Future - On Mentoring Junior Developers.pdf -------------------------------------------------------------------------------- /Bringing Up Our Future - On Mentoring Junior Developers/Readme.md: -------------------------------------------------------------------------------- 1 | #### Bringing Up Our Future – On Mentoring Junior Developers 2 | * 1/12/17 4:45 pm 3 | * Speakers: Sarah Dutkiewicz 4 | 5 | --- 6 | While it is one thing to learn from videos or blog posts, it is a different experience when you have someone to turn to that can answer the questions you have when you have them. It makes a world of difference to be able to ask someone "What do they mean when they say "inheritance vs. interfaces'?" When you have someone who forces you to think about what it is you want in life and what steps you may need to take to get there… someone who can make introductions and offer direction… it makes your career and life a little less scary and a lot more manageable. In this session, we will look at some practices that are used by great mentors in the field and learn lessons on how we can be great role models and mentors for our future – junior developers! 7 | -------------------------------------------------------------------------------- /Building Lightsabers Workshop/readme.md: -------------------------------------------------------------------------------- 1 | From [@javajudd](https://twitter.com/javajudd) [slides](https://s3.amazonaws.com/cmj-presentations/lightsabers-codemash-2017.pdf), [worksheet](https://s3.amazonaws.com/cmj-presentations/worksheet-codemash-2017.pdf) and [Instructables](http://www.instructables.com/id/Lightsabers-for-Learning-Basic-Electronics/) for KidzMash Building Lightsabers workshop. 2 | -------------------------------------------------------------------------------- /Building Self-Defending Applications With AppSensor/README.md: -------------------------------------------------------------------------------- 1 | Slides for [Building Self-Defending Applications With AppSensor](http://www.slideshare.net/jtmelton/appsensor-codemash-2017) 2 | 3 | Contact: @_jtmelton on Twitter 4 | -------------------------------------------------------------------------------- /Building Serverless Applications in AWS Workshop/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](https://s3.amazonaws.com/cmj-presentations/serverless-codemash-2017.pdf) 2 | --- 3 | ##### Building Serverless Applications in AWS Workshop 4 | * Date: 1/11/17 1:00 pm 5 | * Speakers: [Christopher Judd](https://twitter.com/javajudd) and [Jarred Olson](https://twitter.com/jarredolson) 6 | * Room: Nile 7 | * Tags: Cloud/Big Data, JavaScript 8 | * Category: Pre-Compiler 9 | ---- 10 | Tired of trying to manage and maintain servers? Never have a large enough operations team? Don’t have a budget for running lots of server? Don’t want to pay for servers siting idle? Afraid you might become so popular that you won’t be able to scale fast enough? Don’t worry, it is possible to alleviate these issues by moving to a serverless architecture that utilizes microservices hosted in the cloud. This type of architecture can support all different types of clients including web, mobile and IoT. During this hands-on workshop, you will build a serverless application utilizing AWS services such as Lambda, API Gateway, S3 and a datastore. 11 | -------------------------------------------------------------------------------- /Building Serverless Software with AWS Lambda/presentation with notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Building Serverless Software with AWS Lambda/presentation with notes.pdf -------------------------------------------------------------------------------- /Building Serverless Software with AWS Lambda/presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Building Serverless Software with AWS Lambda/presentation.pdf -------------------------------------------------------------------------------- /Building Serverless Software with AWS Lambda/readme.md: -------------------------------------------------------------------------------- 1 | [Slides from PittsburgTechFest 2016](https://github.com/PghTechFest/PghTechFest2016/blob/master/building%20serverless%20software%20with%20AWS%20lambda%20-%20Jon%20Knapp.pdf) 2 | [Video from Erie Day of Code 2016](https://www.youtube.com/watch?v=i5hhcZk31t8) 3 | [What Does Lambda Support Reference Site](http://whatdoeslambdasupport.com) 4 | --- 5 | ##### Building “serverless” software with AWS Lambda 6 | * Date: 1/12/17 1:00 pm 7 | * Speakers: Jonathan Knapp 8 | * Room: Indigo Bay 9 | * Tags: Other, JavaScript 10 | * Category: General Session 11 | --- 12 | I was asked to build a fuzzytext search interface for information stored in the SEC’s massive Edgar database which holds all of the electronic documents filed with the SEC. By leveraging managed ElasticSearch, S3 for document storage, and the asynchronous job processing power of AWS Lambda I was able to build a solution that required absolutely no ongoing server maintenance for my client. In this talk I’ll explain how I was able to: – parse gigabytes of info without IP activity restrictions – provide an easy way to scale or disable the application – continuously monitor parsing activity and application health You will learn about the different services I utilized with their strengths and weaknesses as well as alternative services like Iron.io which allows you to write code in many different languages. I’ll also talk about different ways async processing can be applied to other situations such as managing contact forms for static websites as FormKeep does. 13 | -------------------------------------------------------------------------------- /Building a Better Development Shop/Readme.md: -------------------------------------------------------------------------------- 1 | #### Building a Better Development Shop 2 | * 1/13/17 1:30 pm 3 | * Speakers: Eric Wise, The Software Guild 4 | 5 | --- 6 | In a world where "every company is becoming a software company", building and managing a software development team that can consistently deliver value is a key concern for hiring managers and executives. In this presentation we cover the key qualities of good software, discuss research showing why hiring great developers pays big dividends, explore why your hiring process sucks, and cover common traits of high performing teams, and more importantly things in your environment that drive great developers away. Bonus: Most of the recommendations are inexpensive! 7 | -------------------------------------------------------------------------------- /Building a Better Development Shop/TheSoftwareGuild-HowToBuildABetterDevelopmentShop-CodeMash Presentation 1-9-17.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Building a Better Development Shop/TheSoftwareGuild-HowToBuildABetterDevelopmentShop-CodeMash Presentation 1-9-17.pptx -------------------------------------------------------------------------------- /Building failure resistant systems with circuit breakers/Building failure resistant systems with circuit breakers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Building failure resistant systems with circuit breakers/Building failure resistant systems with circuit breakers.pdf -------------------------------------------------------------------------------- /Building failure resistant systems with circuit breakers/Readme.md: -------------------------------------------------------------------------------- 1 | #### Building failure resitant systems with circuit breakers 2 | * 1/13/17 12:15 pm 3 | * Speakers: Stuart Ingram 4 | 5 | --- 6 | Murphy’s law is universal and constant, if something can go wrong it will go wrong, which is especially true of distributed heterogeneous systems. Failures can take many forms from a complete service breakdown to a single latent service causing a cascading catastrophic failure for your users or even intermittent service failures. This talk will discuss how to build resilient, highly available systems utilizing circuit breaker and bulkhead design patterns that help provide service and user guarantees regardless of service QoS breakdowns. See how visualizing the telemetry around service interactions, latency and failures can provide valuable early insights into growing problems before they affect your customers. Learn how Netflix, one of the largest examples of a distributed system, implements these patterns at scale and how you can apply them to your infrastructure big or small. Failure is now an option when implemented the right way! 7 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | dist 4 | *.log 5 | .sass-cache 6 | /index.html 7 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "bitwise": true, 4 | "camelcase": true, 5 | "curly": true, 6 | "eqeqeq": true, 7 | "immed": true, 8 | "indent": 4, 9 | "latedef": true, 10 | "newcap": true, 11 | "noarg": true, 12 | "quotmark": "single", 13 | "undef": true, 14 | "unused": true, 15 | "strict": true, 16 | "trailing": true, 17 | "smarttabs": true, 18 | "white": true 19 | } 20 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-reveal": { 3 | "presentationTitle": "Writing for the PHP Command Line Interface", 4 | "packageVersion": "0.1.0", 5 | "useSass": true, 6 | "deployToGithubPages": true, 7 | "githubUsername": "stevegrunwell", 8 | "githubRepository": "writing-for-php-cli" 9 | } 10 | } -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/Gruntfile.coffee: -------------------------------------------------------------------------------- 1 | # Generated on 2016-04-03 using generator-reveal 0.5.8 2 | module.exports = (grunt) -> 3 | 4 | grunt.initConfig 5 | pkg: grunt.file.readJSON 'package.json' 6 | 7 | watch: 8 | 9 | livereload: 10 | options: 11 | livereload: true 12 | files: [ 13 | 'index.html' 14 | 'slides/{,*/}*.{md,html}' 15 | 'js/*.js' 16 | 'css/*.css' 17 | 'resources/**' 18 | ] 19 | 20 | index: 21 | files: [ 22 | 'templates/_index.html' 23 | 'templates/_section.html' 24 | 'slides/list.json' 25 | ] 26 | tasks: ['buildIndex'] 27 | 28 | coffeelint: 29 | files: ['Gruntfile.coffee'] 30 | tasks: ['coffeelint'] 31 | 32 | jshint: 33 | files: ['js/*.js'] 34 | tasks: ['jshint'] 35 | 36 | sass: 37 | files: ['css/source/theme.scss'] 38 | tasks: ['sass'] 39 | 40 | sass: 41 | 42 | theme: 43 | files: 44 | 'css/theme.css': 'css/source/theme.scss' 45 | 46 | connect: 47 | 48 | livereload: 49 | options: 50 | port: 9001 51 | # Change hostname to '0.0.0.0' to access 52 | # the server from outside. 53 | hostname: 'localhost' 54 | base: '.' 55 | open: true 56 | livereload: true 57 | 58 | coffeelint: 59 | 60 | options: 61 | indentation: 62 | value: 4 63 | max_line_length: 64 | level: 'ignore' 65 | 66 | all: ['Gruntfile.coffee'] 67 | 68 | jshint: 69 | 70 | options: 71 | jshintrc: '.jshintrc' 72 | 73 | all: ['js/*.js'] 74 | 75 | copy: 76 | 77 | dist: 78 | files: [{ 79 | expand: true 80 | src: [ 81 | 'slides/**' 82 | 'bower_components/**' 83 | 'js/**' 84 | 'css/*.css' 85 | 'resources/**' 86 | ] 87 | dest: 'dist/' 88 | },{ 89 | expand: true 90 | src: ['index.html'] 91 | dest: 'dist/' 92 | filter: 'isFile' 93 | }, 94 | { 95 | expand: false 96 | src: ['node_modules/reveal-ga/dist/reveal-ga.min.js'] 97 | dest: 'dist/js/reveal-ga.min.js' 98 | filter: 'isFile' 99 | }] 100 | 101 | 102 | buildcontrol: 103 | 104 | options: 105 | dir: 'dist' 106 | commit: true 107 | push: true 108 | message: 'Built from %sourceCommit% on branch %sourceBranch%' 109 | pages: 110 | options: 111 | remote: '<%= pkg.repository.url %>' 112 | branch: 'gh-pages' 113 | 114 | 115 | 116 | # Load all grunt tasks. 117 | require('load-grunt-tasks')(grunt) 118 | 119 | grunt.registerTask 'buildIndex', 120 | 'Build index.html from templates/_index.html and slides/list.json.', 121 | -> 122 | indexTemplate = grunt.file.read 'templates/_index.html' 123 | sectionTemplate = grunt.file.read 'templates/_section.html' 124 | slides = grunt.file.readJSON 'slides/list.json' 125 | 126 | html = grunt.template.process indexTemplate, data: 127 | slides: 128 | slides 129 | section: (slide) -> 130 | grunt.template.process sectionTemplate, data: 131 | slide: 132 | slide 133 | grunt.file.write 'index.html', html 134 | 135 | grunt.registerTask 'test', 136 | '*Lint* javascript and coffee files.', [ 137 | 'coffeelint' 138 | 'jshint' 139 | ] 140 | 141 | grunt.registerTask 'serve', 142 | 'Run presentation locally and start watch process (living document).', [ 143 | 'buildIndex' 144 | 'sass' 145 | 'connect:livereload' 146 | 'watch' 147 | ] 148 | 149 | grunt.registerTask 'dist', 150 | 'Save presentation files to *dist* directory.', [ 151 | 'test' 152 | 'sass' 153 | 'buildIndex' 154 | 'copy' 155 | ] 156 | 157 | 158 | grunt.registerTask 'deploy', 159 | 'Deploy to Github Pages', [ 160 | 'dist' 161 | 'buildcontrol' 162 | ] 163 | 164 | 165 | # Define default task. 166 | grunt.registerTask 'default', [ 167 | 'test' 168 | 'serve' 169 | ] 170 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/README.md: -------------------------------------------------------------------------------- 1 | # Building for the PHP Command Line Interface 2 | 3 | Executing PHP from the command line enables us to interact with our applications in new and interesting ways: from performing site maintenance to scaffolding new projects, CLI tools like [WP-CLI](http://wp-cli.org/), [Artisan](https://laravel.com/docs/5.1/artisan), and [Drush](http://www.drush.org/en/master/) make it easy to interface with our code without ever opening a browser. 4 | 5 | Attendees will be introduced to popular PHP CLI tools and their default capabilities. We'll discuss characteristics of good CLI scripts, strong use-cases for writing custom commands, then write several CLI programs across different platforms. 6 | 7 | #### [View slides](http://stevegrunwell.github.io/building-for-php-cli) 8 | 9 | This presentation also has [a companion repository, full of executable examples from this presentation](https://github.com/stevegrunwell/php-cli-examples). 10 | 11 | ## Notes and links 12 | 13 | * [Symfony Console Component](http://symfony.com/doc/current/components/console/introduction.html) - Project documentation 14 | * [PHP-CLI Tools](https://github.com/wp-cli/php-cli-tools) - GitHub repository 15 | * [Building PHP Daemons and Long Running Processes](https://prezi.com/pymsnzwlieqt/building-php-daemons-and-long-running-processes-tek15/) - Talk from php[tek] 2015 by [Tim Lytle](http://timlytle.net) 16 | * [Exit Codes with Special Meanings](http://tldp.org/LDP/abs/html/exitcodes.html) - The Linux Documentation Project 17 | * [Understanding Exit Codes and How to Use Them in Bash Scripts](http://bencane.com/2014/09/02/understanding-exit-codes-and-how-to-use-them-in-bash-scripts/) - Article by Benjamin Cane 18 | 19 | ### Platform-specific CLI tools 20 | 21 | * [WP-CLI](http://wp-cli.org/) 22 | * [Laravel Artisan](https://laravel.com/docs/5.1/artisan) 23 | * [Drush](http://www.drush.org/en/master/) 24 | * [Joomlatools Console](https://www.joomlatools.com/developer/tools/console/) 25 | 26 | ## Presentation History 27 | 28 | * [CodeMash 2017](http://www.codemash.org/) - January 13, 2017 29 | * [Nomad PHP (EU)](https://nomadphp.com/nomadphp-2016-12-eu/) – December 15, 2016 ([joind.in](https://joind.in/talk/dce28)) 30 | * [php[tek] 2016](https://tek.phparch.com/speakers/#66432) – May 27, 2016 ([joind.in](https://joind.in/talk/ce9a4)) 31 | * [Columbus PHP Meetup](http://www.meetup.com/phpphp/events/229434721/) – April 13, 2016 ([joind.in](https://joind.in/talk/e9465)) 32 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "writing-for-the-php-command-line-interface", 3 | "version": "0.1.0", 4 | "dependencies": { 5 | "reveal.js": "~3.2.0", 6 | "highlightjs": "~9.0.0" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/css/source/theme.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Black theme for reveal.js. This is the opposite of the 'white' theme. 3 | * 4 | * Copyright (C) 2015 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | // This file has been copied over from 8 | // ../../bower_components/reveal.js/css/theme/source/black.scss 9 | 10 | // See ../../bower_components/reveal.js/css/theme/README.md 11 | // for further explanations on how to create a custom reveal.js theme. 12 | 13 | // Default mixins and settings ----------------- 14 | @import "../../bower_components/reveal.js/css/theme/template/mixins"; 15 | @import "../../bower_components/reveal.js/css/theme/template/settings"; 16 | // --------------------------------------------- 17 | 18 | 19 | // Include theme-specific fonts 20 | @import url(../bower_components/reveal.js/lib/font/source-sans-pro/source-sans-pro.css); 21 | 22 | 23 | // Override theme settings (see ../../bower_components/reveal.js/css/theme/template/settings.scss) 24 | $backgroundColor: #222; 25 | 26 | $mainColor: #fff; 27 | $headingColor: #fff; 28 | 29 | $mainFontSize: 38px; 30 | $mainFont: 'Source Sans Pro', Helvetica, sans-serif; 31 | $headingFont: 'Source Sans Pro', Helvetica, sans-serif; 32 | $headingTextShadow: none; 33 | $headingLetterSpacing: normal; 34 | $headingTextTransform: uppercase; 35 | $headingFontWeight: 600; 36 | $linkColor: #42affa; 37 | $linkColorHover: lighten( $linkColor, 15% ); 38 | $selectionBackgroundColor: lighten( $linkColor, 25% ); 39 | 40 | $heading1Size: 2.5em; 41 | $heading2Size: 1.6em; 42 | $heading3Size: 1.3em; 43 | $heading4Size: 1.0em; 44 | 45 | section.has-light-background { 46 | &, h1, h2, h3, h4, h5, h6 { 47 | color: #222; 48 | } 49 | } 50 | 51 | // Theme template ------------------------------ 52 | @import "../../bower_components/reveal.js/css/theme/template/theme"; 53 | // --------------------------------------------- 54 | 55 | .slides { 56 | 57 | h2, h3, h4, h5, h6 { 58 | code { 59 | text-transform: none; 60 | } 61 | } 62 | 63 | cite { 64 | display: block; 65 | margin-top: 1em; 66 | font-size: .8em; 67 | } 68 | 69 | .slides-link { 70 | display: block; 71 | margin-top: 1em; 72 | font-size: .86em; 73 | white-space: nowrap; 74 | + .slides-link { 75 | margin-top: 0; 76 | } 77 | } 78 | 79 | .speaker-headshot { 80 | display: inline-block; 81 | vertical-align: middle; 82 | max-width: 15%; 83 | margin-top: 2em; 84 | margin-right: 1em; 85 | transform: rotate(-8deg); 86 | } 87 | 88 | dd + dt { 89 | margin-top: 1em; 90 | } 91 | } -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/css/theme.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Black theme for reveal.js. This is the opposite of the 'white' theme. 3 | * 4 | * Copyright (C) 2015 Hakim El Hattab, http://hakim.se 5 | */ 6 | @import url(../bower_components/reveal.js/lib/font/source-sans-pro/source-sans-pro.css); 7 | section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 { 8 | color: #222; } 9 | 10 | /********************************************* 11 | * GLOBAL STYLES 12 | *********************************************/ 13 | body { 14 | background: #222; 15 | background-color: #222; } 16 | 17 | .reveal { 18 | font-family: "Source Sans Pro", Helvetica, sans-serif; 19 | font-size: 38px; 20 | font-weight: normal; 21 | color: #fff; } 22 | 23 | ::selection { 24 | color: #fff; 25 | background: #bee4fd; 26 | text-shadow: none; } 27 | 28 | .reveal .slides > section, 29 | .reveal .slides > section > section { 30 | line-height: 1.3; 31 | font-weight: inherit; } 32 | 33 | /********************************************* 34 | * HEADERS 35 | *********************************************/ 36 | .reveal h1, 37 | .reveal h2, 38 | .reveal h3, 39 | .reveal h4, 40 | .reveal h5, 41 | .reveal h6 { 42 | margin: 0 0 20px 0; 43 | color: #fff; 44 | font-family: "Source Sans Pro", Helvetica, sans-serif; 45 | font-weight: 600; 46 | line-height: 1.2; 47 | letter-spacing: normal; 48 | text-transform: uppercase; 49 | text-shadow: none; 50 | word-wrap: break-word; } 51 | 52 | .reveal h1 { 53 | font-size: 2.5em; } 54 | 55 | .reveal h2 { 56 | font-size: 1.6em; } 57 | 58 | .reveal h3 { 59 | font-size: 1.3em; } 60 | 61 | .reveal h4 { 62 | font-size: 1em; } 63 | 64 | .reveal h1 { 65 | text-shadow: none; } 66 | 67 | /********************************************* 68 | * OTHER 69 | *********************************************/ 70 | .reveal p { 71 | margin: 20px 0; 72 | line-height: 1.3; } 73 | 74 | /* Ensure certain elements are never larger than the slide itself */ 75 | .reveal img, 76 | .reveal video, 77 | .reveal iframe { 78 | max-width: 95%; 79 | max-height: 95%; } 80 | 81 | .reveal strong, 82 | .reveal b { 83 | font-weight: bold; } 84 | 85 | .reveal em { 86 | font-style: italic; } 87 | 88 | .reveal ol, 89 | .reveal dl, 90 | .reveal ul { 91 | display: inline-block; 92 | text-align: left; 93 | margin: 0 0 0 1em; } 94 | 95 | .reveal ol { 96 | list-style-type: decimal; } 97 | 98 | .reveal ul { 99 | list-style-type: disc; } 100 | 101 | .reveal ul ul { 102 | list-style-type: square; } 103 | 104 | .reveal ul ul ul { 105 | list-style-type: circle; } 106 | 107 | .reveal ul ul, 108 | .reveal ul ol, 109 | .reveal ol ol, 110 | .reveal ol ul { 111 | display: block; 112 | margin-left: 40px; } 113 | 114 | .reveal dt { 115 | font-weight: bold; } 116 | 117 | .reveal dd { 118 | margin-left: 40px; } 119 | 120 | .reveal q, 121 | .reveal blockquote { 122 | quotes: none; } 123 | 124 | .reveal blockquote { 125 | display: block; 126 | position: relative; 127 | width: 70%; 128 | margin: 20px auto; 129 | padding: 5px; 130 | font-style: italic; 131 | background: rgba(255, 255, 255, 0.05); 132 | box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } 133 | 134 | .reveal blockquote p:first-child, 135 | .reveal blockquote p:last-child { 136 | display: inline-block; } 137 | 138 | .reveal q { 139 | font-style: italic; } 140 | 141 | .reveal pre { 142 | display: block; 143 | position: relative; 144 | width: 90%; 145 | margin: 20px auto; 146 | text-align: left; 147 | font-size: 0.55em; 148 | font-family: monospace; 149 | line-height: 1.2em; 150 | word-wrap: break-word; 151 | box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } 152 | 153 | .reveal code { 154 | font-family: monospace; } 155 | 156 | .reveal pre code { 157 | display: block; 158 | padding: 5px; 159 | overflow: auto; 160 | max-height: 400px; 161 | word-wrap: normal; } 162 | 163 | .reveal table { 164 | margin: auto; 165 | border-collapse: collapse; 166 | border-spacing: 0; } 167 | 168 | .reveal table th { 169 | font-weight: bold; } 170 | 171 | .reveal table th, 172 | .reveal table td { 173 | text-align: left; 174 | padding: 0.2em 0.5em 0.2em 0.5em; 175 | border-bottom: 1px solid; } 176 | 177 | .reveal table th[align="center"], 178 | .reveal table td[align="center"] { 179 | text-align: center; } 180 | 181 | .reveal table th[align="right"], 182 | .reveal table td[align="right"] { 183 | text-align: right; } 184 | 185 | .reveal table tr:last-child td { 186 | border-bottom: none; } 187 | 188 | .reveal sup { 189 | vertical-align: super; } 190 | 191 | .reveal sub { 192 | vertical-align: sub; } 193 | 194 | .reveal small { 195 | display: inline-block; 196 | font-size: 0.6em; 197 | line-height: 1.2em; 198 | vertical-align: top; } 199 | 200 | .reveal small * { 201 | vertical-align: top; } 202 | 203 | /********************************************* 204 | * LINKS 205 | *********************************************/ 206 | .reveal a { 207 | color: #42affa; 208 | text-decoration: none; 209 | -webkit-transition: color .15s ease; 210 | -moz-transition: color .15s ease; 211 | transition: color .15s ease; } 212 | 213 | .reveal a:hover { 214 | color: #8dcffc; 215 | text-shadow: none; 216 | border: none; } 217 | 218 | .reveal .roll span:after { 219 | color: #fff; 220 | background: #068de9; } 221 | 222 | /********************************************* 223 | * IMAGES 224 | *********************************************/ 225 | .reveal section img { 226 | margin: 15px 0px; 227 | background: rgba(255, 255, 255, 0.12); 228 | border: 4px solid #fff; 229 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } 230 | 231 | .reveal section img.plain { 232 | border: 0; 233 | box-shadow: none; } 234 | 235 | .reveal a img { 236 | -webkit-transition: all .15s linear; 237 | -moz-transition: all .15s linear; 238 | transition: all .15s linear; } 239 | 240 | .reveal a:hover img { 241 | background: rgba(255, 255, 255, 0.2); 242 | border-color: #42affa; 243 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } 244 | 245 | /********************************************* 246 | * NAVIGATION CONTROLS 247 | *********************************************/ 248 | .reveal .controls .navigate-left, 249 | .reveal .controls .navigate-left.enabled { 250 | border-right-color: #42affa; } 251 | 252 | .reveal .controls .navigate-right, 253 | .reveal .controls .navigate-right.enabled { 254 | border-left-color: #42affa; } 255 | 256 | .reveal .controls .navigate-up, 257 | .reveal .controls .navigate-up.enabled { 258 | border-bottom-color: #42affa; } 259 | 260 | .reveal .controls .navigate-down, 261 | .reveal .controls .navigate-down.enabled { 262 | border-top-color: #42affa; } 263 | 264 | .reveal .controls .navigate-left.enabled:hover { 265 | border-right-color: #8dcffc; } 266 | 267 | .reveal .controls .navigate-right.enabled:hover { 268 | border-left-color: #8dcffc; } 269 | 270 | .reveal .controls .navigate-up.enabled:hover { 271 | border-bottom-color: #8dcffc; } 272 | 273 | .reveal .controls .navigate-down.enabled:hover { 274 | border-top-color: #8dcffc; } 275 | 276 | /********************************************* 277 | * PROGRESS BAR 278 | *********************************************/ 279 | .reveal .progress { 280 | background: rgba(0, 0, 0, 0.2); } 281 | 282 | .reveal .progress span { 283 | background: #42affa; 284 | -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 285 | -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 286 | transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } 287 | 288 | .slides h2 code, .slides h3 code, .slides h4 code, .slides h5 code, .slides h6 code { 289 | text-transform: none; } 290 | 291 | .slides cite { 292 | display: block; 293 | margin-top: 1em; 294 | font-size: .8em; } 295 | 296 | .slides .slides-link { 297 | display: block; 298 | margin-top: 1em; 299 | font-size: .86em; 300 | white-space: nowrap; } 301 | .slides .slides-link + .slides-link { 302 | margin-top: 0; } 303 | 304 | .slides .speaker-headshot { 305 | display: inline-block; 306 | vertical-align: middle; 307 | max-width: 15%; 308 | margin-top: 2em; 309 | margin-right: 1em; 310 | transform: rotate(-8deg); } 311 | 312 | .slides dd + dt { 313 | margin-top: 1em; } 314 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/js/loadhtmlslides.js: -------------------------------------------------------------------------------- 1 | // Modified from markdown.js from Hakim to handle external html files 2 | (function () { 3 | /*jslint loopfunc: true, browser: true*/ 4 | /*globals alert*/ 5 | 'use strict'; 6 | 7 | var querySlidingHtml = function () { 8 | var sections = document.querySelectorAll('[data-html]'), 9 | section, j, jlen; 10 | 11 | for (j = 0, jlen = sections.length; j < jlen; j++) { 12 | section = sections[j]; 13 | 14 | if (section.getAttribute('data-html').length) { 15 | 16 | var xhr = new XMLHttpRequest(), 17 | url = section.getAttribute('data-html'), 18 | cb = function () { 19 | if (xhr.readyState === 4) { 20 | if ( 21 | (xhr.status >= 200 && xhr.status < 300) || 22 | xhr.status === 0 // file protocol yields status code 0 (useful for local debug, mobile applications etc.) 23 | ) { 24 | section.innerHTML = xhr.responseText; 25 | } else { 26 | section.outerHTML = '
ERROR: The attempt to fetch ' + url + ' failed with the HTTP status ' + xhr.status + '. Check your browser\'s JavaScript console for more details.

'; 27 | } 28 | } 29 | }; 30 | 31 | xhr.onreadystatechange = cb; 32 | 33 | xhr.open('GET', url, false); 34 | try { 35 | xhr.send(); 36 | } catch (e) { 37 | alert('Failed to get file' + url + '.' + e); 38 | } 39 | } 40 | } 41 | }; 42 | 43 | querySlidingHtml(); 44 | })(); 45 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "writing-for-the-php-command-line-interface", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "coffeelint": "^1.0.0", 7 | "grunt": "^0.4.5", 8 | "grunt-build-control": "^0.5.0", 9 | "grunt-coffeelint": "0.0.13", 10 | "grunt-contrib-connect": "^0.10.1", 11 | "grunt-contrib-copy": "^0.8.0", 12 | "grunt-contrib-jshint": "^0.11.2", 13 | "grunt-contrib-watch": "^0.6.1", 14 | "grunt-sass": "^1.1.0", 15 | "load-grunt-tasks": "^3.2.0", 16 | "node-sass": "^4.2.0" 17 | }, 18 | "engines": { 19 | "node": ">=0.10.0", 20 | "npm": ">=1.3.7" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git@github.com:stevegrunwell/building-for-php-cli.git" 25 | }, 26 | "scripts": { 27 | "test": "grunt test" 28 | }, 29 | "dependencies": { 30 | "reveal-ga": "^0.1.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/resources/.gitkeep: -------------------------------------------------------------------------------- 1 | Used to store static assets -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/resources/emily.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Building for the PHP Command Line Interface/resources/emily.jpg -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/resources/tim-lytle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Building for the PHP Command Line Interface/resources/tim-lytle.jpg -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/about-me.md: -------------------------------------------------------------------------------- 1 | ## Who am I? 2 | 3 | * Director of Technology @ [Growella](https://growella.com) 4 | * Open-source contributor 5 | * Husband + (new) father 6 | * Coffee roaster 7 | 8 | Note: 9 | 10 | New media site covering topics in life, career, and money. 11 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/argc.md: -------------------------------------------------------------------------------- 1 | ### `$argc` 2 | 3 | * Returns the number of arguments passed to a script. 4 | * The script name will be included, so this number should always be >= 1 5 | 6 | Note: 7 | 8 | ARGument Count -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/args.md: -------------------------------------------------------------------------------- 1 | ### Using `$argc` and `$argv` 2 | 3 | ```php 4 | # ArgExample.php 5 | printf('There were %d arguments passed to PHP:' . PHP_EOL, $argc); 6 | print_r($argv); 7 | ``` 8 | 9 | ```sh 10 | $ php ArgExample.php abc 123 11 | ``` 12 | 13 | 14 | ```sh 15 | There were 3 arguments passed to PHP: 16 | Array 17 | ( 18 | [0] => ArgExample.php 19 | [1] => abc 20 | [2] => 123 21 | ) 22 | ``` 23 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/argv.md: -------------------------------------------------------------------------------- 1 | ### `$argv` 2 | 3 | * Retrieves the arguments passed to the PHP script as an array. 4 | * The script name will be included, so this array should never be empty. 5 | 6 | Note: 7 | 8 | ARGument Values -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/artisan.md: -------------------------------------------------------------------------------- 1 | ### Artisan 2 | 3 | [laravel.com](https://laravel.com/docs/5.2/artisan) 4 | 5 | * The underlying CLI for Laravel 6 | * Scaffold new models, views, controllers, seeds, and more 7 | * Built atop the Symfony Console 8 | * Enables third-party packages to register new commands 9 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/benefits.md: -------------------------------------------------------------------------------- 1 | ### Benefits 2 | 3 | * No reliance on the browser 4 | * Publicly-discoverable interfaces 5 | * Timeouts 6 | * Script using the same libraries as your application 7 | * PHP developers don't *have* to learn Bash 8 | ```php 9 | #!/usr/bin/env php 10 | Developers should write programs that can communicate easily with other programs. This rule aims to allow developers to break down projects into small, simple programs rather than overly complex monolithic programs. 4 | 5 | Eric S. Raymond, [*The Art of Unix Programming*](https://en.wikipedia.org/wiki/The_Art_of_Unix_Programming) 6 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/daemons.md: -------------------------------------------------------------------------------- 1 | ### Daemons 2 | 3 | A process that continually runs in the background 4 | 5 | ```php 6 | while ( $run ) { 7 | // do something! 8 | } 9 | ``` 10 | 11 | [![Tim Lytle](resources/tim-lytle.jpg) bit.ly/1S0RwGw](https://prezi.com/pymsnzwlieqt/building-php-daemons-and-long-running-processes-tek15/#) -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/dont-assume-anything.md: -------------------------------------------------------------------------------- 1 | ### Don't assume anything! 2 | 3 | * Your script could be run on a wide variety of systems 4 | * Check that system commands work before calling them 5 | 6 | Note: 7 | 8 | This could mean system libraries, PHP extensions, or other dependencies. 9 | 10 | PHP can run in a lot of environments, so you can never be too careful! 11 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/drush.md: -------------------------------------------------------------------------------- 1 | ### Drush 2 | 3 | [drush.org](http://www.drush.org/en/master/) 4 | 5 | * Short for "Drupal Shell" 6 | * One of the OG CLI tools for PHP CMSs 7 | * Manage themes, modules, system updates, etc. 8 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/emily.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/environment-variables.md: -------------------------------------------------------------------------------- 1 | ### Environment Variables 2 | 3 | ```php 4 | $name = getenv('DEMO_NAME'); 5 | 6 | if ($name) { 7 | printf('Hey, I recognize you, %s!' . PHP_EOL, $name); 8 | $name = sprintf('My old friend, %s!', $name); 9 | 10 | } else { 11 | echo "I don't know you, so I'll just call you Fred." . PHP_EOL; 12 | $name = 'Fred'; 13 | } 14 | 15 | // Update DEMO_NAME and call the system's echo program. 16 | putenv('DEMO_NAME=' . $name); 17 | passthru('echo $DEMO_NAME'); 18 | ``` 19 | 20 | Note: 21 | 22 | Another neat trick is the ability to access environment variables from within your PHP script. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/environment-variables2.md: -------------------------------------------------------------------------------- 1 | ### Environment Variables 2 | 3 | `export DEMO_NAME="Steve"` 4 | ```html 5 | > Hey, I recognize you, Steve! 6 | > My old friend, Steve! 7 | ``` 8 | 9 |
Otherwise: 10 | ```html 11 | > I don't know you, so I'll just call you Fred. 12 | > Fred 13 | ``` 14 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/escapeshellcmd.md: -------------------------------------------------------------------------------- 1 | #### `escapeshellcmd()` 2 | 3 | *Escapes any meta-characters that could be used to execute arbitrary commands* 4 | 5 | 6 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/escaping-arguments.md: -------------------------------------------------------------------------------- 1 | #### `escapeshellarg()` 2 | 3 | ```php 4 | $name = 'steve && rm -rf /'; 5 | 6 | # Oh no, $name isn't being escaped! 7 | exec('greet-user ' . $name); 8 | ``` 9 | 10 | ```php 11 | > Hello, steve # proceeded by your system being destroyed 12 | ``` 13 | 14 | 15 |
16 | ```php 17 | $name = 'steve && rm -rf /'; 18 | 19 | # Nice try, user! 20 | exec('greet-user ' . escapeshellarg($name)); 21 | ``` 22 | 23 | 24 | ```php 25 | > Hello, steve && rm -rf / # What an odd name! 26 | ``` 27 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/escaping-shell-commands.md: -------------------------------------------------------------------------------- 1 | ### Escaping shell commands 2 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/example-symfony-console.md: -------------------------------------------------------------------------------- 1 | ### Symfony Console 2 | 3 | ```php 4 | setName('symfony-example') 12 | ->setDescription('Greet a user by name.') 13 | ->addArgument( 14 | 'name', 15 | InputArgument::REQUIRED, 16 | 'The name of the user' 17 | ); 18 | } 19 | ``` 20 | 21 | Note: 22 | 23 | The configure method defines what our command looks like: 24 | 25 | Its name, description, and arguments are defined here. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/example-symfony-console3.md: -------------------------------------------------------------------------------- 1 | ### Symfony Console 2 | 3 | ```php 4 | /** 5 | * Execute the command. 6 | * 7 | * @param InputInterface $input The input interface. 8 | * @param OutputInterface $output The output interface. 9 | */ 10 | protected function execute($input, $output) 11 | { 12 | $output->writeln(sprintf( 13 | 'Symfony says "hello", %s!', 14 | $input->getArgument('name') 15 | )); 16 | } 17 | ``` 18 | 19 | Note: 20 | 21 | The execute() method defines what happens when someone runs the command. 22 | 23 | We receive two interfaces, one for input and one for output, which give us ways to handle data. 24 | 25 | In this case, we're printing a line that will get colored by the console that greets the user. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/example-symfony-console4.md: -------------------------------------------------------------------------------- 1 | ### Symfony Console 2 | 3 | ```sh 4 | $ php examples/SymfonyExample.php symfony-example Steve 5 | ``` 6 | 7 | ```sh 8 | > Symfony says "hello", Steve! 9 | ``` 10 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/examples.md: -------------------------------------------------------------------------------- 1 | ## Examples 2 | 3 | [github.com/stevegrunwell/php-cli-examples](https://github.com/stevegrunwell/php-cli-examples) 4 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/exit-codes.md: -------------------------------------------------------------------------------- 1 | ### Exit codes 2 | 3 | * The *way* we exit scripts is significant: 4 | * `0` = successful 5 | * `1` = error 6 | * Additional values between 2-255 have special meanings in *nix 7 | * If no exit status is provided, scripts will exit with the status of the last command run -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/exit-codes2.md: -------------------------------------------------------------------------------- 1 | ### Exit codes 2 | 3 | ```php 4 | if (! isset($argv['1'])) { 5 | echo "Missing required argument!"; 6 | exit(1); 7 | } 8 | 9 | // Do something awesome 10 | ``` 11 | 12 | ```sh 13 | $ php my-script.php foo && echo "Success" 14 | $ php my-script.php && echo "You will never see this" 15 | ``` 16 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/garbage-collection.md: -------------------------------------------------------------------------------- 1 | ### Garbage Collection 2 | 3 | * Unset objects when they're no longer necessary 4 | * Be judicious with caching 5 | * Watch the size of arrays that are constantly growing 6 | 7 | Note: 8 | 9 | The garbage collector frees up memory that was previously allocated but no longer needed. 10 | 11 | Not something PHP developers normally have to worry about, because it gets cleaned up for us automatically at the end of each request. 12 | 13 | You can help the garbage collector by explicitly saying "I'm done with this" by using unset(). 14 | 15 | Try to cache values in variables whenever possible, but be careful about how big those caches get; if you're running something in a big loop, consider null-ing out that variable after a certain number of iterations. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/getopt.md: -------------------------------------------------------------------------------- 1 | ### `getopt()` 2 | 3 | ```php 4 | var_dump(getopt( 5 | 'a:b', 6 | array('foo:', 'verbose') 7 | )); 8 | ``` 9 | 10 | ```bash 11 | $ myscript -a=hello -b --foo=bar --verbose 12 | 13 | array(4) { 14 | 'a' => 15 | string(5) "hello" 16 | 'b' => 17 | bool(false) 18 | 'foo' => 19 | string(3) "bar" 20 | 'verbose' => 21 | bool(false) 22 | } 23 | ``` 24 | 25 | 26 | Note: 27 | 28 | PHP also has the getopt() function for retrieving options passed via the CLI, though I'll admit it's not the prettiest syntax. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/how-does-it-run.md: -------------------------------------------------------------------------------- 1 | ### How does it run? 2 | 3 | Two ways to invoke PHP on the CLI: 4 | 5 | ```sh 6 | # 1. Pass the file to the php binary 7 | $ php my-command.php 8 | ``` 9 | 10 | 11 | ```sh 12 | # 2. Execute the file directly if using the php shebang. 13 | $ chmod +x my-command.php 14 | $ ./my-command.php 15 | ``` 16 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/in-the-wild.md: -------------------------------------------------------------------------------- 1 | ## In the Wild 2 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/index.md: -------------------------------------------------------------------------------- 1 | # Building for the PHP Command Line Interface 2 | 3 | Steve Grunwell
4 | [@stevegrunwell](https://twitter.com/stevegrunwell) 5 | 6 | [stevegrunwell.com/slides/php-cli](https://stevegrunwell.com/slides/php-cli) 7 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/joomla-console.md: -------------------------------------------------------------------------------- 1 | ### Joomla Console 2 | 3 | [joomlatools.com/developer/tools/console](https://www.joomlatools.com/developer/tools/console/) 4 | 5 | * CLI framework for Joomla! 6 | * Manage Sites, Extensions, Databases, and Apache vhosts 7 | * List, purge, and clear cache contents -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "index.md", 3 | [ 4 | "about-me.md", 5 | "emily.md" 6 | ], 7 | [ 8 | "why-the-cli.md", 9 | "benefits.md", 10 | "how-does-it-run.md", 11 | "when-might-i-use-them.md" 12 | ], 13 | [ 14 | "best-practices.md", 15 | "composability.md", 16 | "composability2.md", 17 | "dont-assume-anything.md", 18 | "php-sapi.md", 19 | "verbosity.md", 20 | "garbage-collection.md" 21 | ], 22 | [ 23 | "in-the-wild.md", 24 | "drush.md", 25 | "wp-cli.md", 26 | "artisan.md", 27 | "joomla-console.md" 28 | ], 29 | [ 30 | "writing-your-own-scripts.md", 31 | "symfony-console.md", 32 | "php-cli-tools.md", 33 | "types-of-arguments.md", 34 | "argv.md", 35 | "argc.md", 36 | "args.md", 37 | "getopt.md", 38 | "system-commands.md", 39 | "system-commands2.md", 40 | "system-commands3.md", 41 | "escaping-shell-commands.md", 42 | "escapeshellcmd.md", 43 | "escaping-arguments.md", 44 | "environment-variables.md", 45 | "environment-variables2.md", 46 | "exit-codes.md", 47 | "exit-codes2.md", 48 | "daemons.md" 49 | ], 50 | [ 51 | "examples.md", 52 | "example-symfony-console.md", 53 | "example-symfony-console2.md", 54 | "example-symfony-console3.md", 55 | "example-symfony-console4.md", 56 | "php-cli-tools-example.md", 57 | "php-cli-tools-example2.md", 58 | "wp-cli-example.md", 59 | "wp-cli-example2.md", 60 | "wp-cli-example3.md", 61 | "wp-cli-example4.md" 62 | ], 63 | "thank-you.md" 64 | ] -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/php-cli-tools-example.md: -------------------------------------------------------------------------------- 1 | ### PHP-CLI Tools 2 | 3 | ```php 4 | #!/usr/bin/env php 5 | 18 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/php-cli-tools.md: -------------------------------------------------------------------------------- 1 | ### PHP-CLI Tools 2 | 3 | * Functions to handle input and output, including progress indicators 4 | * Tabular and Tree displays for output 5 | * Maintained by the WP-CLI team 6 | 7 | [github.com/wp-cli/php-cli-tools](https://github.com/wp-cli/php-cli-tools) -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/php-sapi.md: -------------------------------------------------------------------------------- 1 | ### Know the current Server API 2 | 3 | Scripts can use `php_sapi_name()` (or the `PHP_SAPI` constant) to determine the Server API being used. 4 | 5 | ```php 6 | // Make sure this script is being run over the PHP CLI! 7 | if ('cli' !== php_sapi_name()) { 8 | return; 9 | } 10 | ``` 11 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/symfony-console.md: -------------------------------------------------------------------------------- 1 | ### Symfony Console Component 2 | 3 | * Robust library for writing PHP CLI scripts 4 | * Helpers for all sorts of input and output options 5 | * Designed to be easily tested 6 | * Integrates with other Symfony components (naturally) 7 | 8 | [symfony.com/doc/current/components/console](http://symfony.com/doc/current/components/console/index.html) -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/system-commands.md: -------------------------------------------------------------------------------- 1 | ### System commands 2 | 3 | * PHP can natively do a lot of common Unix operations: [`copy`](http://us3.php.net/manual/en/function.copy.php), [`chmod`](http://us3.php.net/manual/en/function.chmod.php), [`chown`](http://us3.php.net/manual/en/function.chown.php), etc. 4 | * Can also execute arbitrary system operations! -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/system-commands2.md: -------------------------------------------------------------------------------- 1 | #### Executing System Commands 2 | 3 |
4 |
exec()
5 |
Returns the last line of output as a string.
6 |
shell_exec()
7 |
returns full output as a string.
8 |
Can also be represented using the backtick operator: 9 |
\`ls -al` === shell_exec('ls -al')
10 |
11 |
12 | 13 | 14 | Note: 15 | 16 | If you require multiple lines of output, use shell_exec() 17 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/system-commands3.md: -------------------------------------------------------------------------------- 1 | #### (Even More) System Commands 2 | 3 |
4 |
system()
5 |
Flush the output buffer after each line
6 |
passthru()
7 |
Returns the raw output.
8 |
Great for working with binary files or interactive output
9 |
10 | 11 | 12 | Note: 13 | 14 | A very practical use-case for passthru(): using tools like Gifsicle to resize animated gifs uploaded to your app. 15 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/thank-you.md: -------------------------------------------------------------------------------- 1 | ## Thank You! 2 | 3 | Steve Grunwell
4 | [stevegrunwell.com](https://stevegrunwell.com)
5 | [growella.com](https://growella.com) 6 | 7 | [stevegrunwell.com/slides/php-cli](https://stevegrunwell.com/slides/php-cli) 8 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/types-of-arguments.md: -------------------------------------------------------------------------------- 1 | ### Types of input 2 | 3 | [Positional] Arguments 4 | 5 | ``` 6 | $ my-command foo bar 7 | ``` 8 | 9 | 10 | Options ("associative args") 11 | 12 | ``` 13 | $ my-command -n=100 --type foo --verbose 14 | ``` 15 | 16 | 17 | Note: 18 | 19 | Important to establish common language before we go further around accepting input: 20 | 21 | Args (or "positional args") are passed in a specific order to the command 22 | 23 | Options (sometimes called "associate args", but that's not really correct) have one or two dashes before them and either act as key:value pairs or as flags (such as --verbose) 24 | 25 | Single dash/letter is a convention. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/verbosity.md: -------------------------------------------------------------------------------- 1 | ### Rule of Silence 2 | 3 | > Developers should design programs so that they do not print unnecessary output. This rule aims to allow other programs and developers to pick out the information they need from a program's output without having to parse verbosity. 4 | 5 | Eric S. Raymond, [*The Art of Unix Programming*](https://en.wikipedia.org/wiki/The_Art_of_Unix_Programming) 6 | 7 | Note: 8 | 9 | The amount of output will vary depending on the purpose of your script; a major platform migration might call for very detailed output, while a maintenance script may only need to print something if there was an error. 10 | 11 | Know your audience, and only print the bare minimum by default. Use options like --verbose for when users need more. 12 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/when-might-i-use-them.md: -------------------------------------------------------------------------------- 1 | ### When might I use them? 2 | 3 | * Data migrations and transformations 4 | * Maintenance scripts 5 | * Actions that should only be available via a console 6 | * Scaffolding 7 | * Other code changes 8 | * "#YOLO scripts" 9 | 10 | Note: 11 | 12 | Other code changes like schema updates, table seeding, etc. 13 | 14 | YOLO scripts = scripts you're only going to run once (or a small number) of times. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/why-the-cli.md: -------------------------------------------------------------------------------- 1 | ## Why the CLI? 2 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/wp-cli-example.md: -------------------------------------------------------------------------------- 1 | ### WP-CLI: Register Command 2 | 3 | ```php 4 | /** 5 | * Example WP-CLI script. 6 | */ 7 | class Example_WP_CLI_Command extends WP_CLI_Command { 8 | // At least one public method. 9 | } 10 | 11 | WP_CLI::add_command( 'example-command', 'Example_WP_CLI_Command' ); 12 | ``` 13 | 14 | Note: 15 | 16 | Looking at WP-CLI commands, they're registered using the WP_CLI::add_command() method. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/wp-cli-example2.md: -------------------------------------------------------------------------------- 1 | ### WP-CLI: Command Definition 2 | 3 | ```php 4 | /** 5 | * Display the latest posts from a given user. 6 | * 7 | * ## OPTIONS 8 | * 9 | * 10 | * : The user login to collect stats for. 11 | * 12 | * @subcommand latest-posts-by-user 13 | */ 14 | public function latest_posts_by_user( $args, $assoc_args ) { 15 | // Do something! 16 | } 17 | ``` 18 | 19 | Note: 20 | 21 | Each command is given a DocBlock, which defines the available arguments, provides examples, and lets us use some other DocBlock tags like @subcommand. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/wp-cli-example3.md: -------------------------------------------------------------------------------- 1 | ### WP-CLI: Command Method 2 | 3 | ```php 4 | public function latest_posts_by_user( $args, $assoc_args ) { 5 | $user = get_user_by( 'login', $args['0'] ); 6 | if ( ! $user ) { 7 | return WP_CLI::error( 8 | 'The specified user login does not exist!' 9 | ); 10 | } 11 | 12 | $posts = get_posts( array( 'author' => $user->ID ) ); 13 | $fields = array( 'ID', 'post_title', 'post_date' ); 14 | 15 | return WP_CLI\Utils\format_items( 'table', $posts, $fields ); 16 | } 17 | ``` 18 | 19 | Note: 20 | 21 | Inside the function, we have two arguments: $args and $assoc_args 22 | 23 | $args contains the positional arguments. 24 | 25 | $assoc_args contains the associative arguments. 26 | 27 | WP-CLI also has some nice formatters, like format_items(), which will let us generate an ASCII table. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/wp-cli-example4.md: -------------------------------------------------------------------------------- 1 | ### WP-CLI: In Action 2 | 3 | ```sh 4 | $ wp example-command latest-posts-by-user admin 5 | ``` 6 | 7 | ``` 8 | +-----+---------------+---------------------+ 9 | | ID | post_title | post_date | 10 | +-----+---------------+---------------------+ 11 | | 7 | A third post | 2016-04-08 14:32:00 | 12 | | 5 | Another post | 2016-04-05 18:32:23 | 13 | | 1 | Hello World! | 2015-11-12 01:14:38 | 14 | +-----+---------------+---------------------+ 15 | ``` 16 | 17 | 18 | Note: 19 | 20 | When you're working on the CLI, it's really great to be able to see data like this. 21 | 22 | What's even nicer is that if we pipe this to something else or save it down to a file, it automatically treats the data as a CSV. This is just a great example of composability. -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/wp-cli.md: -------------------------------------------------------------------------------- 1 | ### WP-CLI 2 | 3 | [wp-cli.org](http://wp-cli.org/) 4 | 5 | * Install core, themes, plugins, etc. 6 | * Manage posts, terms, users, and more 7 | * Inspect and maintain cron, caches, and transients 8 | * Extensible for themes + plugins 9 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/slides/writing-your-own-scripts.md: -------------------------------------------------------------------------------- 1 | ## Writing your own scripts 2 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/templates/_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Building for the PHP Command Line Interface 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 30 | 31 | 34 | 35 | 36 | 37 | 38 |
39 | 40 |
41 | 42 | <% _.forEach(slides, function(slide) { %> 43 | <% if (!_.isArray(slide)) { %> 44 | <%= section(slide) %> 45 | <% } %> 46 | <% if (_.isArray(slide)) { %> 47 |
48 | <% _.forEach(slide, function(verticalslide) { %> 49 | <%= section(verticalslide) %> 50 | <% }); %> 51 |
52 | <% } %> 53 | <% }); %> 54 |
55 | 56 |
57 | 58 | 59 | 60 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Building for the PHP Command Line Interface/templates/_section.html: -------------------------------------------------------------------------------- 1 | <% if (!_.isString(slide) && !_.isArray(slide) && _.isObject(slide)) { %> 2 |
<% if (_.isString(slide.filename)) { %>data-<% if (slide.filename.indexOf('.html') !== -1) { %>html<% } else { %>markdown<% }%>="slides/<%= slide.filename %>"<% } %>>
3 | <% } %><% if (_.isString(slide)) { %> 4 |
html<% } else { %>markdown<% }%>="slides/<%= slide %>">
5 | <% } %> 6 | -------------------------------------------------------------------------------- /Caching Made Bootiful/readme.md: -------------------------------------------------------------------------------- 1 | From [@gAmUssA](https://twitter.com/gAmUssA) material for [Caching Made Bootiful](http://next.javaheadbrain.com/posts/2017/01/12/codemash-2017.html) 2 | -------------------------------------------------------------------------------- /Can I Build a 12-Factor App in .Net/Can I Build a 12-Factor App in .Net.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Can I Build a 12-Factor App in .Net/Can I Build a 12-Factor App in .Net.pptx -------------------------------------------------------------------------------- /Chipping away at the monolith with Go/demos/README.md: -------------------------------------------------------------------------------- 1 | # Resources for "Chipping Away at the Monolith with Go" 2 | Items in this repository are a companion to the talk "Chipping Away at the Monolith with Go" that was given at CodeMash 2017 on January 12, 2017 at 9:15 AM at the Kalahari Resort in Sandusky, OH. 3 | 4 | ## Demo Code 5 | All of the programs can be run by going into the directory and issuing the following command: `go run main.go` 6 | 7 | In this repo there are two directories that contain source code: 8 | - `go-kit/` - A simple Go Kit service that demonstrates the basics of using Go Kit. The service listens on localhost:8080. 9 | - `interfaces/` - A simple program that demonstrates how to use interfaces and demonstrates the usefulness of compatible interfaces. 10 | - `server/` - A simple program that demonstrates how to create a simple HTTP server that returns "Hello, World" when accessed. 11 | 12 | ## Resources for learning Go 13 | - [The Go Homepage](https://golang.org/) 14 | - [Effective Go](https://golang.org/doc/effective_go.html) - extremely useful document discussing how to write idiomatic Go 15 | - [Go By Example](https://gobyexample.com/) - a hands-on intro to Go using annotated programs. 16 | - [#gophers Slack](https://invite.slack.golangbridge.org/) - Come chat with other Gophers. 17 | 18 | ## Go Kit Resources 19 | - [The Go Kit Homepage](http://gokit.io/) 20 | - [Go Kit Examples](http://gokit.io/examples/) - very good examples of creating go-kit services. 21 | 22 | ## Who is using Go? 23 | Take a look at this list here: https://github.com/golang/go/wiki/GoUsers 24 | -------------------------------------------------------------------------------- /Chipping away at the monolith with Go/demos/go-kit/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // This is a very simple example of a go-kit service. When executed it will 4 | // start an HTTP server that listens on localhost:8080 and accepts POST requests 5 | // with a simple JSON payload of {"name": "Your name here"} 6 | // One could use cURL to make a request like this: 7 | // curl -v -X POST -H "Content-Type: application/json" -d '{"name": "Aaron"}' http://localhost:8080/hello 8 | 9 | // For more indepth examples please head to gokit.io/examples, and read over 10 | // the many excellent exaples provided there. 11 | 12 | import ( 13 | "encoding/json" 14 | "errors" 15 | "net/http" 16 | "os" 17 | "strings" 18 | "time" 19 | 20 | "golang.org/x/net/context" 21 | 22 | "github.com/go-kit/kit/endpoint" 23 | log "github.com/go-kit/kit/log" 24 | kithttp "github.com/go-kit/kit/transport/http" 25 | ) 26 | 27 | // GreetService is the interface that defines our service, and it will enable 28 | // us to create compatible middlewares to add functionality. 29 | type GreetService interface { 30 | Hello(string) (string, error) 31 | } 32 | 33 | // Here we concrete type that we can use to implement the GreetService interface. 34 | type greetService struct{} 35 | 36 | // Create a struct to represent requests to the service. 37 | type helloRequest struct { 38 | Name string `json:"name,omitempty"` 39 | } 40 | 41 | // Create a struct to represent responses from the service. 42 | type helloResponse struct { 43 | Greeting string `json:"greeting,omitempty"` 44 | Err error `json:"err,omitempty"` 45 | } 46 | 47 | // Go Kit uses the RPC model to communicate. So it expects us to not only create 48 | // structs for requests and responses for each endpoint, but also functions to 49 | // decode requests and encode responses. 50 | 51 | func decodeHelloRequest(_ context.Context, r *http.Request) (interface{}, error) { 52 | var request helloRequest 53 | if err := json.NewDecoder(r.Body).Decode(&request); err != nil { 54 | return nil, err 55 | } 56 | return request, nil 57 | } 58 | 59 | func encodeHelloResponse(_ context.Context, w http.ResponseWriter, response interface{}) error { 60 | return json.NewEncoder(w).Encode(response) 61 | } 62 | 63 | // Hello is the func that is required to implement the GreetService interface. 64 | // creating this func makes the greetService type implicitly implement the 65 | // GreetService interface. 66 | func (g greetService) Hello(s string) (string, error) { 67 | if s == "" { 68 | return "", errors.New("no name provided") 69 | } 70 | return "Hello there, " + strings.Title(s), nil 71 | } 72 | 73 | // A Go Kit Endpoint is a func that takes a Context and a interface{} (empty interface) 74 | // as parameters and returns an empty interface type and an error. 75 | func makeHelloEndpoint(svc GreetService) endpoint.Endpoint { 76 | return func(ctx context.Context, request interface{}) (interface{}, error) { 77 | req := request.(helloRequest) 78 | resp, err := svc.Hello(req.Name) 79 | if err != nil { 80 | return helloResponse{resp, err}, nil 81 | } 82 | return helloResponse{resp, nil}, nil 83 | } 84 | } 85 | 86 | // Here we create a middleware type that will implment the GreetService interface 87 | type loggingMiddleware struct { 88 | logger log.Logger 89 | next GreetService 90 | } 91 | 92 | // This instance of the Hello func makes the loggingMiddleware implment the 93 | // GreetService interface, which makes it compatible with the greetService type, 94 | // and allows us to chain different types of middlewares together to extend the 95 | // service. 96 | func (mw loggingMiddleware) Hello(s string) (output string, err error) { 97 | defer func(begin time.Time) { 98 | mw.logger.Log( 99 | "method", "Hello", 100 | "input", s, 101 | "err", err, 102 | "took", time.Since(begin), 103 | ) 104 | }(time.Now()) 105 | 106 | output, err = mw.next.Hello(s) 107 | return 108 | } 109 | 110 | func main() { 111 | ctx := context.Background() 112 | logger := log.NewLogfmtLogger(os.Stderr) 113 | 114 | var svc GreetService 115 | svc = greetService{} 116 | svc = loggingMiddleware{logger, svc} 117 | 118 | helloHandler := kithttp.NewServer( 119 | ctx, 120 | makeHelloEndpoint(svc), 121 | decodeHelloRequest, 122 | encodeHelloResponse, 123 | ) 124 | 125 | http.Handle("/hello", helloHandler) 126 | logger.Log("msg", "HTTP", "addr", ":8080") 127 | logger.Log("err", http.ListenAndServe(":8080", nil)) 128 | 129 | } 130 | -------------------------------------------------------------------------------- /Chipping away at the monolith with Go/demos/interfaces/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "log" 7 | "strings" 8 | ) 9 | 10 | type capitalized interface { 11 | Capitalize() string 12 | } 13 | 14 | type saidName string 15 | 16 | func (n saidName) Capitalize() string { 17 | return strings.Title(string(n)) 18 | } 19 | 20 | type yelledName string 21 | 22 | func (n yelledName) Capitalize() string { 23 | return strings.ToUpper(string(n)) 24 | } 25 | 26 | func main() { 27 | dilbertSays := saidName("aaron") 28 | howardSays := yelledName(dilbertSays) 29 | 30 | speakers := []capitalized{dilbertSays, howardSays} 31 | 32 | for _, speaker := range speakers { 33 | say(speaker) 34 | } 35 | 36 | } 37 | 38 | func say(speaker interface{}) { 39 | var whoSays, greeting, name string 40 | 41 | switch val := speaker.(type) { 42 | case saidName: 43 | whoSays = "Dilbert" 44 | greeting = "Hello" 45 | name = val.Capitalize() 46 | case yelledName: 47 | whoSays = "Loud Howard" 48 | greeting = "HELLO" 49 | name = val.Capitalize() 50 | default: 51 | log.Fatal(errors.New("Unknown type")) 52 | } 53 | 54 | fmt.Printf("%s says, '%s, %s'\n", whoSays, greeting, name) 55 | } 56 | -------------------------------------------------------------------------------- /Chipping away at the monolith with Go/demos/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | ) 8 | 9 | func helloHandler(w http.ResponseWriter, r *http.Request) { 10 | fmt.Fprintln(w, "Hello, world!") 11 | } 12 | 13 | func main() { 14 | http.HandleFunc("/hello", helloHandler) 15 | 16 | log.Fatal(http.ListenAndServe(":8080", nil)) 17 | } 18 | -------------------------------------------------------------------------------- /Chipping away at the monolith with Go/readme.md: -------------------------------------------------------------------------------- 1 | # Resources for "Chipping Away at the Monolith with Go" 2 | Items in this repository are a companion to the talk "Chipping Away at the Monolith with Go" that was given at CodeMash 2017 on January 12, 2017 at 9:15 AM at the Kalahari Resort in Sandusky, OH. 3 | 4 | ## Demo Code 5 | All of the programs can be run by going into the directory and issuing the following command: `go run main.go` 6 | 7 | In this repo there are two directories that contain source code: 8 | - `go-kit/` - A simple Go Kit service that demonstrates the basics of using Go Kit. The service listens on localhost:8080. 9 | - `interfaces/` - A simple program that demonstrates how to use interfaces and demonstrates the usefulness of compatible interfaces. 10 | - `server/` - A simple program that demonstrates how to create a simple HTTP server that returns "Hello, World" when accessed. 11 | 12 | ## Resources for learning Go 13 | - [The Go Homepage](https://golang.org/) 14 | - [Effective Go](https://golang.org/doc/effective_go.html) - extremely useful document discussing how to write idiomatic Go 15 | - [Go By Example](https://gobyexample.com/) - a hands-on intro to Go using annotated programs. 16 | - [#gophers Slack](https://invite.slack.golangbridge.org/) - Come chat with other Gophers. 17 | 18 | ## Go Kit Resources 19 | - [The Go Kit Homepage](http://gokit.io/) 20 | - [Go Kit Examples](http://gokit.io/examples/) - very good examples of creating go-kit services. 21 | 22 | ## Who is using Go? 23 | Take a look at this list here: https://github.com/golang/go/wiki/GoUsers 24 | -------------------------------------------------------------------------------- /Clouds and Containers/readme.md: -------------------------------------------------------------------------------- 1 | [Repository](https://github.com/mkheck/CloudsAndContainers) 2 | --- 3 | ##### Clouds & Containers: Hit the High Points and Give it to Me Straight, What’s the Difference & Why Should I Care? 4 | * Date: 1/12/17 8:00 am 5 | * Speakers: Mark Heckler 6 | * [Blog](http://www.thehecklers.org) 7 | * [Twitter](http://twitter.com/mkheck) 8 | * Room: Salon E 9 | * Tags: Cloud/Big Data, Other, Security, Java 10 | * Category: General Session 11 | --- 12 | As developers, we hear a non-stop stream of technical-but-marketing messages for containers, orchestration tools, and cloud services. There is extensive overlap in these areas with regard to both means and ends, and it’s time to clear the fog and get to the bottom of things. This talk will give a quick overview from a hardcore developer’s perspective of the following topics: * How can I use containers to develop better software? * What are orchestration tools? Do I need to consider/use them? * How do cloud/PaaS options compare? What are the tradeoffs? * What is the difference? * Why should I care? (Or should I?) In this session, the presenter discusses several of these technologies, compares them, and _deploys real applications to them LIVE_ to demonstrate subtle differences and tradeoffs each choice imposes upon developers, for better or worse. Come to this session to level up on containers, clouds, and developing real production software, regardless of where or how you deploy it. 13 | 14 | ## Slides can be viewed [here](http://www.slideshare.net/HecklerMark/clouds-containers-hit-the-high-points-and-give-it-to-me-straight-whats-the-difference-why-should-i-care) 15 | 16 | Please *watch* the repo on Github to be notified of updates! 17 | -------------------------------------------------------------------------------- /Components-and-More-Effective-Angular-2-Testing-Strategies/README.md: -------------------------------------------------------------------------------- 1 | # Components and More: Effective Angular 2 Testing Strategies 2 | 3 | ## Abstract 4 | 5 | Angular 2 is released! With it comes new opportunities for brilliantly authored and well-tested applications! While tests don't come free, they're well worth the time and effort -- especially for larger or long-lived codebases. 6 | 7 | We'll explore the full gamut of Angular 2 testing: What to test, how to test, classifications of tests, and the implications and tradeoffs for each of these decisions. Soon you'll be ready to `npm test` Angular 2 projects with confidence -- no Angular 1.x experience required! 8 | 9 | ## Materials 10 | 11 | - **Demo:** [https://github.com/kendaleiv/angular-testing](https://github.com/kendaleiv/angular-testing) 12 | - **Slides:** [https://kendaleiv.github.io/angular-testing-talk](https://kendaleiv.github.io/angular-testing-talk) 13 | 14 | ## Presenter 15 | 16 | Ken Dale 17 | Twitter: [@kendaleiv](https://twitter.com/kendaleiv) 18 | [https://kendaleiv.com](https://kendaleiv.com) 19 | -------------------------------------------------------------------------------- /Containers for Windows Developers/README.md: -------------------------------------------------------------------------------- 1 | [Repository and Presentation](https://github.com/mcollier/ContainersForWindowsDevs) 2 | --- 3 | ##### Containers for Windows Developers 4 | * 1/12/17 11:45 am 5 | * Speakers: Michael Collier 6 | * Room: Indigo Bay 7 | * Tags: Cloud/Big Data 8 | * Category: General Session 9 | --- 10 | 11 | Over the last few years, Docker has popularized Linux containers, but Windows developers have been left out in the cold This changes with Windows Server 2016. At this session we’ll cover the basics of the new Windows Server container model and how to develop applications/services that can take advantage of this exciting new advancement, for cloud, for on-prem, and for the future. -------------------------------------------------------------------------------- /DDD for Beginners/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](https://speakerdeck.com/akrabat/ddd-for-beginners) 2 | --- 3 | ##### DevOps @ Scale 4 | * Date: 1/12/17 3:30 pm 5 | * Speakers: [Rob Allen](https://akrabat.com) 6 | * Room: Cypress 7 | * Tags: 8 | * Category: General Session 9 | --- 10 | Domain Driven Design focusses on modelling the domain logic. This talk looks at the components of the model layer of your web application and the options you have. How are you supposed to organise your models in an MVC application? What goes where? What is a service class, a mapper or an entity? We’ll discuss the terminology and take a look at what Domain Driven Design is and see how you use service layer to provide the business logic for your application and hide your persistence code from your controllers. By the end of this session you will be equipped to create excellent, maintainable models in your projects. 11 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent": 2, /* indent sets white to true in jshint 0.9.1, but we want it to be false */ 3 | "white": false, /* so white goes after indent gets set */ 4 | "curly": true, /* requires you to always put curly braces around blocks in loops and conditionals */ 5 | "devel": true, /* expose console.log and alert and other globals */ 6 | "eqeqeq": true, /* prohibits the use of == and != in favor of === and !== */ 7 | "immed": true, /* prohibits the use of immediate function invocations without wrapping them in parentheses */ 8 | "latedef": true, /* prohibits the use of a variable before it was defined (ie, no hoisting) */ 9 | "newcap": false, /* true forces you to capitalize names of constructor functions (we have a 3rd party lib that doesn't) */ 10 | "noarg": true, /* prohibits the use of arguments.caller and arguments.callee (ecma5 strict) */ 11 | "sub": true, /* suppresses warnings about using [] notation when it can be expressed in dot notation */ 12 | "strict": true, /* requires all functions to run in EcmaScript 5's strict mode */ 13 | "undef": true, /* no explicitly undefined vars (ie, no spontaneous globals) */ 14 | "boss": true, /* suppresses warnings about the use of assignments in cases where comparisons are expected */ 15 | "eqnull": true, /* suppresses warnings about == null comparisons */ 16 | "browser": true, /* defines globals exposed by modern browsers */ 17 | "laxcomma": true, /* suppresses warnings about comma-first coding style */ 18 | "globals": { 19 | "Modernizr": true, 20 | "self": true, 21 | "url_regex": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 3 | grunt.loadNpmTasks("grunt-contrib-jshint"); 4 | grunt.loadNpmTasks("grunt-contrib-uglify"); 5 | grunt.loadNpmTasks("grunt-contrib-copy"); 6 | grunt.loadNpmTasks("grunt-contrib-concat"); 7 | grunt.loadNpmTasks("grunt-contrib-clean"); 8 | grunt.loadNpmTasks("grunt-contrib-less"); 9 | grunt.loadNpmTasks("grunt-contrib-cssmin"); 10 | grunt.loadNpmTasks('grunt-angular-templates'); 11 | grunt.loadNpmTasks("grunt-ng-annotate"); 12 | 13 | var buildTasks = [ 14 | 'notify:"build starting..."', 15 | "jshint", 16 | "clean", 17 | "ngtemplates", 18 | "ngAnnotate", 19 | "uglify", 20 | "concat", 21 | "less", 22 | "cssmin", 23 | "copy" 24 | ]; 25 | 26 | grunt.registerTask('default', buildTasks); 27 | 28 | grunt.registerTask('notify', 'tell the user what is happening', function(arg) { 29 | console.warn(arg); 30 | }); 31 | 32 | grunt.initConfig({ 33 | pkg: grunt.file.readJSON('package.json'), 34 | 35 | jshint: { 36 | files: [ 37 | 'src/js/**/*.js', 38 | 'src/components/**/*.js', 39 | '!src/components/**/*.spec.js' 40 | ], 41 | options: { 42 | jshintrc: '.jshintrc' 43 | }, 44 | }, 45 | 46 | clean: { 47 | options: { 48 | force: true, 49 | }, 50 | app:{ 51 | files: [{ 52 | expand: true, 53 | cwd: 'dist/', 54 | src: ['js/**', 'css/**'], 55 | }] 56 | } 57 | }, 58 | 59 | less: { 60 | app: { 61 | files: { 62 | 'src/tmp/app.max.css' : 'src/css/index.less' 63 | }, 64 | options: { 65 | paths: ['src/less'] 66 | } 67 | } 68 | }, 69 | 70 | ngAnnotate: { 71 | options: { 72 | add: true, 73 | singleQuotes: true 74 | }, 75 | 'app': { 76 | files: { 77 | 'src/tmp/app.annotated.js': 78 | [ 79 | 'src/js/app.js', 80 | 'src/components/**/*.js', 81 | 'src/js/**/*.js', 82 | '!src/components/**/*.spec.js' 83 | ] 84 | } 85 | } 86 | }, 87 | 88 | ngtemplates: { 89 | 'MyApp': { 90 | cwd: 'src', 91 | src: [ 92 | 'components/**/*.html' 93 | ], 94 | dest: 'src/tmp/app-components.js', 95 | options: { 96 | standalone: false, 97 | prefix: '/', 98 | htmlmin: { 99 | collapseWhitespace: true, 100 | removeRedundantAttributes: true, 101 | removeScriptTypeAttributes: true, 102 | removeStyleLinkTypeAttributes: true, 103 | keepClosingSlash: true 104 | } 105 | } 106 | } 107 | }, 108 | 109 | concat: { 110 | 'MyApp': { 111 | src: ['src/tmp/app.uglified.js', 'src/tmp/app-components.js'], 112 | dest: 'src/tmp/app.min.js' 113 | } 114 | }, 115 | 116 | uglify: { 117 | app: { 118 | options: { 119 | sourceMap: true, 120 | report: 'min' 121 | }, 122 | src: ['src/tmp/app.annotated.js'], 123 | dest: 'src/tmp/app.uglified.js' 124 | }, 125 | }, 126 | 127 | cssmin: { 128 | compress: { 129 | files: { 130 | 'dist/css/app.min.css': ['src/tmp/app.max.css'] 131 | } 132 | } 133 | }, 134 | 135 | copy: { 136 | rootFiles: { 137 | files: [ 138 | { 139 | expand: true, 140 | flatten: true, 141 | src: [ 142 | 'src/index.html' 143 | ], 144 | dest: 'dist/', 145 | filter: 'isFile' 146 | } 147 | ] 148 | }, 149 | js: { 150 | files: [ 151 | { 152 | expand: true, 153 | flatten: true, 154 | src: [ 155 | './src/tmp/bootstrap.min.js', 156 | './src/tmp/app.min.js', 157 | './src/tmp/app.uglified.js.map', 158 | './node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js' 159 | ], 160 | dest: 'dist/js/', 161 | filter: 'isFile' 162 | } 163 | ] 164 | }, 165 | css: { 166 | files: [ 167 | { 168 | expand: true, 169 | flatten: true, 170 | src: [ 171 | './node_modules/bootstrap/dist/css/bootstrap.min.css' 172 | ], 173 | dest: 'dist/css/', 174 | filter: 'isFile' 175 | } 176 | ] 177 | }, 178 | fonts: { 179 | files: [ 180 | { 181 | expand: true, 182 | flatten: true, 183 | src: [ 184 | './node_modules/bootstrap/fonts/*', 185 | ], 186 | dest: 'dist/fonts/', 187 | filter: 'isFile' 188 | } 189 | ] 190 | } 191 | } 192 | }); 193 | }; 194 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/README.md: -------------------------------------------------------------------------------- 1 | # Resources and Demos for "Declarative testing for JavaScript applications" 2 | Items in this repo are a companion to the talk "Declarative testing for JavaScript applications" talk that was given at CodeMash 2017 on January 12, 2017 at 10:30 AM at the Kalahari Resort in Sandusky, OH. 3 | 4 | ## Online Resources 5 | 6 | #### Slides 7 | The slide deck for the talk in available here: [Slide Deck](https://docs.google.com/presentation/d/1qf0X10Hsqy04ajyCQaoCtbZnDTdQZmS_YHTsxK1xyJg/edit?usp=sharing) 8 | 9 | #### The Speaker 10 | Obviously you found me here on GitHub, but you can also reach me by using the methods shown below. Please reach out to me if you have questions or feedback about the talk. I especially appreciate hearing from folks who wanted more out of the talk. This is how my future talks get better! 11 | - Twitter: [@naunga](https://twitter.com/naunga) 12 | - Email: [aaron.salvo@gmail.com](mailto:aaron.salvo@gmail.com) 13 | - LinkedIn: [Aaron Salvo](https://www.linkedin.com/in/aaronsalvo) 14 | 15 | ### Tools Used 16 | 17 | #### Testing 18 | - [Karma Test Runner](https://karma-runner.github.io/1.0/index.html) - Run all the tests! 19 | - [Jasmine](https://jasmine.github.io/) -- BDD framework for JavaScript. 20 | - [Yeoman](http://yeoman.io) -- "The web's scaffolding tool." 21 | 22 | #### Demo app built with... 23 | - [AngularJS 1.x](https://angularjs.org/) - Superheroic JavaScript MVW framwork. 24 | - [Grunt](http://gruntjs.com/) - _The_ Javascript Task Runner. 25 | - [lite-server](https://github.com/johnpapa/lite-server) - Lightweight node server. 26 | - [Browsersync](https://browsersync.io/) - Time-saving synchronised browser testing. 27 | 28 | ## Demo Code 29 | 30 | ### Prerequisites 31 | You will need to have npm installed in order to run the examples. 32 | 33 | ### Setting up the example app 34 | The following steps will get you up and running after you've cloned the repo: 35 | 0. `cd` into the newly cloned directory (we will assume `declarative/`) 36 | 0. Run `npm install` 37 | 0. Run `grunt` to build. 38 | 0. Run `npm start` to launch the app. If everything ran correctly a new browser window should launch once the lite-server starts. 39 | 40 | ### Setting up the Yeoman generator 41 | As demonstrated in the talk, there is a Yeoman Generator that will create a new component including the .spec.js and .expect.js files. 42 | 43 | The following steps will get this working for you: 44 | 0. Run `npm install -g yo` (you can skip this step if you've already got Yeoman installed) 45 | 0. cd to `generators/generator-my-app` 46 | 0. Run `npm install` to install the generator's dependencies 47 | 0. Once all the dependencies have installed successfully run `npm link` to make the generator accessible to Yeoman. 48 | 49 | To run the generator cd to the top-level of the repo (i.e. `declarative/`) and run `yo my-app:display` 50 | 51 | Follow the prompts to create the component as you desire. 52 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/bs-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 8080, 3 | "reloadDebounce": 250, 4 | "files": ["./dist/**/*.{html,css,js}"], 5 | "server": { 6 | "baseDir": "./dist", 7 | "index": "index.html" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/css/app.min.css: -------------------------------------------------------------------------------- 1 | .font-variable-width{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}body{padding:10px 0 0}.field_name,.field_value{vertical-align:top;display:inline-block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:18px;padding:2px 0;text-rendering:optimizelegibility}.field_name{z-index:100;text-align:left;font-weight:700;width:165px;overflow:hidden;margin:5px 10px 5px 0}.field_value{margin:5px 0} -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Declarative testing for JavaScript applications/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 |
28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/js/app.min.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";var b="/",c=a.module("MyApp",["ngRoute","ngSanitize","ui.bootstrap"]);c.config(["$routeProvider","$locationProvider","$httpProvider",function(a,c,d){c.html5Mode(!0),a.when(b,{templateUrl:b+"components/project/display.html",controllerAs:"ctrl",reloadOnSearch:!1,controller:["$rootScope",function(a){}]})}]),c.run(["$rootScope","$location","$timeout","$log",function(a,c,d,e){a.baseUrl=b}])}(window.angular),function(a){"use strict";a.module("MyApp").directive("projectDisplay",["$rootScope","$log",function(a,b){return b.log("ProjectDisplay is running..."),{restrict:"E",replace:!0,templateUrl:"/components/project/display.html",scope:{},controllerAs:"ctrl",controller:["$scope",function(a){}]}}])}(window.angular),function(a){"use strict";a.module("MyApp").directive("TeamDisplay",["$rootScope","$log",function(a,b){return b.log("TeamDisplay is running..."),{restrict:"E",replace:!0,templateUrl:"/components/Team/display.html",scope:{},controllerAs:"ctrl",controller:["$scope",function(a){}]}}])}(window.angular); 2 | //# sourceMappingURL=app.uglified.js.map 3 | angular.module('MyApp').run(['$templateCache', function($templateCache) { 4 | 'use strict'; 5 | 6 | $templateCache.put('/components/project/display.html', 7 | "

Project:

Project Summary
" 8 | ); 9 | 10 | 11 | $templateCache.put('/components/project/tab-summary.html', 12 | "

Details

Project Name
Parent Project
Status
Project Type

Points of Contact

POC 1
POC 2
Owning Team
Oncall Team
NOC Station
Mailing List
Slack Channel

Business/Financial Information

Cost Center
Billing Type
Classification
" 13 | ); 14 | 15 | 16 | $templateCache.put('/components/team/display.html', 17 | "

Team:

Summary
" 18 | ); 19 | 20 | 21 | $templateCache.put('/components/team/tab-summary.html', 22 | "

Details

Name
Status
" 23 | ); 24 | 25 | }]); 26 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/dist/js/app.uglified.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["app.annotated.js"],"names":["angular","baseUrl","myApp","module","config","$routeProvider","$locationProvider","$httpProvider","html5Mode","when","templateUrl","controllerAs","reloadOnSearch","controller","$rootScope","run","$location","$timeout","$log","window","directive","log","restrict","replace","scope","$scope"],"mappings":"CAAC,SAASA,GACR,YAGA,IAAIC,GAAU,IAEVC,EAAQF,EAAQG,OAAO,SAAU,UAAW,aAAc,gBAG9DD,GAAME,QAAQ,iBAAkB,oBAAqB,gBAAiB,SAASC,EAAgBC,EAAmBC,GAEhHD,EAAkBE,WAAU,GAG5BH,EACCI,KAAKR,GACJS,YAAaT,EAAU,kCACvBU,aAAc,OACdC,gBAAgB,EAChBC,YAAa,aAAc,SAASC,WAOxCZ,EAAMa,KAAK,aAAc,YAAa,WAAY,OAAQ,SAASD,EAAYE,EAAWC,EAAUC,GAClGJ,EAAWb,QAAUA,MAGvBkB,OAAOnB,SASR,SAASA,GACR,YACAA,GAAQG,OAAO,SAASiB,UAAU,kBAAmB,aAAc,OAAQ,SAASN,EAAYI,GAE9F,MADAA,GAAKG,IAAI,iCAEPC,SAAU,IACVC,SAAS,EACTb,YAAa,mCACbc,SACAb,aAAc,OACdE,YAAa,SAAU,SAASY,WAQpCN,OAAOnB,SASR,SAASA,GACR,YACAA,GAAQG,OAAO,SAASiB,UAAU,eAAgB,aAAc,OAAQ,SAASN,EAAYI,GAE3F,MADAA,GAAKG,IAAI,8BAEPC,SAAU,IACVC,SAAS,EACTb,YAAa,gCACbc,SACAb,aAAc,OACdE,YAAa,SAAU,SAASY,WAQpCN,OAAOnB","file":"app.uglified.js"} -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Aaron Salvo (https://about.me/aaron.salvo) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/README.md: -------------------------------------------------------------------------------- 1 | # generator-my-app [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] 2 | > Demoware for the CodeMash 2017 talk about declarative testing. 3 | 4 | ## Installation 5 | 6 | First, install [Yeoman](http://yeoman.io) and generator-my-app using [npm](https://www.npmjs.com/) (we assume you have pre-installed [node.js](https://nodejs.org/)). 7 | 8 | ```bash 9 | npm install -g yo 10 | npm install -g generator-my-app 11 | ``` 12 | 13 | Then generate your new project: 14 | 15 | ```bash 16 | yo my-app 17 | ``` 18 | 19 | ## Getting To Know Yeoman 20 | 21 | * Yeoman has a heart of gold. 22 | * Yeoman is a person with feelings and opinions, but is very easy to work with. 23 | * Yeoman can be too opinionated at times but is easily convinced not to be. 24 | * Feel free to [learn more about Yeoman](http://yeoman.io/). 25 | 26 | ## License 27 | 28 | MIT © [Aaron Salvo](https://about.me/aaron.salvo) 29 | 30 | 31 | [npm-image]: https://badge.fury.io/js/generator-my-app.svg 32 | [npm-url]: https://npmjs.org/package/generator-my-app 33 | [travis-image]: https://travis-ci.org/naunga/generator-my-app.svg?branch=master 34 | [travis-url]: https://travis-ci.org/naunga/generator-my-app 35 | [daviddm-image]: https://david-dm.org/naunga/generator-my-app.svg?theme=shields.io 36 | [daviddm-url]: https://david-dm.org/naunga/generator-my-app 37 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var yeoman = require('yeoman-generator'); 3 | var chalk = require('chalk'); 4 | var yosay = require('yosay'); 5 | 6 | module.exports = yeoman.Base.extend({ 7 | prompting: function () { 8 | // Have Yeoman greet the user. 9 | this.log(yosay( 10 | 'Welcome to the best ' + chalk.red('generator-my-app') + ' generator!' 11 | )); 12 | 13 | var prompts = [{ 14 | type: 'confirm', 15 | name: 'someAnswer', 16 | message: 'Would you like to enable this option?', 17 | default: true 18 | }]; 19 | 20 | return this.prompt(prompts).then(function (props) { 21 | // To access props later use this.props.someAnswer; 22 | this.props = props; 23 | }.bind(this)); 24 | }, 25 | 26 | writing: function () { 27 | this.fs.copy( 28 | this.templatePath('dummyfile.txt'), 29 | this.destinationPath('dummyfile.txt') 30 | ); 31 | }, 32 | 33 | install: function () { 34 | this.installDependencies(); 35 | } 36 | }); 37 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/app/templates/dummyfile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Declarative testing for JavaScript applications/generators/generator-my-app/generators/app/templates/dummyfile.txt -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/display/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var yeoman = require('yeoman-generator'); 3 | var chalk = require('chalk'); 4 | var yosay = require('yosay'); 5 | var _ = require('lodash'); 6 | 7 | module.exports = yeoman.Base.extend({ 8 | initializing: function() { 9 | var greet = function() { 10 | // Have Yeoman greet the user. 11 | this.log(yosay( 12 | 'Welcome to the superb ' + chalk.red('generator-my-app') + ' generator!' 13 | )); 14 | }.bind(this); 15 | 16 | greet(); 17 | }, 18 | prompting: function() { 19 | var tabs = []; 20 | var done = this.async(); 21 | 22 | var getComponentName = function() { 23 | return this.prompt([{ 24 | type: 'input', 25 | name: 'componentName', 26 | message: 'Enter the component name:' 27 | }]); 28 | }.bind(this); 29 | 30 | var getTabs = function() { 31 | return this.prompt([{ 32 | type: 'input', 33 | name: 'tabName', 34 | message: 'Enter a name for a tab or a blank to continue:' 35 | }]).then((answers) => { 36 | if(answers.tabName !== '') { 37 | var idx = tabs.push({name: answers.tabName, sections: []}); 38 | getSections(tabs[idx-1]); 39 | } else { 40 | this.answers.tabs = tabs; 41 | done(); 42 | } 43 | }); 44 | }.bind(this); 45 | 46 | var getSections = function(tab) { 47 | return this.prompt([{ 48 | type: 'input', 49 | name: 'sectionName', 50 | message: 'Enter the name of a section for the ' + chalk.styles.red.open + tab.name + chalk.styles.red.close + ' tab or a blank to continue:' 51 | }]).then((answers) => { 52 | if(answers.sectionName !== '') { 53 | var idx = tab.sections.push({name: answers.sectionName}) 54 | 55 | getFields(tab, tab.sections[idx-1]); 56 | } else { 57 | getTabs(); 58 | } 59 | }); 60 | }.bind(this); 61 | 62 | var getFields = function(tab, section) { 63 | return this.prompt([{ 64 | type: 'input', 65 | name: 'fieldName', 66 | message: 'Enter the name of a field for the ' + chalk.styles.yellow.open + section.name + chalk.styles.yellow.close + ' section or a blank to continue:' 67 | }]).then((answers) => { 68 | if(answers.fieldName !== '') { 69 | if(!section.fields) { 70 | section.fields = []; 71 | } 72 | section.fields.push({name: answers.fieldName}); 73 | 74 | getFields(tab,section); 75 | } else { 76 | getSections(tab); 77 | } 78 | }); 79 | }.bind(this); 80 | 81 | return getComponentName().then((answers) => { 82 | this.answers = answers; 83 | getTabs(); 84 | }); 85 | }, 86 | writing() { 87 | String.prototype.capitalize = function() { 88 | return this.charAt(0).toUpperCase() + this.slice(1); 89 | }; 90 | var componentName = this.answers.componentName; 91 | var tabs = this.answers.tabs; 92 | var that = this; 93 | 94 | this.fs.copyTpl( 95 | this.templatePath('display.html.tmplt'), 96 | this.destinationPath('src/components/' + componentName.toLowerCase() + '/display.html'), 97 | { 98 | componentName: componentName, 99 | tabs: this.answers.tabs 100 | } 101 | ); 102 | 103 | this.fs.copyTpl( 104 | this.templatePath('display.js.tmplt'), 105 | this.destinationPath('src/components/' + componentName.toLowerCase() + '/display.js'), 106 | { 107 | componentName: componentName 108 | } 109 | ); 110 | 111 | tabs.forEach(function(tab) { 112 | that.fs.copyTpl( 113 | that.templatePath('tab-summary.html.tmplt'), 114 | that.destinationPath('src/components/' + componentName.toLowerCase() + '/tab-' + tab.name.toLowerCase() + '.html'), 115 | { 116 | componentName: componentName, 117 | tab: tab 118 | } 119 | ); 120 | }); 121 | 122 | this.fs.copyTpl( 123 | this.templatePath('display.expect.js.tmplt'), 124 | this.destinationPath('test/structural/components/' + componentName.toLowerCase() + '/display.expect.js'), 125 | { 126 | componentName: componentName, 127 | tabs: JSON.stringify(this.answers.tabs, null, 2) 128 | } 129 | ); 130 | 131 | this.fs.copyTpl( 132 | this.templatePath('display.spec.js.tmplt'), 133 | this.destinationPath('test/structural/components/' + componentName.toLowerCase() + '/display.spec.js'), 134 | { componentName: componentName } 135 | ); 136 | }, 137 | }); 138 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/display/templates/display.expect.js.tmplt: -------------------------------------------------------------------------------- 1 | window.ExpectData = window.ExpectData || {}; 2 | window.ExpectData.<%= componentName -%> = { 3 | tabs: <%- tabs %> 4 | }; 5 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/display/templates/display.html.tmplt: -------------------------------------------------------------------------------- 1 | 2 |

<%= componentName.capitalize() -%>:

3 | 4 | 5 | <% tabs.forEach(function(t) { -%> 6 | 7 | 8 | <%= t.name.capitalize() -%> 9 | 10 | 11 | 12 | <% }); -%> 13 | 14 | 15 |
16 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/display/templates/display.js.tmplt: -------------------------------------------------------------------------------- 1 | /** 2 | @memberof MyApp 3 | @ngdoc directive 4 | @name <%= componentName -%>Display 5 | @description A simple display page 6 | @example <<%= componentName -%>-display>-display> 7 | */ 8 | (function(angular) { 9 | 'use strict'; 10 | angular.module('MyApp').directive('<%= componentName.toLowerCase() -%>Display', function($rootScope, $log) { 11 | $log.log("<%= componentName.capitalize() -%>Display is running..."); 12 | return { 13 | restrict: 'E', 14 | replace: true, 15 | templateUrl: '/components/<%= componentName.toLowerCase() -%>/display.html', 16 | scope: {}, 17 | controllerAs: 'ctrl', 18 | controller: function($scope) { 19 | 20 | var ctrl = this; 21 | 22 | } 23 | }; 24 | 25 | }); 26 | }(window.angular)); 27 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/display/templates/display.spec.js.tmplt: -------------------------------------------------------------------------------- 1 | describe('myApp<%= componentName.capitalize() %>Display', function() { 2 | var fields = {}; 3 | var sections = {}; 4 | var tabs = {}; 5 | var element; 6 | 7 | var expectedData = window.ExpectData.<%= componentName %>; 8 | 9 | beforeEach(function() { 10 | module('MyApp'); 11 | 12 | inject(function($compile, $rootScope) { 13 | var directiveElement = window.Jhelpers.getCompiledElement({ 14 | scope: $rootScope.$new(), 15 | compile: $compile, 16 | elementType: '<%= componentName %>', 17 | action: 'display' 18 | }); 19 | 20 | fields = window.Jhelpers.getFields(directiveElement); 21 | sections = window.Jhelpers.getSections(directiveElement); 22 | tabs = window.Jhelpers.getTabs(directiveElement); 23 | 24 | }); 25 | }); 26 | 27 | expectedData.tabs.forEach(function(tab) { 28 | describe('should have a set of tabs...\n', function() { 29 | it('...there should be a tab named ' + tab.name + '. ', function() { 30 | expect(tabs[tab.name]).toBeDefined(); 31 | }); 32 | 33 | if(tab.sections) { 34 | tab.sections.forEach(function(section) { 35 | it('...on the ' + tab.name + ' tab there should be a section named ' + section.name, function() { 36 | expect(sections[section.name]).toBeDefined(); 37 | }); 38 | 39 | section.fields.forEach(function(field) { 40 | it('...on the ' + tab.name + ' tab, within the ' + section.name + ' section, there should be a field named ' + field.name, function(){ 41 | expect(fields[field.name]).toBeDefined(); 42 | }); 43 | }); 44 | }); // End tab.sections.forEach() 45 | } // End if(tab.sections) 46 | 47 | }); // End describe('should have a set of tabs...') 48 | }); // End expectedData.tabs.forEach() 49 | }); 50 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/generators/display/templates/tab-summary.html.tmplt: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | <% tab.sections.forEach(function(s) { -%> 6 |

<%= s.name.capitalize() -%>

7 |
8 | <% s.fields.forEach(function(f) { -%> 9 | <%= f.name.capitalize() -%> 10 | 11 |
12 | <% }); -%> 13 |
14 | <% }); -%> 15 |
16 | 17 |
18 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var gulp = require('gulp'); 4 | var eslint = require('gulp-eslint'); 5 | var excludeGitignore = require('gulp-exclude-gitignore'); 6 | var mocha = require('gulp-mocha'); 7 | var istanbul = require('gulp-istanbul'); 8 | var nsp = require('gulp-nsp'); 9 | var plumber = require('gulp-plumber'); 10 | 11 | gulp.task('static', function () { 12 | return gulp.src('**/*.js') 13 | .pipe(excludeGitignore()) 14 | .pipe(eslint()) 15 | .pipe(eslint.format()) 16 | .pipe(eslint.failAfterError()); 17 | }); 18 | 19 | gulp.task('nsp', function (cb) { 20 | nsp({package: path.resolve('package.json')}, cb); 21 | }); 22 | 23 | gulp.task('pre-test', function () { 24 | return gulp.src('generators/**/*.js') 25 | .pipe(excludeGitignore()) 26 | .pipe(istanbul({ 27 | includeUntested: true 28 | })) 29 | .pipe(istanbul.hookRequire()); 30 | }); 31 | 32 | gulp.task('test', ['pre-test'], function (cb) { 33 | var mochaErr; 34 | 35 | gulp.src('test/**/*.js') 36 | .pipe(plumber()) 37 | .pipe(mocha({reporter: 'spec'})) 38 | .on('error', function (err) { 39 | mochaErr = err; 40 | }) 41 | .pipe(istanbul.writeReports()) 42 | .on('end', function () { 43 | cb(mochaErr); 44 | }); 45 | }); 46 | 47 | gulp.task('watch', function () { 48 | gulp.watch(['generators/**/*.js', 'test/**'], ['test']); 49 | }); 50 | 51 | gulp.task('prepublish', ['nsp']); 52 | gulp.task('default', ['static', 'test']); 53 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/generators/generator-my-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-my-app", 3 | "version": "0.0.0", 4 | "description": "Demoware for the CodeMash 2017 talk about declarative testing.", 5 | "homepage": "https://github.com/naunga/declarative", 6 | "author": { 7 | "name": "Aaron Salvo", 8 | "email": "aaron.salvo@gmail.com", 9 | "url": "https://about.me/aaron.salvo" 10 | }, 11 | "files": [ 12 | "generators" 13 | ], 14 | "main": "generators/index.js", 15 | "keywords": [ 16 | "demoware codemash2017", 17 | "yeoman-generator" 18 | ], 19 | "dependencies": { 20 | "yeoman-generator": "^0.23.0", 21 | "chalk": "^1.0.0", 22 | "yosay": "^1.0.0" 23 | }, 24 | "devDependencies": { 25 | "yeoman-test": "^1.0.0", 26 | "yeoman-assert": "^2.0.0", 27 | "eslint": "^3.1.1", 28 | "eslint-config-xo-space": "^0.15.0", 29 | "gulp": "^3.9.0", 30 | "gulp-eslint": "^3.0.1", 31 | "gulp-exclude-gitignore": "^1.0.0", 32 | "gulp-line-ending-corrector": "^1.0.1", 33 | "gulp-istanbul": "^1.0.0", 34 | "gulp-mocha": "^3.0.1", 35 | "gulp-plumber": "^1.0.0", 36 | "gulp-nsp": "^2.1.0" 37 | }, 38 | "eslintConfig": { 39 | "extends": "xo-space", 40 | "env": { 41 | "mocha": true 42 | } 43 | }, 44 | "repository": "git@github.com:naunga/declarative.git", 45 | "scripts": { 46 | "prepublish": "gulp prepublish", 47 | "test": "gulp" 48 | }, 49 | "license": "MIT" 50 | } 51 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config) { 2 | config.set({ 3 | 4 | // base path that will be used to resolve all patterns (eg. files, exclude) 5 | basePath: './', 6 | 7 | browserNoActivityTimeout: 30000, 8 | 9 | client: { 10 | captureConsole: true, 11 | }, 12 | 13 | // frameworks to use 14 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 15 | frameworks: ['jasmine'], 16 | 17 | // list of files / patterns to load in the browser 18 | files: [ 19 | 'test/Jhelpers.js', 20 | 'node_modules/jquery/dist/jquery.js', 21 | 'node_modules/angular/angular.js', 22 | 'node_modules/angular-mocks/angular-mocks.js', 23 | 'node_modules/angular-route/angular-route.js', 24 | 'node_modules/angular-sanitize/angular-sanitize.js', 25 | 'node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js', 26 | 'node_modules/bootstrap/dist/js/bootstrap.js', 27 | 'src/js/app.js', 28 | 'src/components/**/*.js', 29 | 'src/components/**/*.html', 30 | 'test/structural/**/*.js' 31 | ], 32 | 33 | // preprocess matching files before serving them to the browser 34 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 35 | preprocessors: { 36 | 'src/components/**/*.html': ["ng-html2js"], 37 | }, 38 | 39 | ngHtml2JsPreprocessor: { 40 | // strip this from the file path 41 | stripPrefix: 'src', 42 | moduleName: 'MyApp' 43 | }, 44 | 45 | // test results reporter to use 46 | // possible values: 'dots', 'progress' 47 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 48 | reporters: ['dots'], 49 | 50 | // web server port 51 | port: 9876, 52 | 53 | // enable / disable colors in the output (reporters and logs) 54 | colors: true, 55 | 56 | // level of logging 57 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 58 | logLevel: config.LOG_INFO, 59 | 60 | 61 | // enable / disable watching file and executing tests whenever any file changes 62 | autoWatch: false, 63 | 64 | // start these browsers 65 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 66 | browsers: ['PhantomJS'], 67 | 68 | 69 | // Continuous Integration mode 70 | // if true, Karma captures browsers, runs the tests and exits 71 | singleRun: true, 72 | 73 | // Concurrency level 74 | // how many browser should be started simultanous 75 | concurrency: Infinity 76 | }) 77 | } 78 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "declarative", 3 | "version": "1.0.0", 4 | "description": "Demo code for Declarative Testing talk presented at CodeMash 2017", 5 | "scripts": { 6 | "start": "lite-server -c bs-config.json", 7 | "test": "karma start karma.conf.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/naunga/declarative.git" 12 | }, 13 | "author": "Aaron Salvo", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/naunga/declarative/issues" 17 | }, 18 | "homepage": "https://github.com/naunga/declarative#readme", 19 | "dependencies": { 20 | "angular": "~1.5.6", 21 | "angular-mocks": "~1.5.5", 22 | "angular-route": "~1.5.5", 23 | "angular-sanitize": "~1.5.5", 24 | "angular-ui-bootstrap": "^2.3.0", 25 | "bootstrap": "^3.3.7" 26 | }, 27 | "devDependencies": { 28 | "eslint": "^3.11.1", 29 | "eslint-config-angular": "^0.5.0", 30 | "eslint-plugin-angular": "^1.4.1", 31 | "grunt": "^0.4.5", 32 | "grunt-ng-annotate": "^3.0.0", 33 | "grunt-angular-templates": "^1.0.3", 34 | "grunt-contrib-clean": "^0.6.0", 35 | "grunt-contrib-concat": "^1.0.1", 36 | "grunt-contrib-copy": "^0.8.0", 37 | "grunt-contrib-cssmin": "^0.12.3", 38 | "grunt-contrib-jshint": "^0.11.3", 39 | "grunt-contrib-less": "^1.0.1", 40 | "grunt-contrib-uglify": "^0.9.2", 41 | "grunt-contrib-watch": "^0.6.1", 42 | "grunt-jsdoc": "^2.1.0", 43 | "jasmine-core": "^2.4.1", 44 | "jquery": "^1.9.1", 45 | "karma": "^0.13.22", 46 | "karma-jasmine": "^1.0.2", 47 | "karma-ng-html2js-preprocessor": "^1.0.0", 48 | "karma-phantomjs-launcher": "^1.0.0", 49 | "lite-server": "^2.2.2", 50 | "phantomjs-prebuilt": "^2.1.7" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/components/project/display.html: -------------------------------------------------------------------------------- 1 | 2 |

Project:

3 | 4 | 5 | 6 | 7 | Project Summary 8 | 9 | 10 | 11 | 12 | 13 |
14 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/components/project/display.js: -------------------------------------------------------------------------------- 1 | /** 2 | @memberof MyApp 3 | @ngdoc directive 4 | @name projectDisplay 5 | @description A simple display page 6 | @example 7 | */ 8 | (function(angular) { 9 | 'use strict'; 10 | angular.module('MyApp').directive('projectDisplay', function($rootScope, $log) { 11 | $log.log("ProjectDisplay is running..."); 12 | return { 13 | restrict: 'E', 14 | replace: true, 15 | templateUrl: '/components/project/display.html', 16 | scope: {}, 17 | controllerAs: 'ctrl', 18 | controller: function($scope) { 19 | 20 | var ctrl = this; 21 | 22 | } 23 | }; 24 | 25 | }); 26 | }(window.angular)); 27 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/components/project/tab-summary.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |

Details

6 |
7 | Project Name 8 | 9 |
10 | 11 | Parent Project 12 | 13 | 14 |
15 | 16 | Status 17 | 18 | 19 |
20 | 21 | Project Type 22 | 23 | 24 |
25 | 26 |
27 | 28 |

Points of Contact

29 | 30 |
31 | 32 | POC 1 33 | 34 | 35 |
36 | 37 | POC 2 38 | 39 | 40 |
41 | 42 | Owning Team 43 | 44 | 45 |
46 | 47 | Oncall Team 48 | 49 | 50 |
51 | 52 | NOC Station 53 | 54 | 55 |
56 | 57 | Mailing List 58 | 59 |
60 | 61 | Slack Channel 62 | 63 |
64 | 65 |
66 | 67 | 68 |
69 | 70 | 71 |
72 | 73 | 74 |
75 | 76 |
77 |

Business/Financial Information

78 |
79 | Cost Center 80 | 81 |
82 | 83 | Billing Type 84 | 85 |
86 | 87 | Classification 88 | 89 |
90 | 91 |
92 | 93 |
94 | 95 | 96 |
97 | 98 | 99 |
100 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/css/index.less: -------------------------------------------------------------------------------- 1 | .font-variable-width { 2 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 3 | } 4 | 5 | body { 6 | padding: 10px 0px 0px 0px; 7 | } 8 | .field_name { 9 | display: inline-block; 10 | z-index: 100; 11 | text-align: left; 12 | .font-variable-width; 13 | vertical-align: top; 14 | line-height: 18px; 15 | font-weight: bold; 16 | width: 165px; 17 | overflow: hidden; 18 | margin: 5px 10px 5px 0px; 19 | padding: 2px 0px 2px 0px; 20 | text-rendering: optimizelegibility; 21 | } 22 | .field_value { 23 | vertical-align: top; 24 | display: inline-block; 25 | .font-variable-width; 26 | line-height: 18px; 27 | margin: 5px 0px; 28 | padding: 2px 0px 2px 0px; 29 | text-rendering: optimizelegibility; 30 | } 31 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 |
28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/js/app.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; // ECMA5 strict mode 3 | 4 | // baseUrl is used for routes 5 | var baseUrl = '/'; 6 | 7 | var myApp = angular.module('MyApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']); 8 | 9 | // Configure the module. 10 | myApp.config(function($routeProvider, $locationProvider, $httpProvider) { 11 | 12 | $locationProvider.html5Mode(true); // Assume HTML5 compliant browser that have History API support. 13 | 14 | // ROUTES ///////////////////////////////////////////////////////////////// 15 | $routeProvider 16 | .when(baseUrl, { // BASE ROUTE 17 | templateUrl: baseUrl + 'components/project/display.html', 18 | controllerAs: 'ctrl', 19 | reloadOnSearch: false, 20 | controller: function($rootScope) { 21 | var ctrl = this; 22 | } 23 | }); 24 | 25 | }); // end .config() 26 | 27 | myApp.run(function($rootScope, $location, $timeout, $log) { 28 | $rootScope.baseUrl = baseUrl; 29 | }); 30 | 31 | }(window.angular)); 32 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/tmp/app-components.js: -------------------------------------------------------------------------------- 1 | angular.module('MyApp').run(['$templateCache', function($templateCache) { 2 | 'use strict'; 3 | 4 | $templateCache.put('/components/project/display.html', 5 | "

Project:

Project Summary
" 6 | ); 7 | 8 | 9 | $templateCache.put('/components/project/tab-summary.html', 10 | "

Details

Project Name
Parent Project
Status
Project Type

Points of Contact

POC 1
POC 2
Owning Team
Oncall Team
NOC Station
Mailing List
Slack Channel

Business/Financial Information

Cost Center
Billing Type
Classification
" 11 | ); 12 | 13 | 14 | $templateCache.put('/components/team/display.html', 15 | "

Team:

Summary
" 16 | ); 17 | 18 | 19 | $templateCache.put('/components/team/tab-summary.html', 20 | "

Details

Name
Status
" 21 | ); 22 | 23 | }]); 24 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/tmp/app.annotated.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; // ECMA5 strict mode 3 | 4 | // baseUrl is used for routes 5 | var baseUrl = '/'; 6 | 7 | var myApp = angular.module('MyApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']); 8 | 9 | // Configure the module. 10 | myApp.config(['$routeProvider', '$locationProvider', '$httpProvider', function($routeProvider, $locationProvider, $httpProvider) { 11 | 12 | $locationProvider.html5Mode(true); // Assume HTML5 compliant browser that have History API support. 13 | 14 | // ROUTES ///////////////////////////////////////////////////////////////// 15 | $routeProvider 16 | .when(baseUrl, { // BASE ROUTE 17 | templateUrl: baseUrl + 'components/project/display.html', 18 | controllerAs: 'ctrl', 19 | reloadOnSearch: false, 20 | controller: ['$rootScope', function($rootScope) { 21 | var ctrl = this; 22 | }] 23 | }); 24 | 25 | }]); // end .config() 26 | 27 | myApp.run(['$rootScope', '$location', '$timeout', '$log', function($rootScope, $location, $timeout, $log) { 28 | $rootScope.baseUrl = baseUrl; 29 | }]); 30 | 31 | }(window.angular)); 32 | 33 | /** 34 | @memberof MyApp 35 | @ngdoc directive 36 | @name projectDisplay 37 | @description A simple display page 38 | @example 39 | */ 40 | (function(angular) { 41 | 'use strict'; 42 | angular.module('MyApp').directive('projectDisplay', ['$rootScope', '$log', function($rootScope, $log) { 43 | $log.log("ProjectDisplay is running..."); 44 | return { 45 | restrict: 'E', 46 | replace: true, 47 | templateUrl: '/components/project/display.html', 48 | scope: {}, 49 | controllerAs: 'ctrl', 50 | controller: ['$scope', function($scope) { 51 | 52 | var ctrl = this; 53 | 54 | }] 55 | }; 56 | 57 | }]); 58 | }(window.angular)); 59 | 60 | /** 61 | @memberof MyApp 62 | @ngdoc directive 63 | @name TeamDisplay 64 | @description A simple display page 65 | @example 66 | */ 67 | (function(angular) { 68 | 'use strict'; 69 | angular.module('MyApp').directive('TeamDisplay', ['$rootScope', '$log', function($rootScope, $log) { 70 | $log.log("TeamDisplay is running..."); 71 | return { 72 | restrict: 'E', 73 | replace: true, 74 | templateUrl: '/components/Team/display.html', 75 | scope: {}, 76 | controllerAs: 'ctrl', 77 | controller: ['$scope', function($scope) { 78 | 79 | var ctrl = this; 80 | 81 | }] 82 | }; 83 | 84 | }]); 85 | }(window.angular)); 86 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/tmp/app.max.css: -------------------------------------------------------------------------------- 1 | .font-variable-width { 2 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 3 | } 4 | body { 5 | padding: 10px 0px 0px 0px; 6 | } 7 | .field_name { 8 | display: inline-block; 9 | z-index: 100; 10 | text-align: left; 11 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 12 | vertical-align: top; 13 | line-height: 18px; 14 | font-weight: bold; 15 | width: 165px; 16 | overflow: hidden; 17 | margin: 5px 10px 5px 0px; 18 | padding: 2px 0px 2px 0px; 19 | text-rendering: optimizelegibility; 20 | } 21 | .field_value { 22 | vertical-align: top; 23 | display: inline-block; 24 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 25 | line-height: 18px; 26 | margin: 5px 0px; 27 | padding: 2px 0px 2px 0px; 28 | text-rendering: optimizelegibility; 29 | } 30 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/tmp/app.min.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";var b="/",c=a.module("MyApp",["ngRoute","ngSanitize","ui.bootstrap"]);c.config(["$routeProvider","$locationProvider","$httpProvider",function(a,c,d){c.html5Mode(!0),a.when(b,{templateUrl:b+"components/project/display.html",controllerAs:"ctrl",reloadOnSearch:!1,controller:["$rootScope",function(a){}]})}]),c.run(["$rootScope","$location","$timeout","$log",function(a,c,d,e){a.baseUrl=b}])}(window.angular),function(a){"use strict";a.module("MyApp").directive("projectDisplay",["$rootScope","$log",function(a,b){return b.log("ProjectDisplay is running..."),{restrict:"E",replace:!0,templateUrl:"/components/project/display.html",scope:{},controllerAs:"ctrl",controller:["$scope",function(a){}]}}])}(window.angular),function(a){"use strict";a.module("MyApp").directive("TeamDisplay",["$rootScope","$log",function(a,b){return b.log("TeamDisplay is running..."),{restrict:"E",replace:!0,templateUrl:"/components/Team/display.html",scope:{},controllerAs:"ctrl",controller:["$scope",function(a){}]}}])}(window.angular); 2 | //# sourceMappingURL=app.uglified.js.map 3 | angular.module('MyApp').run(['$templateCache', function($templateCache) { 4 | 'use strict'; 5 | 6 | $templateCache.put('/components/project/display.html', 7 | "

Project:

Project Summary
" 8 | ); 9 | 10 | 11 | $templateCache.put('/components/project/tab-summary.html', 12 | "

Details

Project Name
Parent Project
Status
Project Type

Points of Contact

POC 1
POC 2
Owning Team
Oncall Team
NOC Station
Mailing List
Slack Channel

Business/Financial Information

Cost Center
Billing Type
Classification
" 13 | ); 14 | 15 | 16 | $templateCache.put('/components/team/display.html', 17 | "

Team:

Summary
" 18 | ); 19 | 20 | 21 | $templateCache.put('/components/team/tab-summary.html', 22 | "

Details

Name
Status
" 23 | ); 24 | 25 | }]); 26 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/tmp/app.uglified.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";var b="/",c=a.module("MyApp",["ngRoute","ngSanitize","ui.bootstrap"]);c.config(["$routeProvider","$locationProvider","$httpProvider",function(a,c,d){c.html5Mode(!0),a.when(b,{templateUrl:b+"components/project/display.html",controllerAs:"ctrl",reloadOnSearch:!1,controller:["$rootScope",function(a){}]})}]),c.run(["$rootScope","$location","$timeout","$log",function(a,c,d,e){a.baseUrl=b}])}(window.angular),function(a){"use strict";a.module("MyApp").directive("projectDisplay",["$rootScope","$log",function(a,b){return b.log("ProjectDisplay is running..."),{restrict:"E",replace:!0,templateUrl:"/components/project/display.html",scope:{},controllerAs:"ctrl",controller:["$scope",function(a){}]}}])}(window.angular),function(a){"use strict";a.module("MyApp").directive("TeamDisplay",["$rootScope","$log",function(a,b){return b.log("TeamDisplay is running..."),{restrict:"E",replace:!0,templateUrl:"/components/Team/display.html",scope:{},controllerAs:"ctrl",controller:["$scope",function(a){}]}}])}(window.angular); 2 | //# sourceMappingURL=app.uglified.js.map -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/src/tmp/app.uglified.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["app.annotated.js"],"names":["angular","baseUrl","myApp","module","config","$routeProvider","$locationProvider","$httpProvider","html5Mode","when","templateUrl","controllerAs","reloadOnSearch","controller","$rootScope","run","$location","$timeout","$log","window","directive","log","restrict","replace","scope","$scope"],"mappings":"CAAC,SAASA,GACR,YAGA,IAAIC,GAAU,IAEVC,EAAQF,EAAQG,OAAO,SAAU,UAAW,aAAc,gBAG9DD,GAAME,QAAQ,iBAAkB,oBAAqB,gBAAiB,SAASC,EAAgBC,EAAmBC,GAEhHD,EAAkBE,WAAU,GAG5BH,EACCI,KAAKR,GACJS,YAAaT,EAAU,kCACvBU,aAAc,OACdC,gBAAgB,EAChBC,YAAa,aAAc,SAASC,WAOxCZ,EAAMa,KAAK,aAAc,YAAa,WAAY,OAAQ,SAASD,EAAYE,EAAWC,EAAUC,GAClGJ,EAAWb,QAAUA,MAGvBkB,OAAOnB,SASR,SAASA,GACR,YACAA,GAAQG,OAAO,SAASiB,UAAU,kBAAmB,aAAc,OAAQ,SAASN,EAAYI,GAE9F,MADAA,GAAKG,IAAI,iCAEPC,SAAU,IACVC,SAAS,EACTb,YAAa,mCACbc,SACAb,aAAc,OACdE,YAAa,SAAU,SAASY,WAQpCN,OAAOnB,SASR,SAASA,GACR,YACAA,GAAQG,OAAO,SAASiB,UAAU,eAAgB,aAAc,OAAQ,SAASN,EAAYI,GAE3F,MADAA,GAAKG,IAAI,8BAEPC,SAAU,IACVC,SAAS,EACTb,YAAa,gCACbc,SACAb,aAAc,OACdE,YAAa,SAAU,SAASY,WAQpCN,OAAOnB","file":"app.uglified.js"} -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/test/Jhelpers.js: -------------------------------------------------------------------------------- 1 | var Jhelpers = (function() { 2 | 'use strict'; 3 | 4 | String.prototype.capitalize = function() { 5 | return this.charAt(0).toUpperCase() + this.slice(1); 6 | }; 7 | 8 | var handleError = function(e) { 9 | var err; 10 | 11 | // Dependency missing in the Karma conf. 12 | if(e.message && e.message.match("Failed to instantiate module")) { 13 | var lines = e.message.split('\n'); 14 | err = new Error('A dependency could not be loaded. Is it included in the Karma config?\n' + lines[0] + '\n\t' + lines[1] + '\n\t' + lines[2]); 15 | throw err; 16 | } 17 | throw e; 18 | } 19 | 20 | var getCompiledElement = function(conf) { 21 | var element = angular.element('<'+conf.elementType + '-' + conf.action + '>'); 22 | var compiledElement = conf.compile(element)(conf.scope); 23 | var cachedTemplate; 24 | 25 | conf.scope.$digest(); 26 | 27 | if(conf.httpBackend) { 28 | conf.httpBackend.flush(); 29 | } 30 | 31 | compiledElement.isolateScope().ctrl.elementData = conf.mockData; 32 | conf.scope.$digest(); 33 | 34 | return compiledElement; 35 | }; 36 | 37 | var getFields = function(directiveElement) { 38 | var fields = {}; 39 | 40 | directiveElement.find("span[class*='field']").toArray().forEach( 41 | function(val,i,a) { 42 | if( i%2 === 1) return; 43 | fields[val.innerText.trim()] = {value: a[i+1].innerHTML.trim(), required: val.classList.contains("required") }; 44 | }); 45 | 46 | return fields; 47 | }; 48 | 49 | var getSections = function(directiveElement) { 50 | var sections = {}; 51 | 52 | directiveElement.find("h4").toArray().forEach( 53 | function(val) { 54 | sections[val.innerText.trim()] = 1; 55 | }); 56 | 57 | return sections; 58 | }; 59 | 60 | var getTabs = function(directiveElement) { 61 | var tabs = {}; 62 | 63 | directiveElement.find("uib-tab-heading").toArray().forEach( 64 | function(val) { 65 | tabs[val.innerText.trim()] = 1; 66 | }); 67 | 68 | return tabs; 69 | }; 70 | 71 | return { 72 | getCompiledElement: getCompiledElement, 73 | getFields: getFields, 74 | getSections: getSections, 75 | getTabs: getTabs, 76 | handleError: handleError 77 | }; 78 | 79 | }()); 80 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/test/structural/components/project/project.expect.js: -------------------------------------------------------------------------------- 1 | window.ExpectData = window.ExpectData || {}; 2 | window.ExpectData.project = { 3 | tabs: [ 4 | { 5 | name: "Project Summary", 6 | sections: [ 7 | { 8 | name: "Details", 9 | fields: [ 10 | {name: "Project Name"}, 11 | {name: "Parent Project"}, 12 | {name: "Status"}, 13 | {name: "Project Type"} 14 | ] 15 | }, 16 | { 17 | name: "Points of Contact", 18 | fields: [ 19 | {name: "POC 1"}, 20 | {name: "POC 2"}, 21 | {name: "Owning Team"}, 22 | {name: "Oncall Team"}, 23 | {name: "NOC Station"}, 24 | {name: "Mailing List"}, 25 | {name: "Slack Channel"} 26 | ] 27 | }, 28 | { 29 | name: "Business/Financial Information", 30 | fields: [ 31 | {name: "Cost Center"}, 32 | {name: "Billing Type"}, 33 | {name: "Classification"}, 34 | ] 35 | } 36 | ] // End sections. 37 | } 38 | ] // End tabs 39 | }; 40 | -------------------------------------------------------------------------------- /Declarative testing for JavaScript applications/test/structural/components/project/project.spec.js: -------------------------------------------------------------------------------- 1 | describe('myAppProjectDisplay', function() { 2 | var fields = {}; 3 | var sections = {}; 4 | var tabs = {}; 5 | var element; 6 | 7 | var expectedData = window.ExpectData.project; 8 | 9 | beforeEach(function() { 10 | module('MyApp'); 11 | 12 | inject(function($compile, $rootScope) { 13 | var directiveElement = window.Jhelpers.getCompiledElement({ 14 | scope: $rootScope.$new(), 15 | compile: $compile, 16 | elementType: 'project', 17 | action: 'display' 18 | }); 19 | 20 | fields = window.Jhelpers.getFields(directiveElement); 21 | sections = window.Jhelpers.getSections(directiveElement); 22 | tabs = window.Jhelpers.getTabs(directiveElement); 23 | 24 | }); 25 | }); 26 | 27 | expectedData.tabs.forEach(function(tab) { 28 | describe('should have a set of tabs...\n', function() { 29 | it('...there should be exactly ' + expectedData.tabs.length + ' tabs', function() { 30 | expect(Object.keys(tabs).length).toEqual(expectedData.tabs.length); 31 | }); 32 | 33 | it('...there should be a tab named ' + tab.name + '. ', function() { 34 | expect(tabs[tab.name]).toBeDefined(); 35 | }); 36 | 37 | if(tab.sections) { 38 | it('...there should be exactly ' + tab.sections.length + ' sections on the ' + tab.name + ' tab. ', function() { 39 | expect(Object.keys(tab.sections).length).toEqual(Object.keys(sections).length); 40 | }) 41 | 42 | tab.sections.forEach(function(section) { 43 | it('...on the ' + tab.name + ' tab there should be a section named ' + section.name, function() { 44 | expect(sections[section.name]).toBeDefined(); 45 | }); 46 | 47 | section.fields.forEach(function(field) { 48 | it('...on the ' + tab.name + ' tab, within the ' + section.name + ' section, there should be a field named ' + field.name, function(){ 49 | expect(fields[field.name]).toBeDefined(); 50 | }); 51 | }); 52 | }); // End tab.sections.forEach() 53 | } // End if(tab.sections) 54 | 55 | }); // End describe('should have a set of tabs...') 56 | }); // End expectedData.tabs.forEach() 57 | }); 58 | -------------------------------------------------------------------------------- /Design Before Code/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation on Slideshare](http://www.slideshare.net/CaitlinGeier/design-before-code-thinking-about-accessibility-from-the-ground-up) 2 | [@CaitlinGeier](https://twitter.com/CaitlinGeier) 3 | 4 | --- 5 | ## Design Before Code: Thinking About Accessibility from the Ground Up 6 | * Date: 1/13/17 12:15 pm 7 | * Speakers: Caitlin Geier 8 | * Tags: Design (UI/UX), Soft Skills / Business 9 | * Category: General Session 10 | --- 11 | In web development, accessibility (i.e. making sure people with disabilities can use your site) is often thought of as a technical challenge which can be overcome by teaching developers to use proper semantic elements and well-placed ARIA attributes. In practice, making a site or application accessible usually involves a developer hacking away at the code (and the design) until all of the automated tests pass. If you start with a design that takes the needs of people with disabilities into account, much less time and effort will be needed to make the finished product accessible. This session will include an overview of accessible design principles and will give some practical tips for designers (and for the developers who work with them). 12 | 13 | 14 | -------------------------------------------------------------------------------- /DevOps at Scale Greek Tragedy in 3 Acts/shownotes.md: -------------------------------------------------------------------------------- 1 | https://www.jfrog.com/shownotes/codemash2017-devopsatscale/ 2 | -------------------------------------------------------------------------------- /DevOps at Scale/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](http://www.slideshare.net/jbaruch/devops-scale-greek-tragedy-in-3-acts-as-it-was-presented-at-codemash-2017) 2 | [Show Notes](https://www.jfrog.com/shownotes/codemash2017-devopsatscale/) 3 | --- 4 | ##### DevOps @ Scale 5 | * Date: 1/12/17 2:15 pm 6 | * Speakers: jFrog, Baruch Sadogursky 7 | * Room: Salon E 8 | * Tags: 9 | * Category: Sponsor Session 10 | --- 11 | (Presented by Baruch Sadogursky) Remember the times when one server was enough? And a guy named “sysadmin” was babysitting it along with his other duties of installing MS Office for everybody? For better or for worse, those times are long gone. Today, companies manage tens of thousands of servers and perform thousands of production changes per day. In this talk we will look at the resources, techniques and tools needed for managing DevOps at Scale and we will discuss the challenges that companies encounter when they hit it. 12 | -------------------------------------------------------------------------------- /Docker Container Lifecycles Problem or Opportunity/shownotes.md: -------------------------------------------------------------------------------- 1 | https://www.jfrog.com/shownotes/docker-container-lifecycles-problem-opportunity/ 2 | -------------------------------------------------------------------------------- /Docker and Kubernetes Recipes/docker-kubernetes-recipes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Docker and Kubernetes Recipes/docker-kubernetes-recipes.pdf -------------------------------------------------------------------------------- /Docker and Kubernetes Recipes/readme.adoc: -------------------------------------------------------------------------------- 1 | = Docker and Kubernetes Recipes at Codemash 2017 2 | 3 | So you are a developer but how comfortable are you and your team taking Docker from development to production? Are you hearing developers say, “But it works on my machine!” when code breaks in production? And if you are, how many hours are then spent standing up an accurate test environment to research and fix the bug that caused the problem? Docker provides PODA (Package Once Deploy Anywhere) and helps you reduce the impedance mismatch between dev, test, and production environment and simplifies application deployment. This workshop/session explains how to package, deploy, and scale applications using Docker. It will also cover orchestration frameworks like Docker Engine in Swarm Mode and Kubernetes. 4 | 5 | -------------------------------------------------------------------------------- /Dont Write Secure Code Design Secure Systems/readme.md: -------------------------------------------------------------------------------- 1 | From [@spetryjohnson](https://twitter.com/spetryjohnson) material for [Dont Write Secure Code Design Secure Systems](https://github.com/spetryjohnson/Talk---Dont-Write-Secure-Code-Design-Secure-Systems) 2 | -------------------------------------------------------------------------------- /Fat Controller CQRS Diet/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](http://www.slideshare.net/DerekComartin/fat-controller-cqrs-diet) 2 | [Repository Used](https://github.com/dcomartin/MusicStore) 3 | --- 4 | ##### Fat Controller CQRS Diet 5 | * Date: 1/12/17 8:00 am 6 | * Speakers: Derek Comartin 7 | * Room: Orange 8 | * Tags: .NET 9 | * Category: General Session 10 | --- 11 | Do your controllers need to go on a diet? Fat controllers can quickly lead to tight coupling by the abundance validation, business logic, and data access. Thin out your controllers by only using your web framework for what it’s good at: HTTP, Routing, and Serialization. Attendees will learn to how to organize code by feature by leveraging CQRS and the Mediator pattern to decouple your core business capabilities from your web framework. 12 | -------------------------------------------------------------------------------- /Fragments - the solution to (and cause of) all of android's problems/readme.md: -------------------------------------------------------------------------------- 1 | Fragments: The solution (and cause of) all of Android's problems 2 | ===================================== 3 | 4 | ![Fragments Slide Image](https://raw.githubusercontent.com/myotive/fragments_codemash2017/master/screenshots/presentation_title.PNG) 5 | 6 | * [Slides](https://speakerdeck.com/myotive/fragments-the-solution-to-and-cause-of-all-of-androids-problems-1) 7 | * [Sample Code Repo and References](https://github.com/myotive/fragments_codemash2017) 8 | -------------------------------------------------------------------------------- /From Zero to the Actor Model/readme.md: -------------------------------------------------------------------------------- 1 | From [@tamir_dresher](https://twitter.com/tamir_dresher) material for [From Zero to the Actor Model](http://www.slideshare.net/TamirDresher/from-zero-to-the-actor-model-with-akkanet-codemash2017-tamir-dresher) 2 | -------------------------------------------------------------------------------- /Full Stack ASP.NET Performance/readme.md: -------------------------------------------------------------------------------- 1 | #Full Stack ASP.NET MVC Performance Tuning 2 | 3 | [Slides and Demos](https://github.com/DustinEwers/asp-net-performance) 4 | -------------------------------------------------------------------------------- /Functional Reactive Programming with JavaScript/readme.md: -------------------------------------------------------------------------------- 1 | [Repository](https://github.com/jondejong/functional-reactive-programming) 2 | --- 3 | ##### Functional Reactive Programming with JavaScript 4 | * Date: 1/13/17 9:45 am 5 | * Speakers: Jonathan DeJong 6 | * Room: Orange 7 | * Tags: JavaScript, Functional Programming 8 | * Category: General Session 9 | --- 10 | What is functional programming? What is reactive programming? Taken together, these two programming practice can help break the cycle of unmaintainable spaghetti code in large applications by producing predictable, testable, composable code. In this talk, we’ll cover the fundamentals of functional and reactive programming in JavaScript. We’ll look the reactive extensions project (RxJS), as well as Redux, and see how these can be utilized to manage complex intereactions and produce predicatable systems. We’ll also look at how these practices can be used to make life easier in major front end frameworks, including Angular 2, React, and Vue. 11 | -------------------------------------------------------------------------------- /GraphQL What it is and why you should care/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](https://github.com/superchris/graphql-slides) 2 | --- 3 | ##### GraphQL: What it is and why you should care 4 | * Date: 1/13/17 11:00 am 5 | * Speakers: Chris Nelson 6 | * Room: Sagewood, Zebrawood 7 | * Tags: Cloud/Big Data, JavaScript 8 | * Category: General Session 9 | --- 10 | GraphQL is an open specification created by Facebook for exchanging data between a client and server. It turns REST on its head by letting the client ask for exactly the data it needs rather than the server sending whatever it thinks is best. In this talk, attendees will learn about what GraphQL is and the basic syntax. We’ll see how it works on the client and the server, and how it can be used to solve some of the most frustrating problems in modern web app development. We’ll also see how powerful features like schema introspection allow you to do things in web development we’ve never been able to do before. Expect to come away with a good understanding of where and how to harness GraphQL on your next project. 11 | -------------------------------------------------------------------------------- /Hacking and Hardening Java Web Applications/readme.md: -------------------------------------------------------------------------------- 1 | From [@javajudd](https://twitter.com/javajudd) [slides](https://s3.amazonaws.com/cmj-presentations/hacking-codemash-2017.pdf) and [VM](http://prereqs.codemash.org/Files/hhjwa-2016.1-vbox-amd64.ova) for Hacking & Hardening Java Web Applications workshop. 2 | -------------------------------------------------------------------------------- /Horizontally Scaling Nodejs and WebSockets/readme.md: -------------------------------------------------------------------------------- 1 | 2 | [Repository](https://github.com/goldfire/Horizontally-Scaling-Node.js-Websockets-Talk) 3 | [Presentation](http://www.slideshare.net/goldfire33/horizontally-scaling-nodejs-and-websockets/1) 4 | [In More Depth Article](http://goldfirestudios.com/blog/136/Horizontally-Scaling-Node.js-and-WebSockets-with-Redis) 5 | --- 6 | ##### Horizontally Scaling Node.js and WebSockets 7 | * 1/13/17 8:30 am 8 | * Speakers: James Simpson 9 | * Room: Indigo Bay 10 | * Tags: Cloud/Big Data, JavaScript 11 | * Category: General Session 12 | --- 13 | Underneath every breakout website or app is a horizontally scaling back-end, but how do we get from a single process Node.js server to a highly-available, auto-scaling system? In this talk, we’ll take a high level look at a full production stack before getting our hands dirty with the secret sauce: Node.js, WebSockets and Redis. Through a live coding demo, you’ll learn how to take a single-server app and scale it infinitely. Walk away with a better conceptual understanding of high-scale web systems and practical tools to start implementing these techniques in your own projects today. 14 | -------------------------------------------------------------------------------- /How to Disclose a Security Vulnerability/README.md: -------------------------------------------------------------------------------- 1 | # "How to disclose a security vulnerability" Reading List 2 | 3 | Talk by Carol (Nichols || Goulding) 4 | 5 | Twitter: [@Carols10cents](https://twitter.com/Carols10cents) 6 | 7 | Below are all the resources and links I mentioned in my talk; this may be more 8 | useful than the slides! 9 | 10 | ## Todo List 11 | 12 | 1. Make a keypair - instructions at [PGP and You](https://robots.thoughtbot.com/pgp-and-you) 13 | 2. Share it via [Keybase](https://keybase.io/) or a key server so people can verify it belongs to you 14 | 3. Send encrypted emails to a friend for practice. Once you have gpg2 installed: 15 | 16 | $ gpg2 ——import recipients-public-key.asc 17 | 18 | # write the body of your email in message.txt 19 | # e = encrypt, a = ascii, r = recipient 20 | $ gpg2 -ea -r Recipient message.txt 21 | 22 | $ pbcopy < message.txt.asc 23 | # paste into an email and send! 24 | 25 | # Copy reply encrypted with your public key 26 | # from your email into reply.txt.asc 27 | $ pbpaste > reply.txt.asc 28 | 29 | # d = decrypt 30 | $ gpg2 -d reply.txt.asc 31 | 32 | # enter your password and receive plain text! 33 | 34 | 4. Add contact info + public key to your open source projects for people to report vulnerabilities 35 | 5. At work, add a `/security` contact page 36 | * [DNSimple](https://dnsimple.com/security) 37 | * [Sample security page to copy](https://responsibledisclosure.nl/en/) 38 | 39 | ## Secure communications 40 | 41 | * [Signal](https://whispersystems.org/) 42 | 43 | ## Security vulnerability I found 44 | 45 | * [Rust security announcement](https://groups.google.com/forum/#!topic/rustlang-security-announcements/BK_3gbXhSn4) 46 | * [Rust security policy](https://www.rust-lang.org/en-US/security.html) 47 | 48 | ## Books and articles 49 | 50 | * [Bug Hunter's Diary](https://www.nostarch.com/bughunter) 51 | * [Locks and Safes: The construction of locks, 1868](https://books.google.com/books?id=by1bAAAAcAAJ) 52 | * [Scott Culp: It's time to end Information Anarchy, Oct 2001](http://web.archive.org/web/20040227175033/http://www.microsoft.com/technet/columns/security/essays/noarch.asp) 53 | * [Bruce Schneier on The Window of Exposure, Nov 2001](https://www.schneier.com/crypto-gram/archives/2001/1115.html) 54 | * [Katie Moussouris on Microsoft using the words Coordinated Disclosure instead of Responsible Disclosure, July 2010](https://blogs.technet.microsoft.com/ecostrat/2010/07/22/coordinated-vulnerability-disclosure-bringing-balance-to-the-force/) 55 | * [Adam Caudill: Responsible Disclosure is Wrong Nov 2015](https://adamcaudill.com/2015/11/19/responsible-disclosure-is-wrong/) 56 | * [howdoireportavuln.com](http://howdoireportavuln.com/) 57 | 58 | ## Case studies 59 | 60 | ### GitHub/Rails Mass Assignment - Mar 2012 61 | 62 | * [Original bug report about insecure defaults](https://github.com/rails/rails/issues/5228) 63 | * [Explanation of the problem](https://gist.github.com/peternixey/1978249) 64 | * [Commit homakov made to rails/rails](https://github.com/rails/rails/commit/b83965785db1eec019edf1fc272b1aa393e6dc57) 65 | * [GitHub incident report](https://github.com/blog/1068-public-key-security-vulnerability-and-mitigation) 66 | * [GitHub's responsible disclosure policy](https://github.com/blog/1069-responsible-disclosure-policy) 67 | * [Homakov's blog post with an update from 2014 containing regrets](http://homakov.blogspot.com/2012/03/how-to.html) 68 | 69 | ### Rubygems YAML - Jan 2013 70 | 71 | * [Hacker news thread](https://news.ycombinator.com/item?id=5139583) 72 | * [Incident response google doc](https://docs.google.com/document/d/10tuM51VKRcSHJtUZotraMlrMHWK1uXs8qQ6Hmguyf1g/preview) 73 | * [Venturebeat article](http://venturebeat.com/2013/01/30/rubygems-org-hacked-interrupting-heroku-services-and-putting-millions-of-sites-using-rails-at-risk/) 74 | * [Underlying library issue](https://github.com/ruby/psych/issues/119) 75 | * [Tenderlove blog post explanation](http://tenderlovemaking.com/2013/02/06/yaml-f7u12.html) 76 | -------------------------------------------------------------------------------- /How to Disclose a Security Vulnerability/license.txt: -------------------------------------------------------------------------------- 1 | All content in this directory is under a Creative Commons Attribution-ShareAlike 3.0 Unported License ( http://creativecommons.org/licenses/by-sa/3.0/ ) -------------------------------------------------------------------------------- /How to Disclose a Security Vulnerability/slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/How to Disclose a Security Vulnerability/slides.pdf -------------------------------------------------------------------------------- /How to Have the Best Dates Ever/Readme.md: -------------------------------------------------------------------------------- 1 | ### How to Have the Best Dates Ever! 2 | #### (On date, time, and time zones in programming.) 3 | 4 | Matt Johnson 5 | [@mj1856](http://twitter.com/mj1856) 6 | [codeofmatt.com](http://codeofmatt.com) 7 | 8 | - [CodeMash Link](http://www.codemash.org/session/how-to-have-the-best-dates-ever-on-date-time-and-time-zones-in-programming/) 9 | - [Slides](http://codeofmatt.com/content/images/best-dates-ever.pdf) 10 | -------------------------------------------------------------------------------- /How to Have the Best Dates Ever/readme.md: -------------------------------------------------------------------------------- 1 | ### How to Have the Best Dates Ever! 2 | #### (On date, time, and time zones in programming.) 3 | 4 | Matt Johnson 5 | [@mj1856](http://twitter.com/mj1856) 6 | [codeofmatt.com](http://codeofmatt.com) 7 | 8 | - [CodeMash Link](http://www.codemash.org/session/how-to-have-the-best-dates-ever-on-date-time-and-time-zones-in-programming/) 9 | - [Slides](http://codeofmatt.com/content/images/best-dates-ever.pdf) 10 | -------------------------------------------------------------------------------- /How to Hire Programmers You'll Want as Teammates/readme.md: -------------------------------------------------------------------------------- 1 | From [@tscottdrake](https://twitter.com/tscottdrake) material for [How to Hire Programmers You'll Want as Teammates](http://www.scottdrakeblog.com/codemash2017/) 2 | -------------------------------------------------------------------------------- /How to write Java web apps like a JS hipster/readme.md: -------------------------------------------------------------------------------- 1 | # How to write Java web apps like a JS hipster 2 | ### Stephen Shary 3 | > It’s easy to find a web-developer position at an enterprise company and spend multiple years writing code in a language that was bleeding edge 10 years ago. Passionate developers go home and continually spend time learning new languages and writing in new styles that allow them to stay up-to-date. Not everyone is up for that lifestyle and the daily grind can be miserable when you’re limited on technology choices. This session focuses on the changes that have been made in the past couple of years to allow Java to go through a “renewal” so that developers now have the ability to write code that is so similar to modern Javascript server applications. It will demonstrate how Java8, Spring Boot, AsyncIO allow developers to write code in a modern way that is concise, fast, scalable and just as “cool” as the startup in the loft downtown. 4 | 5 | Slides: https://github.com/STeveShary/CodeMash2017-Talks/blob/master/Java-JS-Hipster.pdf 6 | -------------------------------------------------------------------------------- /Implementing Binary Protocols With Elixir/readme.md: -------------------------------------------------------------------------------- 1 | From [@CodeStars](https://twitter.com/CodeStars) material for [Implementing Binary Protocols With Elixir](https://slidr.io/nesQuick/implementing-binary-protocols-with-elixir-1#1) 2 | -------------------------------------------------------------------------------- /Incredibly Strange Programming Languages/readme.md: -------------------------------------------------------------------------------- 1 | Incredibly Strange Programming Languages 2 | ======================================== 3 | 4 | * [Slides](https://speakerdeck.com/craigstuntz/incredibly-strange-programming-languages-codemash-1) 5 | * [Slides with speaker notes](https://speakerdeck.com/craigstuntz/incredibly-strange-programming-languages-codemash-2017-with-notes) 6 | * [Preroll quotes](https://speakerdeck.com/craigstuntz/incredibly-strange-programming-languages-codemash-2017-preroll) 7 | 8 | If you’ve ever suspected that “all programming languages are pretty much the same; they just have 9 | different syntax,” well, you will never suspect that again! Covering languages from the unusually 10 | powerful (Idris) to the illuminated (قلب) to the profoundly limited (BlooP), and all points in 11 | between, these languages will help you think differently about approaches to software problems you 12 | face in your day job. Of course we’ll have a lot of fun, but these languages are no joke. The 13 | practical benefit of an impractical language is the power to find new approaches to common 14 | problems. 15 | -------------------------------------------------------------------------------- /Integrating React Into A Legacy Web App/readme.md: -------------------------------------------------------------------------------- 1 | From [@mudetroit](https://twitter.com/mudetroit) material for [Integrating React Into A Legacy Web App](https://github.com/mudetroit/integrating-react-into-a-legacy-web-app) 2 | 3 | --- 4 | ##### Integrating React into a legacy web app 5 | * Date: 1/12/17 9:15 am 6 | * Speakers: Matthew LaForest 7 | * Room: Salon H 8 | * Tags: JavaScript 9 | * Category: General Session 10 | --- 11 | 12 | You know the web app, the one started 6 years ago, before all of these cool new JS technologies came along. Creaking with a 3 year old copy of jQuery loaded down with 30 some plugins of code that is almost impenetrable. You would like to modernize it but you don’t even know where to start. You have a working site, and know the pitfalls of the dreaded “rewrite”. How do you integrate the new tooling along side what is already there and allow yourself to build something knew. Learn how you can integrate React seamlessly into a legacy web application. Have it slowly take on more responsibility as you let it become your new codebase. 13 | -------------------------------------------------------------------------------- /Introducing Managed Effects/README.md: -------------------------------------------------------------------------------- 1 | # Introducing Managed Effects to your Enterprise Front-ends 2 | 3 | ### Kofi Gumbs 4 | 5 | 6 | Effect management sounds like an abstract paradigm with few tangible benefits, 7 | so many dismiss it out of hand. 8 | That is a mistake. 9 | 10 | Managed effects are natural extensions of common design patterns. 11 | It emphasizes separation of business logic 12 | and implementation details on a whole new level. 13 | 14 | This may sound like a big change, 15 | but it is easy to adopt effect management in incremental steps: 16 | no re-writes required! 17 | 18 | Using Elm as an example, 19 | the speaker will explore the observable benefits 20 | that managed effects can have on your project. 21 | You will walk away with a new appreciation for the paradigm 22 | and the knowledge required to start implementing it today. 23 | 24 | 25 | 26 | 27 | --------|-------- 28 | Blog | https://8thlight.com/blog/kofi-gumbs 29 | Twitter | https://twitter.com/hkgumbs 30 | 31 | -------------------------------------------------------------------------------- /Introducing Managed Effects/slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Introducing Managed Effects/slides.pdf -------------------------------------------------------------------------------- /Java 8 Puzzlers The strange the bizarre and the wonderful/shownotes.md: -------------------------------------------------------------------------------- 1 | https://www.jfrog.com/shownotes/codemash2017-java8puzzlers/ 2 | -------------------------------------------------------------------------------- /JavaScript Robotics - Not a Bad Idea/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](http://briangenisio.com/js-robotics) 2 | [Repository](https://github.com/BrianGenisio/js-robotics) 3 | [CodePen Demo](http://codepen.io/BrianGenisio/pen/PbaLKo) 4 | ####### Learn More: 5 | [Johnny-Five](http://johnny-five.io) 6 | [Johnny-Five Chat](https://gitter.im/rwaldron/johnny-five) 7 | [NodeBots](http://nodebots.io/) 8 | --- 9 | ##### JavaScript Robotics? Not a Bad Idea 10 | * 1/12/17 11:45 am 11 | * Speakers: Brian Genisio 12 | * Room: Mangrove 13 | * Tags: JavaScript 14 | * Category: General Session 15 | --- 16 | JavaScript is seeing its renaissance right now. All the cool kids are coding JavaScript everywhere they can. But robotics? Really? Doesn’t that sound like a bad idea? I’d like to show you the opposite: why JavaScript robotics is NOT a bad idea! It turns out that the same things that make JavaScript great for the web also make JavaScript great for robotics. Enter Johnny-Five: a JavaScript robotics platform with beautiful abstractions. We’ll discover the power of Johnny-Five and explore the possibilities of controlling low-cost electronics to manipulate the real world with a much more accessible language than C/C++. 17 | -------------------------------------------------------------------------------- /Lets Write a Lambda Calculus in Haskell/LambdaCal.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import System.Environment 4 | 5 | data Token = 6 | LParen 7 | | RParen 8 | | Dot 9 | | Backslash 10 | | Alpha Char 11 | 12 | alphabet :: String 13 | alphabet = "abcdefghijklmnopqrstuvwxyz" 14 | 15 | tokenize :: String -> [Token] 16 | tokenize [] = [] 17 | tokenize ('(':rest) = LParen:tokenize rest 18 | tokenize (')':rest) = RParen:tokenize rest 19 | tokenize ('.':rest) = Dot:tokenize rest 20 | tokenize ('\\':rest) = Backslash:tokenize rest 21 | tokenize (char:rest) = 22 | (if elem char alphabet 23 | then [Alpha char] 24 | else []) ++ tokenize rest 25 | 26 | data Term = 27 | Var Char 28 | | Lambda Char Term 29 | | Closure Char Term Env 30 | | App Term Term 31 | 32 | parse :: [Token] -> Term 33 | parse tokens = fst (parseSingle tokens) 34 | 35 | parseSingle :: [Token] -> (Term, [Token]) 36 | parseSingle (Alpha c:rest) = (Var c, rest) 37 | parseSingle (Backslash:Alpha argName:Dot:bodyToks) = 38 | let 39 | (body, rest) = parseSingle bodyToks 40 | in 41 | (Lambda argName body, rest) 42 | parseSingle (LParen:innerToks) = 43 | let 44 | (first, secondToks) = parseSingle innerToks 45 | (second, RParen:rest) = parseSingle secondToks 46 | in 47 | (App first second, rest) 48 | parseSingle _ = error "Parser error" 49 | 50 | eval :: Term -> Term 51 | eval = evalInEnv [] 52 | 53 | type Env = [(Char, Term)] 54 | 55 | evalInEnv :: Env -> Term -> Term 56 | evalInEnv env (Var name) = 57 | case lookup name env of 58 | Nothing -> error "Name not found" 59 | Just t -> t 60 | evalInEnv env (Lambda argName body) = Closure argName body env 61 | evalInEnv env (App fn op) = 62 | let 63 | (Closure argName body enclosedEnv) = evalInEnv env fn 64 | evaluatedOp = evalInEnv env op 65 | newEnv = (argName, evaluatedOp):enclosedEnv ++ env 66 | in 67 | evalInEnv newEnv body 68 | evalInEnv _ closure = closure 69 | 70 | pretty :: Term -> String 71 | pretty (Var name) = [name] 72 | pretty (App fn op) = concat ["(", pretty fn, " ", pretty op, ")"] 73 | pretty (Lambda argName body) = concat ["\\", [argName], ".", pretty body] 74 | pretty (Closure argName body _) = concat ["\\", [argName], ".", pretty body] 75 | 76 | interp :: String -> String 77 | interp = pretty . eval . parse . tokenize 78 | 79 | main :: IO () 80 | main = do 81 | args <- getArgs 82 | case args of 83 | [code] -> putStrLn (interp code) 84 | _ -> putStrLn "Where's the code?" 85 | -------------------------------------------------------------------------------- /Lets Write a Lambda Calculus in Haskell/Let's Write a Lambda Calculus in Haskell.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Lets Write a Lambda Calculus in Haskell/Let's Write a Lambda Calculus in Haskell.pdf -------------------------------------------------------------------------------- /Lets Write a Lambda Calculus in Haskell/README.mkd: -------------------------------------------------------------------------------- 1 | # Let's Write a Lambda Calculus in Haskell 2 | Michael Gilliland - CodeMash 2017 3 | 4 | ## [LambdaCal.hs](LambdaCal.hs) 5 | The interpreter, unchanged from the live-coding session. 6 | 7 | To compile it, get `ghc` (using `haskell-platform`, `slack` or something else) then run 8 | ```bash 9 | ghc -o lc LambdaCal.hs 10 | ``` 11 | 12 | Run an example 13 | ```bash 14 | ./lc "(\x.x \y.y)" 15 | ``` 16 | 17 | 18 | ## [Let's Write a Lambda Calculus in Haskell.pdf](Let's Write a Lambda Calculus in Haskell.pdf) 19 | The slides given as an introduction to the lambda calculus. 20 | -------------------------------------------------------------------------------- /Life After Nil/Readme.md: -------------------------------------------------------------------------------- 1 | # Life After Nil 2 | 3 | Ruby is late to the type system party. Let’s give Ruby something smart to say when it gets there. You’ll take a journey with Haskell’s type system. Along the way, you’ll learn how types can let you forget about nil, declaratively model your domain, and allow your compiler to drive your design. 4 | 5 | ## Description 6 | 7 | There are murmurs that a type system will be coming to Ruby. Before that happens, you should get informed about what is hot in the current type system market. Haskell is known for its type system, but instead of describing it with dense language, let’s take a journey through code examples. Throughout our trip, we will avoid scary buzzwords like “monad” and “algebraic data type” because, honestly, what good is a formal definition when you don’t understand the power behind the concept? 8 | 9 | We will compare solutions in Ruby to solutions in Haskell, and each stop on our trip will introduce a new mind-blowing paradigm brought to you by Haskell’s type system. You will learn about type systems through a non-threatening story, and you’ll understand the value a type system can bring to your code. Key stops on our route will be “forget about nil”, “declaratively model your domain”, and “allow your compiler to drive your design”. 10 | 11 | ## Watch The Video 12 | 13 | The [Video][Video]. 14 | 15 | ## About the Speaker 16 | 17 | Sam Jones [@samjonester][Twitter] 18 | 19 | I have been learning Haskell as a hobby, and I’ve been blown away by it’s elegant handling of Optional data, and the powerful way in which the type system drives the design of my code. I was originally a Java developer, so I am familiar with typical OOP strong typing. However, Haskell’s type system was such a different and enlightening experience, that I’d LOVE to help light that bulb over the heads of many more Rubyists. 20 | 21 | I am a double agent at Test Double living in Philadelphia, PA. I have a passion for learning and teaching. I love the ruby community for its inclusivity, and also for fostering such an amazing community. Ruby is a place where anyone can share ideas and code. I am a cook and cyclist in my free time, as well as a Husband and Father. 22 | 23 | ## Relevant links 24 | 25 | - [Maybe Haskell][MaybeHaskell] 26 | - [Learn You A Haskell][LearnYou] 27 | - [Trying Haskell][Haskell] 28 | 29 | [MaybeHaskell]: http://maybe-haskell.com 30 | [LearnYou]: http://learnyouahaskell.com/ 31 | [Haskell]: https://www.haskell.org/ 32 | [Video]: https://vimeo.com/200077718 33 | [Twitter]: https://twitter.com/samjonester 34 | -------------------------------------------------------------------------------- /Mashing Up QA and Security/readme.md: -------------------------------------------------------------------------------- 1 | Mashing Up QA and Security 2 | ========================== 3 | 4 | * [Slides](https://speakerdeck.com/craigstuntz/mashing-up-qa-and-security-codemash-2017) 5 | * [Slides with speaker notes](https://speakerdeck.com/craigstuntz/mashing-up-qa-and-security-codemash-2017-with-notes) 6 | * [Preroll quotes](https://speakerdeck.com/craigstuntz/mashing-up-qa-and-security-preroll-quotes) 7 | * [Fizil repository](https://github.com/CraigStuntz/Fizil) 8 | 9 | Security is domain specific quality assurance, but developers, testers, and security 10 | professionals often don’t work together. When this type of disconnect exists between 11 | big groups of people who are very good at their jobs, there is usually a mostly 12 | untapped potential for learning. I’ve been exploring this landscape by writing an 13 | open source fuzzer aimed at discovering new test cases (not just crashes!) using 14 | binary rewriting of managed executables and genetic modification of a test corpus, 15 | implemented in F# and using Mono.Cecil. I’ll contrast the fundamentals of each 16 | discipline, demonstrate tools used by experts on both sides of the security and QA 17 | fence, and challenge the audience to find new ways to mix them up. Expect to see lots 18 | of code and leave with ideas for making entire communities better, not just your own 19 | team! 20 | -------------------------------------------------------------------------------- /Migrating the Monolithic to the Microscopic/README.md: -------------------------------------------------------------------------------- 1 | [Repository and Presentation](https://github.com/mcollier/MigratingTheMonolithicToTheMicroscopic) 2 | --- 3 | ##### Migrating the Monolithic to the Microscopic 4 | * 1/13/17 9:45 am 5 | * Speakers: Michael Collier 6 | * Room: Salon A 7 | * Tags: Cloud/Big Data, .NET 8 | * Category: General Session 9 | --- 10 | 11 | Many people are talking about adopting microservices and moving away from the monolithic application. But how do you go about moving to a microservices based architecture? How do you host your microservices reliably on Azure Service Fabric? In this session we’ll provide a brief review of microservices and Service Fabric principals. We’ll then quickly move into a through discussion of field proven strategies for transforming development and IT teams to utilizes these technologies. We’ll review real-world customer examples of how to best handle deployments, monitoring, securing, and generally managing services with Azure Service Fabric. -------------------------------------------------------------------------------- /Netflix Culture Freedome and Responsibility/readme.md: -------------------------------------------------------------------------------- 1 | From [@SonOfGarr](https://twitter.com/SonOfGarr) material for [Netflix Culture Freedome and Responsibility](http://www.slideshare.net/reed2001/culture-1798664) 2 | -------------------------------------------------------------------------------- /Patterns of Effective Test Setup/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation and Repository](https://github.com/spetryjohnson/Talk-Patterns_of_Effective_Test_Setup) 2 | --- 3 | ##### Patterns of Effective Test Setup 4 | * Date:1/12/17 10:30 am 5 | * Speakers: Seth Petry-Johnson 6 | * Room: Orange 7 | * Tags: .NET, JavaScript, Testing 8 | * Category: General Session 9 | --- 10 | Writing clean, effective, and manageable tests begins with the “fixture”, the set of data used in the test. If you’ve ever struggled with the “arrange” part of a test, or if you’ve ever looked at someone else’s “arrange” and struggled to understand the context it establishes, then you’ve suffered the pains of poor fixture setup. In this session you’ll see a collection of patterns and techniques that will help you write smaller, more expressive tests that are easier to read, understand and maintain. We’ll talk about patterns for constructing test data for unit tests, patterns for saving that data in the database for integration tests, and some common anti-patterns that you may not realize you’re following. Code samples will be in C# and NUnit but the core concepts will be presented in a language-agnostic way and are applicable in many contexts. “Clean setup begets clean tests”. Let me show you how. 11 | -------------------------------------------------------------------------------- /Practical Data Science with R/readme.md: -------------------------------------------------------------------------------- 1 | From [@MatthewRenze](https://twitter.com/matthewrenze) material for [Practical Data Science with R](http://www.matthewrenze.com/workshops/practical-data-science-with-r/) 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /PracticalAtdd/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | [Repository](https://github.com/dmorgan3405/practical-atdd) (Note: Contains presentation) 3 | --- 4 | ##### Behave Yourself, A practical guide to ATDD in python 5 | * 1/11/17 8:00 am 6 | * Speakers: Doug Morgan 7 | * Room: Salon D 8 | * Category: Pre-Compiler 9 | --- 10 | 11 | So you can sling some code and automate a web browser, and even work on a team that has a fair bit of UI automation around your “favorite” web application. No doubt you have found yourself spending to much time fixing an inconsistent suite of tests. You might even be asking yourself “are these tests even worth it?”. (the answer is yes!) Lets explore where things typically break down in the acceptance testing process. Starting with breaking user stories into acceptance criteria, and how the words the team chooses can affect the software that is built. Then taking a deep dive into best patterns and practices in automating the scenarios with Behave and other python modules. Along the way answering questions such as how should I manage my test data? Should I ever delete tests? And, how do I keep my test pyramid from becoming a test cupcake? Attendees will walk away from this session armed with information to help them write better acceptance criteria, and tips to keep their test suites clean and less brittle. 12 | -------------------------------------------------------------------------------- /Preparing for This Augmented Life/readme.md: -------------------------------------------------------------------------------- 1 | From [@heathriel](https://twitter.com/heathriel) material for [Preparing for This Augmented Life](http://www.slideshare.net/HeatherWilde/preparing-for-this-augmented-life) 2 | -------------------------------------------------------------------------------- /Programmers dont have to suck at UX and UI/readme.md: -------------------------------------------------------------------------------- 1 | From [@sbastn](https://twitter.com/sbastn) material for [Programmers don't have to suck at UX and UI](https://slidr.io/sbastn/programmers-don-t-have-to-suck-at-ux-and-ui#1) 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CodeMash 2017 ![CodeMash Logo](https://doorcomp.blob.core.windows.net/doorcomp/Codemash%20Gearhead%20200.png) 2 | ============ 3 | 4 | CodeMash v2.0.1.7 session decks, sample code, links and other stuff. 5 | 6 | Speakers: please feel free to send me pull requests with any of your content that you want to share with the CodeMash attendees. This way we have a single place for attendees to go and get content. 7 | 8 | Organization: fork this repository and put your session materials, links or anything else in a subdirectory named with the same name as your session. Then send a pull request and I will merge it in. See the sample for an example of how it could work. 9 | 10 | --- 11 | 12 | *Note that this is a volunteer effort and is not representing CodeMash in any official way. Thanks! 13 | -------------------------------------------------------------------------------- /React Everywhere/readme.md: -------------------------------------------------------------------------------- 1 | From [@ignu](https://twitter.com/ignu) material for [React Everywhere](http://ignu.me/react-everywhere/) 2 | --- 3 | title: React Everywhere 4 | date: "2017-01-12T22:40:32.169Z" 5 | layout: post 6 | path: "/react-everywhere" 7 | tags: 8 | - speaking 9 | - react 10 | --- 11 | 12 | Thanks for everyone who came my React workshop at [CodeMash](http://codemash.org)! Please leave feedback in the [EventsXD](https://eventsxd.com/download) App. 13 | 14 | ### Repositories used in the session: 15 | 16 | * [Web Demo](https://github.com/ignu/react-everywhere-web-demo) [(deployed here)](http://codemash.surge.sh) 17 | * [Native Demo for React Everywhere](https://github.com/ignu/react-everywhere-native-demo) 18 | * [The project we were building during the day](https://github.com/ignu/codemash-react-workshop) 19 | * [Slides](https://github.com/ignu/react-everywhere-workshop) (you'll need to `npm install && npm run`) to view them 20 | 21 | ## More feature ideas, if you still want to hack: 22 | 23 | * Store data offline using [redux-persist](https://github.com/rt2zz/redux-persist) 24 | * Move the initial `fetch` into the redux store using [redux-thunk](https://github.com/gaearon/redux-thunk) 25 | * Update the title using [react-helmet](https://github.com/nfl/react-helmet) 26 | * Filter Sessions that are in the past 27 | * List a Speaker's sessions on their page 28 | * Filter by Tag 29 | 30 | # Further Learning/Playing 31 | 32 | ### React 33 | 34 | * [Getting Started with Redux - Course by @dan_abramov](https://egghead.io/courses/getting-started-with-redux) 35 | * [FormidableLabs/react-music: Make beats with React!](https://github.com/FormidableLabs/react-music) 36 | * [awesome-react: A collection of awesome things regarding React ecosystem.](https://github.com/enaqx/awesome-react) 37 | 38 | ### React Native 39 | 40 | * [ReactNativeKatas](https://github.com/jondot/ReactNativeKatas) ahands-on, and fun learning experience for React Native 41 | * [React Native Playground: Play with React Native in browser](https://rnplay.org/) 42 | * [React Native Radio](https://devchat.tv/react-native-radio) 43 | * [este](http://github.com/este/este) starter kit for one code base for client-side web, server, iOS and Android 44 | * [Awesome React Native](https://github.com/jondot/awesome-react-native) 45 | -------------------------------------------------------------------------------- /Real-time Server Telemetry-The downfall of logging and rise of data pipelines/readme.md: -------------------------------------------------------------------------------- 1 | # Real-time Server Telemetry: The downfall of logging and rise of data pipelines 2 | ### Stephen Shary 3 | > Logging in modern applications is a feast or famine. Every scrap of information is needed when triaging production issues, but who can find relevant information among all the DEBUG and PERFORMANCE lines? Logging to files and STDOUT has become incompatible with cloud-native applications and distributed systems (and most other things). Modern telemetry and APM solutions need to tackle the issue of finding needles in haystacks as well as view the system from 50,000 feet with real-time data. Hear the story of our experiences at Kroger creating an open-source-based system including Elastic Search that handles over 900GBs of data each day. See how we visualize our current production status and discover problematic applications, servers and systems 4 | 5 | Slides: https://github.com/STeveShary/CodeMash2017-Talks/blob/master/ServerTelemetry.pdf -------------------------------------------------------------------------------- /Rules as an Architectural Pattern For Development/readme.md: -------------------------------------------------------------------------------- 1 | Rules as an Architectural Pattern For Development 2 | 3 | 1/13/2017 4:00 pm 4 | 5 | Speakers: Steve Swing 6 | 7 | Room: Nile 8 | 9 | Tags: Testing, Java, Functional Programming 10 | 11 | Category: General Session 12 | 13 | Rule-based architectural patterns produce solutions that are highly performant, composable, loosely coupled, flexible, and can be thoroughly tested. A rule-based approach to application logic integrates well with other architectural patterns such as big data analysis output, streaming data pipelines for real-time processing, or message-oriented processing. Rule-based architectures complement microservices architectures too. Large unwieldy opaque rule engines of the past are not required. Nor are rule-specialized languages and tooling. Developers don’t need specialized training when rules are implemented with the language of the project, available collections API, and business domain language. This session describes an internal architectural pattern to implement complex business logic to deliver quality software that endures. The concepts can be implemented in any language. 14 | 15 | Slides: 16 | 17 | [https://github.com/steveswing/cere/blob/master/Rules%20as%20an%20Architectural%20Pattern%20For%20Development-CodeMash.pdf](https://github.com/steveswing/cere/blob/master/Rules%20as%20an%20Architectural%20Pattern%20For%20Development-CodeMash.pdf) 18 | 19 | Related Source Repository: 20 | 21 | [https://github.com/steveswing/cere/](https://github.com/steveswing/cere/) 22 | -------------------------------------------------------------------------------- /SQL Server Perfomance Tuning/readme.md: -------------------------------------------------------------------------------- 1 | From [@TheSQLGuru](https://twitter.com/TheSQLGuru) material for [SQL Server Perfomance Tuning](https://www.dropbox.com/s/6pihzwdpthz6pum/SQLServerPerformanceTuning101_TheSQLGuru.zip?dl=0) 2 | -------------------------------------------------------------------------------- /Scale Your Node Application Skip the Infrastructure/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](https://speakerdeck.com/technovangelist/scale-your-node-application-dot-dot-dot-forget-the-infrastructure) 2 | --- 3 | ##### Scale Your Node Application, Skip the Infrastructure 4 | * 1/12/17 1:00 pm 5 | * Speakers: Matthew Williams 6 | * Room: Guava, Tamarind 7 | * Tags: Cloud/Big Data, Other, JavaScript 8 | * Category: General Session 9 | --- 10 | You don’t have to look far to find yet another article on scaling your NodeJS app to handle large numbers of users. But the techniques covered usually involve becoming an expert in deploying hardware or a guaranteed minimum outlay of cash to handle your expected load. But what if there were a way to scale almost infinitely without having to worry about the infrastructure to run any of it. Using platforms like AWS Lambda, Azure Functions, and IBM OpenWhisk, you can focus on providing scalable functionality in your NodeJS application without having to think about any of infrastructure details. In this session, Matt Williams will show you how to get started building a complex Node application on AWS Lambda from scratch. Starting with the standard CLI, we move to other frameworks like Node Lambda and Serverless to add more functionality to serve your users. We will consider some key architectural decisions that affect how the application is designed. And all the way along we look at ways to monitor the application to help find the bottlenecks. By the end of the session, you will be eager to start working on your next application on AWS Lambda 11 | -------------------------------------------------------------------------------- /Shiny Lets Be Bad Guys/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](https://speakerdeck.com/mpirnat/shiny-lets-be-bad-guys-exploiting-and-mitigating-the-top-10-web-app-vulnerabilities-codemash-2017-edition) 2 | [Repository used](https://github.com/mpirnat/lets-be-bad-guys) 3 | 4 | --- 5 | ##### Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulnerabilities 6 | * Date: 1/11/17 1:00 pm 7 | * Speakers: Mike Pirnat 8 | * Room: Aloeswood, Leopardwood 9 | * Tags: Other, Security 10 | * Category: Pre-Compiler 11 | --- 12 | The Internet is a dangerous place, filled with evildoers out to attack your code for fun or profit, so it’s not enough to just ship your awesome new web app–you have to take the security of your application, your users, and your data seriously. You’ll get into the mindset of the bad guys as we discuss, exploit, and mitigate the most common web app security flaws in a controlled environment. We’ll discuss each kind of the most prevalent security flaws at the theoretical level; then using a specially-crafted, deliberately vulnerable app, individuals or pairs will carry out exploits against these flaws, and we’ll discuss strategies for mitigating each type of attack in several popular Python frameworks. 13 | 14 | We’ll be using the [OWASP Top 10](https://www.owasp.org/index.php/Top_10_2013-Top_10) as our topic roadmap, addressing issues such as: 15 | * Injection Attacks 16 | * Broken Authentication & Session Management 17 | * Cross-Site Scripting (XSS) 18 | * Insecure Direct Object References 19 | * Security Misconfiguration 20 | * Sensitive Data Exposure 21 | * Missing Function-Level Access Control 22 | * Cross-Site Request Forgery (CSRF) 23 | * Using Components with Known Vulnerabilities 24 | * Unvalidated Redirects and Forwards 25 | 26 | You’ll want to set your brain to “devious” mode; you’ll also need a laptop with Python 2.7 or 3.3 (or a buddy you can pair with). Having pip and virtualenv will be useful too, as will having Git installed to pull down the code we’ll be working with. Attendees **do not need prior security experience**; this tutorial is aimed at **intermediate web developers** who are interested in gaining hands-on experience with **simple forms of the most common attacks**. Attendees should have some experience with **Python, Javascript, and SQL**, and may benefit from at least a passing familiarity with Django (eg, previously attending a Django tutorial or working through the [online tutorial](https://docs.djangoproject.com/en/1.10/intro/tutorial01/)). 27 | -------------------------------------------------------------------------------- /Sowing-Seeds-of-STEM-thru-TechnoFashion/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Sowing-Seeds-of-STEM-thru-TechnoFashion/README.md -------------------------------------------------------------------------------- /Sowing-Seeds-of-STEM-thru-TechnoFashion/Sowing the Seeds of STEM Through Techno-Fashion.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/Sowing-Seeds-of-STEM-thru-TechnoFashion/Sowing the Seeds of STEM Through Techno-Fashion.pdf -------------------------------------------------------------------------------- /Style Guides/readme.md: -------------------------------------------------------------------------------- 1 | From [@nicetransition](https://twitter.com/nicetransition) material for [Style Guides](http://nicetransition.com/Kevin-Mack_CodeMash_Style-Guides_01-13-17.pdf) 2 | -------------------------------------------------------------------------------- /Taming the JavaScript Dragon with TypeScript/readme.md: -------------------------------------------------------------------------------- 1 | #Taming the JavaScript Dragon with TypeScript 2 | 3 | [Slides and Demos](https://github.com/DustinEwers/typescript-demos) 4 | -------------------------------------------------------------------------------- /Testing at the boundaries - using Consumer Driven Contracts to keep your microservices in sync/README.md: -------------------------------------------------------------------------------- 1 | #TESTING AT THE BOUNDARIES 2 | ##Using Consumer Driven Contracts to keep your microservices in sync 3 | Andrew Fitzgerald 4 | 5 | Slides and demo code available [here](https://github.com/Fitzoh/testing-at-the-boundaries/tree/codemash-2017-demo-end) 6 | -------------------------------------------------------------------------------- /The Evolution of Memory and Resource Management/Memory-and-Resource-Management-Slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/The Evolution of Memory and Resource Management/Memory-and-Resource-Management-Slides.pdf -------------------------------------------------------------------------------- /The Evolution of Memory and Resource Management/readme.md: -------------------------------------------------------------------------------- 1 | # The Evolution of Memory and Resource Management 2 | 3 | Presented by [Jeff Walker "Code Ranger" (WalkerCodeRanger.com)](http://WalkerCodeRanger.com) 4 | 5 | ## Resources 6 | 7 | ### Rust Language 8 | 9 | * [rust-lang.org](https://www.rust-lang.org) 10 | * [doc.rust-lang.org/book](https://doc.rust-lang.org/book) 11 | * [rustbyexample.com](http://rustbyexample.com/) 12 | 13 | ### Dyon Language 14 | 15 | * [www.piston.rs/dyon-tutorial](http://www.piston.rs/dyon-tutorial/) 16 | 17 | ### Adamant Language 18 | 19 | * [adamant-lang.org](http://adamant-lang.org/) 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /The Mindful Developer/readme.md: -------------------------------------------------------------------------------- 1 | From [@MatthewRenze](https://twitter.com/matthewrenze) material for [Tbe Mindful Developer](http://www.matthewrenze.com/presentations.html#the-mindful-developer) 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /The Rust Language - Memory, Ownership and Lifetimes/Rust-Language-Slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/The Rust Language - Memory, Ownership and Lifetimes/Rust-Language-Slides.pdf -------------------------------------------------------------------------------- /The Rust Language - Memory, Ownership and Lifetimes/readme.md: -------------------------------------------------------------------------------- 1 | # The Rust Language: Memory, Ownership and Lifetimes 2 | 3 | Presented by [Jeff Walker "Code Ranger" (WalkerCodeRanger.com)](http://WalkerCodeRanger.com) 4 | 5 | ## Resources 6 | 7 | ### Rust Language 8 | 9 | * [rust-lang.org](https://www.rust-lang.org) 10 | * [doc.rust-lang.org/book](https://doc.rust-lang.org/book) 11 | * [rustbyexample.com](http://rustbyexample.com/) 12 | 13 | ### Dyon Language 14 | 15 | * [www.piston.rs/dyon-tutorial](http://www.piston.rs/dyon-tutorial/) 16 | 17 | ### Adamant Language 18 | 19 | * [adamant-lang.org](http://adamant-lang.org/) 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Threat Modeling For Secure Software Design/readme.md: -------------------------------------------------------------------------------- 1 | From [@roberthurlbut](https://twitter.com/roberthurlbut) material for [Threat Modeling For Secure Software Design](https://github.com/rhurlbut/CodeMash2017/blob/master/Robert-Hurlbut-CodeMash2017-Threat-Modeling-For-Secure-Software-Design-01122017.pdf) 2 | -------------------------------------------------------------------------------- /Tips and Tricks for Testing Lambda Expressions in Android/readme.md: -------------------------------------------------------------------------------- 1 | From [@kingargyle](https://twitter.com/kingargyle) material for [Tips and Tricks for Testing Lambda Expressions in Android](https://speakerdeck.com/kingargyle/tips-and-tricks-for-testing-lambda-expressions-in-android) 2 | -------------------------------------------------------------------------------- /Toward a Better Front-end Architecture Elm/readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | Title: Toward a Better Front-end Architecture: Elm 3 | Date: 1/12/17 3:30 pm 4 | Speakers: Jeremy Fairbank 5 | Room: Salon A 6 | Tags: Functional Programming 7 | Category: General Session 8 | --- 9 | Amidst the overwhelming cacophony of competing JavaScript frameworks, Elm is a promising voice. Elm is a relatively new language that compiles to JavaScript. Elm is a functional language that encourages describing UI, state, and events in a declarative manner, while performing as good as or better than the current JavaScript framework hotness. With type safety and pure programming constructs, Elm promises code that has fewer bugs and is easier to reason about. In this talk, dive into Elm, exploring its syntax and more importantly its architecture. Learn about unidirectional data flow, modular and composable UI components, update functions, and commands and tasks for side effects. Ultimately, discover how functional programming with Elm’s architecture can solve real problems. Leave this talk equipped to start utilizing Elm to construct non-trivial apps with more maintainable code and better determinism. 10 | 11 | 12 | ### Repositories used in the session: 13 | * [Toward a Better Front-end Architecture: Elm](https://github.com/jfairbank/arch-elm) 14 | 15 | ### Presentation Slides: 16 | * [Toward a Better Front-end Architecture: Elm](https://speakerdeck.com/jfairbank/codemash-2017-toward-a-better-front-end-architecture-elm) 17 | 18 | Repository link from [@elpapapollo](https://twitter.com/elpapapollo) (Thanks!) 19 | -------------------------------------------------------------------------------- /What are Observables and why should I care/readme.md: -------------------------------------------------------------------------------- 1 | [Presentation](https://rkoutnik.com/talks/observables/#/) 2 | Further reading: 3 | [Introduction to Reactive Programming (start here)](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754) 4 | [RxJS Koans](https://github.com/Reactive-Extensions/RxJSKoans) 5 | [Rx Marbles](http://rxmarbles.com/) 6 | [RxJS version 5](https://github.com/ReactiveX/RxJS) 7 | --- 8 | ##### What are Observables and why should I care? 9 | * Date: 1/12/17 8:00 am 10 | * Speakers: Randall Koutnik 11 | * Room: Salon H 12 | * Tags: JavaScript, Functional Programming 13 | * Category: General Session 14 | --- 15 | Learn about the next generation of asynchronous abstraction: Observables. Born of a cross between the Observer & Iterator patterns, observables are being used from Angular 2 to the data teams at Netflix & Microsoft. Start at a high level, learning why observables stand out among the many asynchronous abstractions available to the developer. Then, learn how to conceptualize event streams as simple observable flows when tackling typeaheads on the frontend. Finally, enter the world of machine learning and see how observables can be used for stream processing. Walk out with the confidence to harness the power of observables to straighten out your asynchronous apocalypse. 16 | -------------------------------------------------------------------------------- /[KidzMash] You put the Object in, you take the Object out, … and you shake it all about./KidzMash2017-OOP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/[KidzMash] You put the Object in, you take the Object out, … and you shake it all about./KidzMash2017-OOP.pdf -------------------------------------------------------------------------------- /electron-desktop-development-for-web-developers/Electron Desktop Development for Web Developers.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechConf/CodeMash2017/8e2a312dda243c05d209818ab2d00b318ef06252/electron-desktop-development-for-web-developers/Electron Desktop Development for Web Developers.pptx -------------------------------------------------------------------------------- /electron-desktop-development-for-web-developers/Readme.md: -------------------------------------------------------------------------------- 1 | Electron Desktop Development for Web Developers 2 | =============================================== 3 | 4 | ### Codemash 2017 5 | 6 |   7 | 8 | Chris Woodruff 9 | 10 | cwoodruff\@live.com 11 | 12 | \@cwoodruff 13 | 14 |   15 | 16 | Slidedeck 17 | --------- 18 | 19 |   20 | 21 | Repositories 22 | ------------ 23 | 24 |   25 | 26 | Other Resources 27 | --------------- 28 | 29 |   30 | 31 |   32 | -------------------------------------------------------------------------------- /stranger-streams-howto-rxandroid/readme.md: -------------------------------------------------------------------------------- 1 | Stranger Streams: How to RxAndroid 2 | ===================================== 3 | 4 | ![RxAndroid Slide Image](https://raw.githubusercontent.com/myotive/stranger-streams/master/screenshots/streams_title.PNG) 5 | 6 | * [Slides](https://speakerdeck.com/myotive/stranger-streams-how-to-rxandroid) 7 | * [Sample Code Repo and References](https://github.com/myotive/stranger-streams) 8 | --------------------------------------------------------------------------------