github.com/dahs81/otto@v0.2.1-0.20160126165905-6400716cf085/website/source/docs/plugins/app.html.md (about) 1 --- 2 layout: "docs" 3 page_title: "App Plugins - Appfile" 4 sidebar_current: "docs-plugins-app" 5 description: |- 6 App plugins enable Otto to detect and work with new application types. 7 --- 8 9 # App Plugins 10 11 Apps in Otto are responsible for development, build, and deploy of 12 an application. An example of an app type is [PHP](/docs/apps/php). 13 14 By writing an app plugin for Otto, you can add support to Otto for new 15 kinds of languages and frameworks. You can also override the defaults that 16 are built-in to Otto by replacing the built-in plugins. 17 18 The primary reasons to care about app plugins are: 19 20 * You want to add support for a new language or framework. 21 22 * You want to change the behavior of an existing plugin. 23 24 * You want to support highly custom or legacy application types. This is 25 very common in large organizations adopting Otto. 26 27 ~> **Advanced topic!** Plugin development is a highly advanced topic in 28 Otto, and is not required knowledge for day-to-day usage. If you don't plan 29 on writing any plugins, we recommend not reading this section of the 30 documentation. 31 32 If you're interested in provider development, then read on. The remainder of 33 this page will assume you're familiar with 34 [plugin basics](/docs/plugins/basics.html) 35 and that you already have a basic development environment setup. 36 37 ## Low-Level Interface 38 39 The interface you must implement for app plugins is 40 [App](https://github.com/hashicorp/otto/blob/master/app/app.go). 41 42 The interface is extremely low level, giving you the ability to do almost 43 anything with Otto. However, we provide a lot of higher level helpers 44 that we recommend using to make your experience writing plugins a lot easier. 45 The core types also use these high-level helpers. 46 47 Rather than go into detail about what each function does for `App`, 48 we recommend looking at the 49 [builtin app types](https://github.com/hashicorp/otto/tree/master/builtin/app) 50 for real examples of how we use the `App` interface. 51 52 There is also a very basic 53 [example app type plugin](https://github.com/hashicorp/otto-example-app-plugin) 54 to show the general structure of things in the simplest possible form. 55 56 ## Compilation 57 58 Otto has a distinct compilation step through `otto compile`. During this 59 step, your application type should inspect the environment and use that 60 to generate files (covered below) that will be used for the other commands 61 such as `Dev`, `Build`, etc. 62 63 In general, Otto tries to do _as much work as possible_ during the 64 compilation step. Try to compute all the values you need such that when 65 `Dev`, `Build`, etc. are called, they almost only have to execute an 66 underlying tool such as Vagrant or Packer to achieve their goals. You 67 should not be rendering any new configuration outside of the `Compile` 68 call. 69 70 To assist with compilation, we use the 71 [helper/compile](https://github.com/hashicorp/otto/tree/master/helper/compile) 72 helper library. This automatically handles file structure, templating, 73 [ScriptPack usage](/docs/plugins/scriptpack.html), 74 etc. More on this is covered below. 75 76 One thing to be very careful about: set a compilation version on the 77 `app.CompileResult` value (helper/compile gives you a way to do this). This 78 version should be used in subsequent function calls to expect a certain file 79 layout. This lets you change templates in your plugin over time but still 80 be able to work with previously compiled data. 81 82 Practically speaking, a user shouldn't update your plugin and have all 83 their existing environments break without an `otto compile`. Existing 84 environments should continue to work even if you changed the directory 85 structure. 86 87 ## Bindata 88 89 A lot of Otto has static data that is templated onto the filesystem during 90 the compilation phase. You can see the files that Otto generates in the 91 `.otto` directory after running `otto compile` on a directory. 92 93 The templates for this static data are compiled directly into Otto plugins. 94 To do this, we use a tool called [go-bindata](https://github.com/jteeuwen/go-bindata). 95 To invoke `go-bindata`, we use `go generate` which is a command built-in 96 to Go that executes a command as part of the Go compilation process. 97 You can see an example of 98 [how we do this for Ruby](https://github.com/hashicorp/otto/blob/c70a67f85beaa3db353052ee82b8dfc149ff2753/builtin/app/ruby/app.go#L18). 99 100 This will create an autogenerated `bindata.go` file. We gitignore this 101 from the main Otto repository. But you can view it by running `make` within 102 the Otto directory which will generate all the files for the project. 103 104 That bindata is then used in combination with `helper/bindata` which 105 is covered below in the templating section in order to write the files to 106 disk. You can see an 107 [example of that for Ruby here](https://github.com/hashicorp/otto/blob/c70a67f85beaa3db353052ee82b8dfc149ff2753/builtin/app/ruby/app.go#L35). 108 109 ## Templating 110 111 In addition to compiling the static data directly into the final binary, 112 Otto does a lot of templating. It uses templates to generate the proper output 113 during `otto compile`. 114 115 All of this templating is handled by `helper/bindata` automatically: any 116 rendered static asset will be processed by the templating engine if the 117 static asset ends in ".tpl". The final filename removes the ".tpl" extension. 118 119 Again, you can see examples of templates in the `data` directory of 120 the [built-in Ruby application type](https://github.com/hashicorp/otto/tree/master/builtin/app/ruby). 121 122 You can use `helper/bindata` directly, which we do in some places, or more 123 likely you'll be using the `helper/compile` helper to assist with compilation 124 which automatically processes your data directory for templates. 125 126 ## ScriptPacks 127 128 Otto encourages the use of [ScriptPacks](/docs/plugins/scriptpack.html) for 129 any logic that isn't running directly on the user's machine, such as in 130 a development or deployment environmet. 131 132 ScriptPacks are pure standalone shell libraries. By putting complex logic 133 within ScriptPacks, we encourage unit testing and reusability for more stable 134 app types. 135 136 ScriptPacks are integrated directly within the `helper/compile` interface 137 for easy use. For example, directly from the Ruby application type, within 138 the compilation options for `helper/compile`: 139 140 ScriptPacks: []*scriptpack.ScriptPack{ 141 &stdSP.ScriptPack, 142 &rubySP.ScriptPack, 143 }, 144 145 This tells the compilation helper to automatically compile in the Ruby 146 and stdlib ScriptPacks (referenced using their Go package names). Then, 147 within the shell scripts used by the app type, you can see ScriptPack usage: 148 149 . /otto/scriptpacks/STDLIB/main.sh 150 . /otto/scriptpacks/RUBY/main.sh 151 otto_init 152 153 otto_output "Installing Ruby ${RUBY_VERSION}. This can take a few minutes..." 154 ruby_install_prepare 155 ruby_install ruby-${RUBY_VERSION} 156 157 The application type then uses the high-level functions from the ScriptPack 158 directly, which are each well tested on their own.