 My name is Mark Allen. I am really pleased to be with you today. And I'm going to talk about Rebar 3. The title of this talk is Three Greater Than Two. And for a long time I didn't believe it, but recently I've drank the Kool-Aid and I'm a really big fan of Rebar 3. And through this talk I hope to make you all big fans of Rebar 3 as well. How many of you are currently using Rebar 2? Anyone? No? Are you already using Rebar 3 now? Yeah? How many of you are like splitters and using Erlang.mk? Yeah, a few of you. Okay, that's fine. If you like Erlang.mk and it works for you, then that's great. Hopefully you'll see that there's some really nice features that Rebar has added that will encourage you to consider switching. But I understand you go with a build system and you invest time in it and you build automation around it and it's difficult to change. I do understand that. I'm sympathetic to that. Alright, so let's start with some context with the tool itself. If you go sort of back into the deep, deep, deep commit history of Rebar, you'll see that it started in 2009. It was laid in 2009, actually about nine years ago, I think, no, eight years ago. It was written by this guy named Dave Smith who goes by Dizzy. He worked at Bashow and now he's a digital ocean, but he still goes by Dizzy. Anyway, Dizzy started this build tool, Rebar, to help build React releases. And if you read the commit history, you can see over time it's acquired a whole bunch of features. They came in organically. And people were like, hey, this tool is pretty good and it really helps us save time. The Erlang compiler, the Erl-C tool is adequate, but this is really nice because it takes care of a lot of issues for us. Over time it has gotten all sorts of compilers for proto buffs and C programs and templating files and you just all sorts of different things included inside of the guts of it. And this organic growth of the tool really just led to chaos. Internally in the tool itself, it was really difficult to add new features easily, to test features that were added, and also just to generally organize the code in a more coherent and sane way. And so about, I don't know, three or four years ago, Tristan Slaughter started kind of working on a fork of Rebar called Rebar 3 and then Fred Aver kind of joined in and together they've been working on the tool now for at least three years and it's really gotten very mature. And some of the things that were really frustrating about Rebar 2, I think for both of us and also for me personally, was really the dependency management. I don't know how many times this has happened to y'all but when I have an Erlang library and I'm downloading it and it uses Mac and Mac is pinned in some version and then some other application also has Mac as a dependency for testing purposes and it's pinned in a different version than you're kind of stuck in what I call Mac hell. And you have these conflicting versions and you have to have some way to resolve that and Rebar 2 just sort of threw up its hands like, I don't know what to do. You're on your own, buddy. And that's not very friendly. That's not a very good experience. I think it's going to be a lot better. So one other thing that was really frustrating I think for me also again in my professional experience is the lack of repeatable builds. So you would execute a build with Rebar and it would output some artifact and then later you wouldn't be able to tell exactly what commits went into that build, right? So you wouldn't be able to say definitively that this library at this commit level went into this artifact. And Rebar 3 really tries to solve and approach a lot of these problems. So now there's just something better. So as I said, it's a major rework. The reason that Rebar 3 is sort of a separate thing now is that it broke compatibility with Rebar 2 in really fundamental ways. A couple of the really important changes that happened between 2 and 3 is that RelTool was the sort of release tool. I'm going to talk about this later more in my talk. But RelTool was the tool that was integrated into Rebar originally. RelTool comes with the OTP release. It's bundled with Erlang directly. And a lot of people don't like it. And actually the syntax, if you go read the man page for it, is quite arcane. It's really only for wizards. And I'm not a wizard and I don't know many wizards. I know a few of them. I've met a couple of them at various Erlang events. But I mean, generally speaking, if you're not a wizard, RelTool is probably not what you want to be building your releases with. So they put in relax. RelX, I guess it's also called sometimes. And there's also a lock file. So the lock file is intended to address that issue where you have repeatable build concerns, right? So you want to know this library, this commit, went into this artifact and it's repeatable. Every single time you ask Rebar to build or compile this artifact, it's going to be those libraries, this commit level, that's your output. So you won't be able to get the same hashes necessarily because of the way that Erlang actually encodes time information into Beam files. This is actually quite irritating. As an engineer, I think they've added an option in OTP-20 to turn that off. But it used to be that Erlang modules had a version ID that was assigned by the compiler and it was based on a timestamp. And what that meant is that if you hashed two Beam files and they were built at different times, they could be completely identical except they won't hash to the same value. And so that's kind of irritating. But some other great things about Rebar 3 that I really like just on highlights here is hex integration. We're going to talk a lot about what hex is. How many of you know what hex is already? Quite a few. Okay, good. So hex is a package repository that started up a couple of years ago. It was really started by Eric. Meadows Johnson, I think, does his name. He's an elixir guy and he's on the elixir core team. And he's really, really cool. Nice guy, met him a couple of times. He started this project called hex to kind of be a package repository. And one of the other issues that I have about Erlang builds in general is that until really recently, until hex kind of came about, there wasn't sort of a, quote, definitive place to put your Erlang artifacts, right? So you could throw code up on GitHub and then you're kind of in this weird spot where, you know, there's forks of forks of forks, especially, I mean, just think about like MySQL support. You know, there's like 85 different MySQL drivers to talk to MySQL. And some of them are like abandoned. Some of them are bit-rotted. Some of them are terrible. Some of them are not terrible, but it's like as someone that's coming to the language, we can do a lot better to help people find out, okay, these pieces of code are like really quality. A lot of people use them. They're widely used in the community, all those sorts of things. All the indicators of quality have been very difficult to signal just by relying on something like GitHub by itself. And so with Hex, we don't really have to do that anymore, and that's also a really nice thing I like. So let me tell you a story. I'm not implying, by the way, that Rebar 3 is as beautiful as the Taj Mahal, but it's pretty nice. Also, I had an observation, which is when you take a drink of something, and it's really terrible, you don't keep it to yourself, right? You say, here, try this. It's so terrible, right? You say, oh, this is awful. Gotta have some. Why don't we do that for nice things, right? Why don't we try that for things that taste really delicious, right? It's like, oh, this is so wonderful. You should have some. I don't know. Maybe we're just too greedy or something. But what I wanted to tell you is that for a long time, I was kind of in the ambivalent camp about Rebar 3, right? I could take it or leave it. In the last two years, I've really become a believer. And what I want to do with this slide and with this little segment of my talk is encourage you to give it a shot. If you've been using Rebar 2, just tip your toe in the water of Rebar 3. And I think that as you use it more, you really come to like all the features that it's added to, the capabilities that you can have. And what this talk is really focused on is kind of customizing Rebar to make it the best possible build tool for you or even for your company or for your colleagues or your team, right? Rebar 3 offers you a level of customization that we've never had before. And I think that's really exciting that you'll have the opportunity to customize your build tool to do exactly what you want to do and not what someone else wanted to do and have to go through submitting patches upstream and all those sorts of things, okay? So we're just going to run through some of the basic operations to start with just to kind of level set everything. The first thing that's really important is dependencies. So one of the weird things about Rebar 2 was that you had to explicitly ask Rebar 2 to pull dependencies. Now, there is an actual, again, if you sort of dive back into the commit history of Rebar 2, there is a lot of, there's an explicit commit that Dizzy added like in 2010, like a year after he started Rebar project directly, that says that you have to explicitly, I guess that used to automatically fetch dependencies. And then at some point, that was not a good choice, okay? And so Dizzy changed it so that you had to explicitly fetch, and I'm not trying to throw Dizzy under the bus, by the way, hey Dizzy, if you're watching, hi. I'm not trying to throw him under the bus, but there was a decision made at some point where getting dependencies automatically was decided to be a bad thing to explicitly ask Rebar to pull your desks, right? There's this Rebar get desks command that Rebar 2 uses and supports. And that's what fetches your desks from whatever sources you have to find in your big file. That is not any longer the case. So Rebar 3 actually has sort of a tree approach to handling commands. And the commands know that there might be precursors and ancestors that follow a certain command. So for example, if you tell Rebar 3 to use a code, and you have dependencies defined in your Rebar config file, the first thing it's going to do is go out and check to see are the dependencies already present on your system. And it's going to look in the underscore build directory. So that's where Rebar puts all of its artifacts now as an underscore build. It used to go into a depth directory if you use Rebar 2. But now in Rebar 3, it goes into build. And then underneath that, there's some profiles. The normal one is default. That's the one that 99% of people use. And today, hopefully, maybe you'll get more comfortable with other profiles. But so they go into build default lib, and then that's where all the dependencies ended up. And so it'll go in there and check and see if they're the right version. And then it'll check the lock file that gets created. If there's a lock file, it will go to check that. Make sure that your versions are right. And if they're not, it will try to get the right version and put it in place. And then the other nice thing is that the dependencies from Hex, it will cache those locally on your system. So let's say that you're on an airplane or whatever and airplanes have terrible Wi-Fi. So you could grab them at the airport before you get on the plane and then you'll have your dependencies already set in your project and you're actually sitting in your seat and you're ready to write code. That's really nice. Some of the other things that are great is the profiles. I already mentioned those a little bit. You get out of this mech hell and you can even put dependencies in for E-Doc and other targets and stuff like that. So it's really great. You can segment what dependencies get downloaded based on what sort of profile you're executing. And I think that that's a really nice advancement in terms of, you know, how much clutter you have to think about, how much overhead you're going to have. And also tries to put out these fires of, okay, well, this project uses that version of Mac and this project uses that version of Mac and they're not the same. This can go a long way to solving that problem and I think that's great. Okay, so rebar three shell. This is the goat. This is a goat to go to Modicon. It's the greatest of all time. It's the greatest of all time. This thing is, it's my favorite thing. You just type rebar three shell and what it does is it will download all your dependencies, compile your project, and it will actually put you right into an Erlang REPL. And you can even go one further and tell it to start your application and tell it to read a config file. So you can do all that from command line. It's super, super convenient. It's really great for testing and experimenting. This is really absolutely my favorite feature about rebar three. And this one feature alone is enough, I hope, to sort of push you over the edge and get you to try it. It's really, really nice. Now, you can certainly do this and I worked at Bashow too. So, I mean, a lot of Bashow make files have a target called shell, so this is built in and it works on everything. So you don't have to write any make files or anything like that. You just get it and it's really lovely. Definitely works with time. So I already mentioned integration with Hex. One of the other things that's really neat about the Hex integration is that you can actually publish your own code to Hex. So, rebar three gives you a direct route to go ahead and publish your code. There's also this notion of a global config file. So all of the Hex stuff is encoded in a global plugin and you can put those in this path here. By the way, all the slides and everything, I'm going to upload those so you don't need to take notes unless you want to. But you put the rebar Hex in your global profile and then what you can do is register yourself as a user and you can add some extra metadata to your .app.source like here. This is a project that I have for sagas. So here's my maintainer information here's the licensing information and then here's some links. When this data gets processed by Hex, when you say upload it and you say Hex publish it outputs all of this nice output stuff here for you and at the bottom sorry, it's hard to read at the bottom it can actually go ahead and publish it directly and it will send up the tar ball and Hex will process it and that metadata information will get presented in a really nice little web UI for people to look at and to evaluate so that's pretty neat. Alright, so let's talk about releases a little bit. Who is doing releases already? Yeah, you. So a release is really a collection of an application and its dependencies and it's sort of mashed up with the early runtime the idea here is that you want to build an artifact that you're ready to deploy to something else and you want to push it to production or you want to put it into a CI service or something like that so a release is really a collection of a library plus all of its dependencies in some sort of way that you can manage it to be an artifact and when I say artifact, what I mean is a tar ball or depending on if you have dev mode enabled so I mentioned RelTool already it's for wizards I'm not a wizard, I don't know any wizards I know a few wizards but they're rare and so Rebar 3 uses RelX which is a really nice tool and there is a RelX project so if you're new to RelX and I know I was, especially when I started with Rebar it's really worth your time to sort of get familiar with that but the really basic way to handle this is it's pretty straightforward I stole this out of a project that I started that I actually presented in my workshop yesterday so Udon is a React Core example application and here's the RelX configuration for that you can see up here at the top there's this keyword release and then the name of the app and then a version and then I have the dependencies that come with it and here this dev mode thing is really interesting what that means is that I don't want to create a tar ball I want you to lay out the apps I want you to lay out the app as if it were going to be a tar ball but just sim link all the application dependencies don't actually copy them in place and what this lets you do is simply re-sim link those things as this changes so as you're developing an app and you want to do release and test the release having dev mode enabled is a really nice and fast way to get a lot of mileage out of getting those dependencies in the right place and then this is include early runtime, false for dev mode and then you have the overlay bars and what this does is it sets up your release directory the way that you want it if you have config files or you have a certain directory layout that your application expects like you need to write data into a certain directory or whatever these overlays, bars and template files can help you create that environment very quickly one really nice thing about this method is that you can have specific overlays for specific releases so for example if you have a prod release if you have a prod release here so if you just want to do a normal release you can just tell rebar release and that means dev mode on so just sim link my dependencies but then down here if I say rebar3 as prod release tar that means dev mode off so I want the runtime, I want all the apps all copied into the right place and then I want you to rebar I want you to create a tar ball and Gzip it so that at the end of this process I'm going to have a complete artifact with repeatable build, rebar lock all that stuff in a nice little artifact, a tar ball that I can deploy to whatever I need to send it to it could be a customer side it could be a deployment server it could be a CI system whatever the case may be are there any questions so far so that's a good question the question was is the application order here is that meaningful the answer is no it's really just the list of applications what they should be copied the startup order of your applications is defined by the metadata that's in the application directory itself so that would be like your app.source and then if you have any kind of other start standards inside of your source code so yeah, that's a good question though any other questions? okay do you have an example or because my experience has been so the question was rebar is great and I agree with that sometimes some of the features are not properly documented what can we do about that and I agree I think the documentation could be better it certainly could be more of it and I think this talk is hopefully an attempt to do that but my experience has generally been when I needed a feature I found an example and I do have a resource slide at the end of this if I find something that's not well documented or is not working correctly there's an IRC channel on FreeNode and IRC is like a slack for old people I'm old by the way so IRC is slack for old people there's a rebar channel on IRC Tristan and Fred are in there almost all the time so you can ask questions in the channel and someone will help you and if it's a legitimate problem or bug they usually know about it already that's been my experience so if I find something that's really weird about rebar 3 I go to the IRC channel and I ask for help in there and they've been super good about helping me so that would be my first suggestion in general I agree that I think there could be more documentation I think the documentation that comes with rebar is actually reasonably pretty good at least at the high level first class some of the other more obscure things like plugins and whatever I do have some examples that we're going to talk about today on that topic but generally speaking it's pretty good I think especially for just basic usage it's really adequate yeah, I agree yeah yes so I'll tell you the weirdest part about rebar 3 just since the question prompted it I do have a couple slides about templating and oh yeah here it is, boom, templates so the weirdest part about rebar 3 for me was the templating language the templating language is is this thing called mustache and mustache is kind of a weird templating language so in a normal templating language in a normal templating language you have these constructs where you can iterate over lists and stuff like that and there aren't those constructs so you have to think really hard about how you want to explode out collections and you can totally do it and I have done it it's just that you have to think about it rather than you normally would like if you were using early VTL style templates or the elixir templating language EEX has all of these iterative things that are really nice you don't have to think about it there you just put it in and it gives you an instance and boom you just stamp these things out but with mustache you actually have to think about it for a little bit so that's been the weirdest part about getting rebar 3 to do exactly as I want I'll write a template or whatever and it doesn't come out right so I'll have to like try it again and try it again and try it again and that's mostly about my mental model about how mustache should work and not with the tool itself but anyway so that's been the weirdest part about that and I've actually found resources about using mustache surprisingly difficult to find as well especially about dealing with loops and stuff like that most of the time they just point you to the band page and there's exactly one example about how to use loops on that band page and if you're not doing that one example then it's kind of like oh so it's a little bit weird but alright so templates, templates are really great and there are a ton of them that are built in and you can see how many of these are built in you can see they're all labeled built in and there's actually one here that's not labeled built in it's this one so if you're writing React core applications like we did in my workshop yesterday there's actually a template pack that you can install and once you do that then you can have a nice neat new way to stamp out new React core applications really quickly and just ready to go so building templates for your application stack is a really really useful technique and this is something that we do at my company we have a rebar plugin and it has a set of templates associated with it that map to our internal web framework so we have a microservice web framework that's written in Erlang and when we want to create a new service we can just ask rebar to go ahead and create a new template file so that we can quickly write a new microservice that fits into our framework there I already talked a little bit about template variables so here's the weird mustache language how do these, yeah question so the comment was is that there's a Java implementation of mustache which has really good docs so if you get stuck if you get stuck check there yeah question and I heard there's a comment about JavaScript so you can check mustache and JavaScript too I guess they have better examples that's nice okay so here's the weird mustache language and you can see up here there's this double bracket, double bracket and there's this variable in here the question is how do you get values in that well the answer to that is this they actually have a whole bunch of variables which you can see here and it tells you what the variable is, what its default value is and then what this actually means like in the context of this template and so this is a great way for you to be able to customize your templates at creation time you can just pass these parameters in on the command line and rebar3 will do the right thing with them it will put them into the mustache template for example if I had a custom template that stamped out this weird example one of the parameters I have is name and so I would pass name on the command line and then when this gets rendered this little squiggly squiggly name thing would be replaced with the actual name I passed right that's super clear mustache is great for really obvious templates passed like this but like I said it is a little bit more complex for loops and collections okay so let's talk about custom rebar3 plugins looks like I have 20 minutes left okay cool so this is a really huge topic I could do a whole talk just about rebar3 plugins to be honest it's a very large topic but there is help that's on the way one of the great examples and the one that we're going to use today is actually this one here it's sort of a tutorial it's a plugin that searches through your files and looks for the phrase to do and then it outputs them so you can tell rebar3 hey I want you to show me all my to-do items and it will just search through your source code directory and every time there is a to in a comment it will actually output it it will emit it on standard out so you can keep track of what those are and maybe it will be like hey I was supposed to fix that problem and I haven't gotten to it yet so the main thing is that you're going to write three callback functions the callbacks are this so you get an init function that takes a state and it returns a new state and then there's this do function that also takes a state and returns a new state or errors and then format error and then it returns a string and you can also have plugins that have their own templates I mentioned that already that's something that we have for our custom plugin every single project there's a global rebar config file and rebar3 you can just put your plugins there at the list and it will just use them it's really really nice for in-house frameworks it's one of my bullet points but I'll just reiterate it it is really really nice to have this is an initialization step here I know this is a wall of code but it's actually quite simple really what we're doing is a prop list and it's got these keys and values over here and the keys are really standardized and this all comes from a provider library that Tristan wrote a couple years ago that's why these things are called providers because they're actually a library called providers and that's what rebar uses to implement this functionality so there's the name and the module those are I think self-explanatory this is a weird one but basically it says the task can always be run by the user so you just want to do that and then depth is the list of dependencies in this case it is whether or not you should allow the plugin to descend into dependencies or not and then there's an example and this is used for help messages and then here's your options so this is like the parameters or flags that your plugin will take on the command line and you can see that there is one here it's default value is undefined so that means that it's normally not used and then short desk again this is for help messages and then this is also for help messages so the idea here is that we want to try to be really friendly for outputting help messages when users encounter your plugin how they should consume it and what they should pass into it and things like that the most important part is this part down here at the bottom again sorry it's at the bottom slide it's rebar state add provider that's the thing that actually clues rebar in and says hey dynamically add this plugin to the list of things that a user could possibly do so this init function gets executed before any evaluation of your code, before any compiling before it even looks for source code or anything like that so this init function is executed across all the plugins first and then later it does all the command line parsing and stuff like that so the bottom part here the rebar state thing that's the most important part this whole deal the next part is the action so what should we do and you can see here that this is a really straightforward thing the first thing is we're going to discover type so that's carried around in the state the state is rebar state and so that has all the applications that rebar scan and the dependency list and all of that stuff it's all carried around in that variable state and there's a whole bunch of helper functions that rebar exposes to you so that you can execute or pull things out of state like you can see here that rebar state project apps are pulled out is the thing that we're going to search through so that's what this does is it first is it figures out am I looking at the normal project files or dependencies and if I am then I'm going to get a list of dependencies and if I'm not then I'm going to look at just the the top level application stuff it goes into that list apps and then we're just going to do a for each so there's this little function called check to do app and what that does is it scans through the source code and it looks for the phrase to do it's a simple match of to do and it will emit that on standard out and then it returns okay state we didn't modify the state so we're just going to pass it through and then format error really straightforward right it's an error and it just formats it and puts it out and I list and that's it those are the only three callbacks that you need to have for a plugin this is a really simple example and I understand a lot of complexity here but it's really not that difficult and it's kind of fun with it once you start really getting into the rebar api there's a lot that you can do you can define your own custom compilers you can change the way that rebar does certain activities like pulling dependencies you can change how it looks for code to compile you can change the output directories where it drops places you can just do all sorts of really interesting things make your build process customized for your environment and for your own work style and I think that's really great with rebar 2 rebar 3 supports it I just wanted to spend a few minutes talking about converting to rebar 3 this is the boat that I was in especially with some projects that I maintained so I wrote sort of a checklist here the most important thing that I found is that you want to sort of update your dependencies to the new style and what I mean by that is that in rebar 3 the version check thing that rebar 2 had doesn't exist it doesn't use that I personally like to use the hex style which is just an atom a project name and that maps to a whole hex download you can also give other options there's 3 or 4 different options but the most common that you'll see is just a naked atom with a project name and then also there'll be a version specifier that's also in common so that's number 1 number 2 is move your test and dock dependencies out of the sort of mainline create profiles for them profiles are really helpful and powerful and those profiles automatically get created when you execute the test target so for example if you have a profile name test you don't have to explicitly ask rebar to use the test profile it's smart enough to know that you should check to see if it exists if it does to use the dependencies in there and then finally if you need to you're going to have to include the relics dependency specifiers reltool is for wizards but also rebar 2 hit a lot of the complexity of reltool and so it actually made reltool more approachable I think than it actually is as a tool that's good and bad it hit the complexity from you but relics is also not that difficult and it's pretty easy and then finally if you need to provide rebar 2 compatibility there's still a lot of people in the world that are using rebar 2 you don't want to force them to use rebar 3 that's not very nice so be considerate provide compatibility I have an example here I maintain a project called logger which is a logging library here's logger's rebar 3 dependency this is just some extra stuff I copied in here to give context these actually probably should be in their test profile and I haven't done that yet but you can see that it doesn't really matter because rebar 3 is really tolerant it just ignores stuff that it doesn't understand anyway down here's the dependencies there's only one dependency for logger it's gold rush and it has this version and there it is highlighted and then there's a logger rebar 2 compatibility it's in this file and this is the secret this is one of those things I think that's under documented actually is that you can create a rebar config script and what that does is when rebar starts it looks for this file but if there is this file in the current working directory then it will actually execute it it will load it and evaluate it and in this case what we can do is this we can say if the function is exported rebar 3 main then we know we're using rebar 3 and in that case we can just pass through this config where this config thing come from it's magic it didn't come from anywhere it's not specified in here as you can see but it's like the magic thing that says here's the config that rebar's read and it gives you the chance to modify it which is exactly what we do down here so if we're compiling with rebar 2 you can see I have the old style dependency here with gold rush and this little regular expression thing and then the specification for where to pull this from and the version that I want and all that and then I delete the depth key from rebar 3 and replace it with this couple or list and return it and that's how I maintain rebar 2 compatibility with a project that has rebar 3 style dependency you can do this same technique for all the things that need to be fixed and replaced for rebar 2 and so this is a nice way for you to bridge that transition time where people are kind of still using rebar 2 and rebar 3 together alright so one last thing I wanted to mention rebar 3 has a debug facility and if things blow up go boom you can actually just pass in the debug-1 over here and run a command and it will give you verbose output it will show you every single step that it's doing and tell you what all the internal states of rebar are this is really really helpful if you're going to file a bug report like we're asked for help or whatever you can take that output and put it in a gist or some paste bin or whatever and then ask for help in IRC and people can take a look at it try to help you figure out what's broken so here's some great resources the main sort of doc website is this one rebar3.org if you want to look at the github source code and play around with it that's where it is it's on Erlang rebar3 I already mentioned the hashtag rebar channel on IRC and then there's a couple of YouTube videos that if you haven't seen are really worth watching the first one is this one the introduction to rebar3 that's where Fred and Tristan sort of introduced the tool itself where after this is from 2016 where they talk about moving from two to three in the same vein as kind of what this talk is but it's a little more elementary and that's also a great video both of those videos are about 40 minutes each and then finally I mentioned Hex if you haven't played around with it it's really neat so maybe spend a minute or two and take a look at it it's really really great and I think that's it thank you for your time I appreciate it I'm happy to take any questions that people might have yeah, question they don't really play with Hex they don't have a previous state to actually pull the Hex can we optionally choose Hex and sometimes not to choose Hex can it fall back? Hex isn't available you're saying that the rebar doesn't have access to talk to Hex I mean it doesn't have a state the CI systems don't really have a file system structure to keep that going so when I mentioned just an atom there saying that pull me cow boy now it doesn't really understand where the cow boy is is there a configuration where we can define such a way that if there's Hex package available it pulls it from there and it's not available it just goes on there currently is not a fall back mechanism that's actually one of the things that I have been asking for and just as an aside I actually hope I can demo this a little bit later during our lunchtime but I've been working off and on on a service that allows you to store Hex style artifacts but not in Hex okay so it's something that's behind your firewall right but it would store your own like private artifacts that would be generated through uploads and currently there's no way to say try this repo and then try this repo and then try this repo unfortunately it's a all or nothing type deal where it either gets it or it does not get it right now but hopefully that will change in the future no I'm writing a server so the question was am I using Nexus no I'm writing my own server to do that yeah question comment two questions one is do you know of any resources for speccing I saw that you've specced out stuff in your library that you maintain that's the first question the second question is is the type check dialyzer part of the rebar builds it is yeah so rebar has a dialyzer build target so you can actually type rebar 3 dialyzer and it will go ahead and build you a PLT and actually dialyzer run as far as resources on speccing the best in documentation directly maybe there ought to be more of a discussion around that I know that Costas Segonis couldn't be here unfortunately he had a visa issue he was going to be here but he's like the world's expert on speccing because he invented it and so he's also done some talks at Erlang factories and other things that are available on the internet where he discusses how the specs work and what they're intended to do so I would recommend you check that out yeah question away in the back please not exactly a question but a response to one of the previous questions with being able to get your dependencies either from Hex or from source repositories in a CI system that's probably locked to the network so I have solved a similar problem recently essentially repeatable which is where the rebar locks and mix.lock are not sufficient to ensure repeatability so I have done it using mix functional package manager and it's standard library has a few functions that are already defined which allow you to build a rebar project or a mix project or an Erlang mk project where you can freeze the contents of your dependencies by their content hash and repeat that you get the same values instead of having network access you can prefetch them into your CI system and it will automatically detect that the expected content hash is the same as something on disk and it will replace them transparently I'm planning to give a lightning talk on the same so for more details you can so the comment was about using mix to guarantee repeatable build based on hashes so yeah yeah yeah so the question was about can we update fix dynamically using plugins the answer to that question is yes that is totally possible to do I'm not aware of a plugin that does that currently but it sounds like a great project oh you already have one so is that a mix only thing or oh ok so great what's the name of the plugin ok so ok great so as rebar elixir compile right ok cool that sounds really great I'll check that out anything else any other questions comments ok thank you very much for your time I appreciate you being here thanks