6. Generate!
‣ take some resources: files, data, APIs, ...
‣ provide a set of steps for transforming them
‣ repeat for each version using different settings
resources transforms
settings forks
8. transforms
mak
e
‣ Copy a file an t
m av
‣ Rename a file waf
en
‣ Move a file e tc.
‣ ... do this to groups of files
‣ use files as templates
‣ run compilers
‣ ... whatever you're having yourself
9. settings
conf: general settings
‣ schema-free structure - basically just a JSON doc
‣ each fork gets its own copy
‣ use for whatever you like
gen: current context
‣ well-defined schema
‣ describes current file: contents, name, etc
‣ ... or current iteration item, etc
10. forks
transforms forks
‣ Step 1
‣ Fork: ios, android
‣ Step 2
‣ Fork: skin1, skin2
‣ Step 3
s te p s a r
e the s a
f o r e ach me
f or k!
11. appgen
appgen.nearform.com
‣ An open source implementation of this approach
‣ $ npm install appgen
‣ $ appgen my-spec.js
‣ new AppGen(spec).exec(conf)
14. what we have now
macros JavaScript
conditionals loops
resource api sub processes
lang agnostic asynchronous
15. appgen.nearform.com
when should you
use it?
‣ You need to build lots of similar apps
‣ You need to support multiple configurations
‣ You need to build cross-platform HTML5 apps
‣ You need to let users create pre-defined apps
‣ You need a ready-made way to organize your code
Notas del editor
Today we are open sourcing an internal dev tool that we've been using to generate apps\n\nNot an app designer or user int framework\nThis is a build tool that lets you generate multiple versions of the same app\n\nWhy would you want to do this?\nMulti platform and white label (same apps, many skins, optional features)\nMultiplat includes more than just mobile\n\nWhy multiplat obvious\nWhy white label - move beyond one off projects, cut + paste \n
\ncurrent state of cross platform html5 app development\nSingle code base apps\nany color so long as it's black\nsingle codebase gets messy, extend this over hybrid/native\nthat's just mobile - what about tablets, tv, voice interfaces\nResponsive design is great in theory, painful in practice\nDoesnt solve white labelling anyway\n
this is how we should do it\ngenerate per platform per target\nconfigure and build\ntrue purpose of the assembly line is to produce variants easily, not copies\n\nNeed an dynamic, configurable assembly line - that's what we built\n
Dig deeper into why\nExamples of stuff we've built\n\nplatform: \nconventions: where tabs go, back button\nbugs: version specific\nconstraints: android css3 transforms are funky\nNative plugins\nAlso: beyond mobile apps - same underlying code base for web, iptv, voice, low end mobile, googles, etc - there is a proliferation of user devices coming - SBP \n\nversions: \nskins: color schemes, styles, images etc\nfeatures: tick box on/off - client pays for extras, platform constraints\nContent: same features, different content, eg city guides for tourists\n
Big problem with most build tools is they have no deep foundation\nE.g SQL databases built on the relational data model\nFunctional languages built on the lamda calculus\nThings such as ant and makes started as quick hacks\n\nIve been messing about with generative programming for a long time \nCzarnecki Eisenecker developed the theoretical foundation\nTheir book is a deep dive on the methods and techniques of feature composition and modelling - motivated by auto industry\nTheir implementation uses C++ templates - oh boy! Because they are Turing complete don't you know !\n\nBasic model: feature tree, each path represents a generated product\nBuilds traverse the tree, constructing features by applying a set of transform steps\nWe extend this by adding "context" for features, which can be manipulated as you traverse the feature tree, or even specified dynamically on a per build basis\n\n\n
Practical implementation\n\nFeatures are defined by a set of operations on source code files - transform steps\n\nEach version, a fork, is built by a specific set of steps\n\nModel provides the two additional key concepts that makes this scale to many versions:\n \ncontext specific configuration - each branch gets it own copy to modify\nForking - can occur at any point, copies entire build state\n\n
Simple example - a html5 app\n\nMulti-platform, ios and android, and multiple versions with different skins\nNeed to output four code bases\n\nIndex.html - template that you can insert text into - like jsps\nApp.js - functionality - also a template - although you could compose from separate files\n\nCSS - renamed simple as style.css\nImages - copy skin set\n\nShowing relationship between base resources and generated output\n\n
Transformation steps\n\nNo rocket science here - what you would expect from a build tool\nExcept that it's mostly about moving things from base folder to generated folders, and modifying their contents if needed\n\nYou can also trigger external process to compile, e.g, Xcode, javac etc\n\nAnd of course you can define your own:\nEither using JavaScript and standard node.js Apis \nOr using macros - you can compose build steps!\nin fact the main built-in steps are themselves macros composed of smaller steps. \n
This is the contextual element of the model\n\nYou start with shared config - eg api endpoints\nEach fork can add/modify config\n\nSchema free structure - content depends on the app you're building\n\nThere's also the current context for each step, gen namespace\nWell defined schema \nEach step can read/write to the schema\nE.g. Loading a file from the base folder creates a gen.resource object with properties for the file path and content\n\nIf iterating over a set of config data, gen.item contains the current item\n
Forking - key concept\nFork as many times as you like - each time the config is copied\nE.g configuration: fork first for platform, then for skin\n\nImportant: the same linear set of steps are applied for each full branch - this keeps you sane! What changes is the config and context\n\nYou can have conditional steps if you like, but platform or feature specific macros are a better approach\n\nYou can also iterate over a subset of steps - this is how the built-in macros iterate over file globs\n\nforking model provides a structured deterministic declarative description of multiple versions and how to generate them\n\nYou avoid the work of having to design the build process yourself\n \n
We've had this problem for a while\nWe built an internal tool to solve it\nAnd we're open sourcing it\n\nAppgen is built using node.js\nIt's an npm module \n\nruns as a command line tool\n - you provide a JSON file as a build spec\n - or just use a node module - it's easier syntax!\n\nAnd can also be called dynamically via an API\n - you can override config settings and build on the fly\n\n\n
Example spec file\n\nDefines the build process we've seen already\n\nRes: where are the base and generated output folders\n\nConf: initial shared conf\n\nSteps: build steps\n\nTemplate executes files as a template\nImport copies a set of files\nForking is just another build step\n\nThese are macros built from simpler steps like load and save file\n
All about sw\n\n10000 products\n20+ apps planned - push button build by content editor\n\nCustom CMS to specify speech classification hierarchy\nSeparate build machine runs appgen from a build queue and compiles ipa and apk packages for ios and android respectively\n\nall node.js of course\n
Review key features\nMacros: extensible\nJavaScript: build tool should use a scripting Lang\nCond: there if you need em\nLoops: for Turing completeness - just kidding, no idea and not going to prove it!\nResource api: don't have to deal with file system directly, could reference bit repos etc\nSub procs: call out to other build tools\nLang: whatever you like\nAsynchronous: use any node module, get data from net, etc\n\nStill working on the docs - feel to pester on twitter!\n\n