Devreal

Rage Against the Ecosystem

Event: Scale by the Bay

Scale By the Bay 2018: John Pretty, Rage Against the Ecosystem

Recording: Scale By the Bay 2018: John Pretty, Rage Against the Ecosystem

how y'all doing you all happy anyone anyone angry okay so I'm gonna talk today about something I've been working on recently called fury how many people here have heard a little bit or anything at all about fury there's a few hands got going up not everybody day so fury is often described as a build tool which is partially accurate but I think more importantly it is a dependency manager so it's it's a different problem being solved than what SBT does but there is a some significant overlap between the two so in designing fury as with many other things I've I've worked on that I I tend not to be too interested or excited with things unless I'm breaking conventions or trying to find alternative ways of doing things often those experiments fail disastrously but sometimes I think at least I catch on to an alternative way of doing something and I hope fury you very much fits into that that category so one thing Fury does differently is to define builds as data not as code and I'll explain a little bit about that decision later it prefers to depend on sources rather than binaries and the so build file as such not not in the familiar sense I mean we're not writing code or writing data so we modify this file using git commands gates style commands so we're running a command line calls which will mutate that file and it's interactive so let's talk about builds as as data rather than code all of the relevant parts of the build all of the information that fury needs to compile your Scala code this is I'm talking about multi-phase compilations here with things like compiler plugins and all your dependency details where it's gonna fetch those dependencies from that's all represented by a data structure inside Fury's code there is an ADT which represents that data so these graphs the relationships between the different compile phases the steps in compilation are not turing-complete we can know them just by inspecting the data structure so that's something we have access to it without needed to compile anything without having to go through the process of compiling code and then running it just to work out what our graph of dependencies is we have that we have the data there already and what this gives us is simplicity it's fast we can analyze it we can reason about it and this is a huge advantage Fury is very very fast and very responsive when you use it let's talk about source dependencies there's some debate over where the source dependencies or binary dependent dependencies work better and there are pros and cons to both but I I do prefer source dependencies and I think if people started using Furey they would appreciate some of the advantages I've got I'm getting a thumbs up from from Oscar at the back so this is what basil does as well the thumbs up give you a free mention of basil and so it's sort of sauce dependencies to offer a lot more flexibility I think there's a greater chance if you if you depend on on sources that you can successfully compiled some code if you if you have the binary that's built for the wrong version of Scala it's not going to work if you have a binary that's built for the wrong version of another library it might work if you're lucky and what what Ivy tends to do is if you end up with a version conflict between two dependencies on subtle different subtly different versions of the same library it will just evict one version of that this is a diamond dependency problem and we just have to hope that all of that links successfully at runtime when we come to run it that seems really quite dangerous with source dependencies we never we never separate the binary from the sources so the compiler will check for us whether that compiles or not maybe it compiles maybe it doesn't but we never have a situation where we're trying to run code that might not link where we might get a no such method error or a class not found we don't we don't have to wait for the binary so we published we can just grab the sources or fury can grab the sources on your behalf and work from those rather than waiting for the project maintainer to go through the quite convoluted process of publishing to to maven central and anybody can publish it doesn't have to be the project owner if you want to publish a build or if you want to publish a variant of another library you can fork it you have all the tools that get provides you you can take advantage of all of those in your build definitions and I really made that point so the other the other point I mentioned the beginning was that Furi Furi works through a command-line interface and i I don't know about you but I quite like using git from the command line I'm familiar with it I trust it there's no complicated GUI there's not a large configuration file that I have to edit I mean you there are some configuration files and get but I wanted to replicate as much as possible that interactivity and as I said Ronny command will typically change the build build file you don't you don't need to see that build file you don't need to edit it you can you can rewrite it you can you can query it using using fury we do actually use git itself to to track changes it's version controlled like anything else the output that you see is nice beautiful colorful obviously that's what counts in any build tool but on honor honor on a serious points there's a lot of things a lot of information you you receive when when using a bill tool some of it will contain things that are project names some of the module names some will be repositories some will be URLs these will have different colors and you will learn to associate those colors with the type of thing you're looking at it's all part of the user interface and user experience to give you as much information as as much indication and an intuition about what you're seeing is possible and my favorite part is that you get tab-completion which works pretty well it's it's quite smart it will for example look at the parameters you've already specified and maybe constrain later parameters you haven't yet specified so the tab completion is pretty adaptive pretty good and makes makes it very easy to make these changes and to run the commands very fast so let's just show you a little bit about what it's like to use 2 after new project we can run a command like this fury project ad and then we give it a name and that's gonna be Magnolia for this example we can add a module don't worry I'll explain what a module in the projects are soon we can add a module to the project called Magnolia we can call that call and if we wanted to add a reference to a source repository so I'm defining this this fresh fresh build for building Magnolia I need the Magnolia sources I needed in order to build them so I can add this dependency I can use this github shorthand definition here and I'm going to name that I'm also going to name the repository Magnolia as well so I've got something short to refer to it by if you don't if you don't provide that it will just assume the same name there so this is actually redundant and then having to find the project having to find the mortal within the project I want to add those sources from a particular directory from the source / core directory of the Magnolia repository I want to add those to the module I've just created so now that module knows what it will be compiling and the module is basically a single invocation of the compiler with some class path with some sources maybe with some binary dependencies as well and it will produce some set of class files we didn't specify the compiler so by default you'll get the Java compiler if it doesn't know any better but if we specify if we update the module two to use the Scala compiler we can we can do that like this and then to compile it we just run fury now I was going to do a demo but as with most projects I'd work on they spend the majority of their time not working and at least during during my development work and constantly I broke it yesterday and because I've modified the build file format or my build files don't work for the previous version that worked so all I can show you today is a video which I've actually published on on Twitter but this is this is what happens when you when you run fury this is fury building itself in in real time slightly blurry so as you can see there are various project names listed there linked between those those lines so the dependencies the models which are highlighted are the ones that are compiling at that particular time if you've only got one at the moment and it finished and and we're done so that was building fury itself from source with no no binary dependencies was building all of the dependencies as well it took about well 30 seconds it's up to about a minute now this this is a this is a couple of months old so that that's that's the experience you get if you run it multiple times it gets faster and faster because it doesn't need to build same stuff again and because the compiler is running hot so I use bloop for that I'm not going to talk too much about bloop but bloop is what provides the actual building back-end for for fury and it's made fury possible without without bloop which is developed at the Scarlet Center I really couldn't do this but maybe we want to depend on another library in our module so what I described so far is building just one one project one module without any external dependencies so if I wanted to depend on another library there's actually a few steps involved here I need to depend on it to depend on a definition for a workspace I'll explain that soon that contains a project definition so if I want to depend on shapeless maybe on github type level there is a shape to stop fury repository published maybe maybe miles saben who wrote shapeless would would publish that so I'm at that source repository now this is a source repository not on sources but on a build its dealt with in the same way because it's managed as any other repository is and from that repository I'm going to import the permit from the shapeless repository I'm going to import this scarlet 212 schemer now I'm using words like workspace schemer and so on without really explaining them don't don't worry for now but you can guess that Scala 212 is related to a particular version of the compiler and that's the that's the variant we're importing and then finally I add the dependency to my current module on shape the slash core and you get you get tab completion on this once this is imported so 3 steps very probably very unfamiliar to what you've what you've worked with so far if you're familiar to using SBT but this this is how it's done in fury and I'll explain over the next few slides why that's one other thing worth mentioning at this point which is support for forking say I discovered a bug in shapeless or maybe even a missing feature now when I cloned that we're not when I depended on that source repository for shapeless that gets cloned in the background it gets hidden away in a in a directory called dot fury so you don't see it and you don't really have to worry about those sources where they are or what they're doing they're part of your bills they get built when you compile your project but they're not really under your control what you can do with fury is you can actually bring an external project that you're depending on into your control you can fork it out of managed space into a directory on your hard disk and then you can edit that you can edit those shape the sources exactly as you edit your own projects you've effectively got your own cloned copy which you can then fork you can create a pull request back to the original shapeless if if you if you want to make a change now compare that to the experience with maven or SBT if you have a binary you depend on first of all you have to go and clone the right version of the sources that correspond to the binary you're currently working on then you have to build them and well maybe you make maybe you make a change maybe maybe the thing you want the bug you want to fix you change that you publish them locally now hopefully there's no other projects in between the thing you depend on and your project otherwise you've got to fix everything on along the way but you publish snapshot to your local ID cache you change your build to depend on that snapshot and then you can test whether the change you made back there actually fixed anything or whether you need to go back and reiterate over and over again every time has anyone had this experience yet so a few a few has anyone found a better way okay so there's a plug-in to make it easier okay okay okay so that there are there are alternative ways with with with fury you just fork it into a different directory and it's part of your project you can watch the files you can just edit them and it all just rebuilds whenever whenever you want so that experience I think should be nicer and also really encourages contributions if you if you find if you find an issue if you find a new feature you want to add it's really really easy for you to contribute back to the project and then when you've we need to find your project with modules and so on you probably want to share it with other people as that's hypothetical shape to stop fury repository was shared and because it's just a git repository that's managing the build file all you have to do is push it to a repository on gate and it's available instantaneously for other people to depend on there's a command and fury that that does that it also does some additional checks to make sure you don't publish something that that doesn't link correctly for example and it's a it's a one-liner it's it tags it with this this tag here and that's available you can tell people on Twitter seconds later that it's available we don't have to wait ages for everything to be released so some concepts let's talk about workspaces so I've mentioned workspaces before a workspace is a collection of projects and a build file defines a workspace and each project in that workspace and by the way frequently a workspace will only contain one project frequently they would contain many but a project contains one or more modules and if you remember a module corresponds to running the compiler once and the inputs are the same there's source files there's a class path there's a choice of compiler and probably some compiler parameters that's more or less everything that goes into defining what that module how that module runs and the outputs are the same every time as well the the outputs will be basically class files and they feed directly into the next compile phase the next module on the class path so this this is a compilation of graph it's a dag is it run ok with that kind of model just think of a a dag with each module being running the compiler and then they're feeding class files between them and as I mention before we can publish workspaces as git repositories so let's take a maybe a more realistic example these these rectangles here are meant to represent workspaces the green squares are projects and the blue dots are modules and linen Oscar yeah so I have I have slides on the cross building and also diamonds dependencies yeah they are like if you've picked on probably the two most important things for like solving problems for bills yeah so let's let's consider we have three workspaces one defines shape this way to find spire and one defines cats oh so the blue dots are modules so the blue dots are invoking the compiler and [Music] maybe you know that shapeless and cats both depend on macro paradise this is a this is a compiler plugin which which enhances what you can do with macros aspire doesn't as it turns out now note what these arrows are linking they're linking the workspace to the workspace so what I intend to imply here is that the the workspace inherits from another workspace so this is a workspace published on gate this is a different git repository and Katz is going to import from macro paradise likewise shapeless will and the dependencies between the modules become possible when when we have inheritance of the workspaces so if you think about cats this is this project just cats this is cats effect say they've each got a couple of modules and the the orange arrows are links between them it's not a very complicated graph but you can see that because because the cats workspace depends on the macro paradise workspace projects defined in macro paradise are available for us to depend on spire cannot depend on projects to find a macro paradise unless it inherits from that that workspace okay say if it's not and we can we can take this a bit further so we could actually define a type level workspace now type level workspace as I've drawn it here doesn't actually define any of its own projects but it pulls in others that maybe you want to include together shapeless spire cats they're all armed onyx they're all type level projects so let's bring them all together and share that as a workspace that other people can depend on and if they or inherit inherit from and if they pull in the type level workspace all of those projects are available for them to depend on so they can depend on cats they can depend on shapeless so it's one import you get all of those type level projects available to you and we can go even further the community build why not bring in other non type level protists why don't we compose our workspaces in such a way that we can aggregate sets of projects and distribute them so when you define your project in your workspace you can just depend on the community build and it brings in all of these and and many more a very important point which I will describe a bit later in more detail is that when you import a workspace you are guaranteed to him to be importing a coherent set of projects that means that if there's a project called shapeless you know that it will be exactly one version of shapeless it won't be there won't be any diamonds dependencies diamonds inheritance where you have two different projects which depend on version 1 and version 2 of shapeless and that somehow has to be reconciled that's reconciled already in the workspace you can't publish a workspace unless you've reconciled your dependencies so for any workspace a project name resolves to unique definition for that project but that's something you have to do as the as the publisher of the workspace let's look what schemas schemas are my answer to cross building so as as Oscar mentioned you have variations of bills that work for different backends different different versions of Scala sometimes different minor versions of Scala so if you're depending on the internals of the compiler you need to publish a different version of your plugin or whatever it is for each minor version if we're if we're using Scala Jess or Scala native we have different backends these typically present themselves as different cross builds which make the whole the whole building process with SBT somewhat more complicated and you may even have the need to depend on different versions of the same library you want to support different versions now this isn't typically called cross building in SBT I don't think but it is a form of cross building we've got different targets or even different libraries so I think there are libraries which offer integration with either cats or Scala said and they publish two different versions normally with underscore cats or underscore Scala Zed so I propose schemas as a way of supporting this and all these variations and a schema is actually a complete copy of the entire work space all the projects all the modules all the definitions that are in that ADT each schema is a complete copy but with some variations now those variations may be a different compiler the variation might be you depend on a different commit hash of a source repository they may be you add an additional source directory to a module it might be you a whole new project it doesn't matter but you can edit them as as a completely independent well almost completely independent copy of the workspace so you might ask why do we why not just use different workspaces for different lists instead of schemas why introduce this new concept the reason is that the tooling is designed to make it easier to maintain these because these builds these definitions the workspaces the schemas they're broadly the same for any any given project at any given workspace the - the - 12 version is probably largely the same as the - 11 version but we do need to maintain these differences so the tooling by which I mean fury is designed that you can either change things globally or you can make a specific change to just one schema and I've tried to design it I'm open to redesigns of the actual of how this actually works but I've tried to design it so that it's quite intuitive whether you're changing just one thing or changing everything across all schemers so adding adding adding a project it's probably something you want to do globally adding a module probably globally adding a source directory of shims that are needed to compile for Scala - 13 that's something which you would want to add just to one schema and the nice thing is that it's it's it allows you to change everything if you want it's not it's not limited to just a change in compiler or just just some magic relating to source directories it's it's the entire thing and you can get a nice diff between the two remember we're working with data it's a it's a tree structure but you can run a command in theory and get an instantaneous diff of all the differences and that I hope will keep you the information you need to maintain these variations and make it clear to you it easy to understand what's happening in your build forces or your your schema versus a different one so let's look at this this hypothetical workspace graph again I didn't give you the complete story before because actually when you inherit from another workspace you inherit from a particular schema in that workspace and the names of the schemas can be anything you like but a typically good name would be Scala 2:12 if it's compiling for Scala 212 so let's say that the type level workspace depends on the Scala 2:12 schema in each of shapeless spire and cats this is something you specify when you when you import it but because macro paralyzes maintaining versions for every different minor version we're going to call that dependency Scala 212 7 maybe you'll notice that this one depends on Scala 212 for which maybe is worrying because we have a conflict here and I actually built that the schema might be called something like latest so the community build might depend on the latest version of type level at all times so let's look at that potential conflict again I have a project down here you come this is I can't read what this has been to say this let's say this is your this is your project you depend on both shaped US and cats and they both depend on macro paradise this is depending on version 212 for this is for version 212 7 so we've actually got diamond dependency problem we're depending on different versions of macro the macro Paradise project we don't know given this how to resolve that that module there we don't know what we're compiling we don't know what the sources are we don't know what compilers being used so with with fury this is not something you can build any subtle difference is not not permitted but down here in in the workspace that depends on more than one other workspace in that that actually brings together the conflicting workspaces you have to resolve that and you resolve that by choosing one or the other you either choose the cats version or the shapeless version and you redefine the macro paradise project down here which means that when you publish your workspace this one at the bottom it will be fully resolved and that that project that's defined down there will effectively shadow the two variants up here so that when Katz's compiled it will use your definition when shapelessness compiled it will use your definition and the two definitions that are used up here and never use nuclear you can change that in any way you need to in order to make them both compile now diamond dependencies are not that there's no silver bullets for for fixing them that there are always going to be issues sometimes the solutions will be as hard as you need to actually fork either shape this or cats or macro paradise in order to get everything to compile together sometimes the API is just don't match up and you've got no they've got no possibility of making them working work unchanged but fury gives you the ability to fork if you really want to and I don't I don't recommend it unless it is really necessary you can fork these projects you can you can upgrade shapeless to use the two twelve seven version of macro paradise you can send the pull request back to the repository very easily and maybe miles will merge it so plugins who likes SVT's plugins I don't feel you can't say yes I like them I think more people like us we like it even says people like svt's plugins you do like you do like the plugins right people always talk about the great plug-in ecosystem with SBT like give SBT some cronies and they they they they to offer quite a wide variety of features there's a lot of things you can do with plugins often it seems to me like really probably we have of SBT there's a plug-in to solve it so the question is how will how will theory support these plugins and I said when I gave this talk at Scala IO that theory will have a plug-in API over my dead body because I think it's it's signing your death warrant to to commit to an API that needs access to the internals of of a bill tool it becomes so hard and so fragile to work with and it restricts your ability to to innovate and change things if you if you create an ecosystem of plugins you have to support them and I'm making the decision that Fury will not support plugins at least not in the same way as you're maybe familiar so I've got three answers to this question the first one is it won't the second one is natively so a lot of features could be brought into fury as native features so things like code coverage that could that could become a come a part of fury itself and this is this is I guess if you're familiar with like the Linux kernel versus the Windows NT kernel the Linux kernel defines everything every driver it's part of the same piece of software essentially Windows NT is a microkernel and has interfaces for for everything to to connect to it this is taking the Linux approach so certain things could be could become native features and that requires some sort of rapid release cycle which rains to be seen seeing whether we can do that but it does give me the ability to fully integrate those features into fury and give you a better user experience and finally as libraries now I mentioned the the graph of compilations and each node in that graph is basically a module an invocation of the compiler and I realized at some point that in addition to compiling the sources for that module I could additionally run them I could run a main method so I could run the thing I've just compiled and that main method could do all sorts of things it could generate sources for example no sources could feed into the next step now hopefully that's deterministic you probably wanted to be deterministic but if you want to opt out of that then you then you can but it gives us the ability to do all sorts of things at stages we want during compilation at stages in that graph as long as we can write them in Scala code and I'm talk about real Scala code not a DSL it's just a main method that is my that is the extent of my plug-in API there's a main method you pass it parameters and it returns an exit code which is either one or sorry it's either zero or nonzero if it's non zero compilation will stop if it's if it's zero then it carries on it was successful so this is how I would anticipate plug-in like behavior being implemented in in fury and of course those modules you define can depend on libraries so you can you can pull in a library for say wart remover which defines the compiler plugin and you can you can then run run that on your sources I think what or remove it doesn't run other sources does it but it can it can look at sources or look at look at the binary so do whatever you wanted to so let's look at some some plugins that people people use I just I just found a list online of popular plugins things like what remove would be a library others like things like native packager which produces some sort of artifact maybe a maybe it's a fancy jar in some way or a docker image that can actually happen entirely after fury has done its work after Fury's finished compilation you can just do that as a next phase unrelated to fury it doesn't need to be part of fury and the opposite side about is things like Scala format which works new sources it doesn't really need to be part of the build tool don't really need to compromise the complexity of my bill tool just to support things that aren't related to compilation course EA is already part of SBT I use it for downloading binaries s coverage I think that that would be really useful and it'd be great if it were much easier for us to get code coverage so that's something I want to make part of part of fury jmh that again I think could be easier so full integration is something I would like to support scholar Jeff's color native these are already supported SBT sono type just doesn't really need to exist so speaking of speaking of that publishing the current situation with publishing is problematic in in my opinion it affects the whole ecosystem so when we publish the binary to maven central that's only possible if all of the dependencies all of the binary dependencies are already published as well we have to wait for the authors or the maintainer zuv all of those libraries to publish first then we can publish ours and depend on them now this puts all sorts of silos in the publish in the publication process we're waiting on people all the time the people who are kindly devoting their time to open source as maintainer x' get this burden and they feel the pressure Sebastian Turan who's been publishing Scala des for a few years now he needs to make sure that as soon as Scala a new release of Scala comes out he's not on vacation he needs to be available and he has it in his diary he books out the time so that he can publish Scala Jets because if he doesn't do that and bear in mind until recently Sebastian was a just a humble PhD student he has to schedule his time so that he doesn't hold up the rest of the ecosystem everything depends on Scala dias Scala test depends on Scala Jess Scala test can't publish until Scala Jas has so we're waiting on him Scala test is published by Bill Venice bill does a there's a great and has done a great job for years maintaining scholar tests but he pays someone hard cash to do his publishing for him because he knows that the community depends on that and we're a we're a multi million probably approaching multi billion dollar industry and we're depending on a PhD student or former PhD student to publish things quickly there's something there's something wrong here it doesn't it seems that there's too much pressure and we need to distribute this work better we can't publish to maven central with source dependencies that's not a modern option we could potentially publish a fat jar containing all of our dependencies from from fury if we wanted to but that's only going to cause more problems when you try and put several of these fat jars onto the same class path and expect them to work it almost certainly won't so I have a solution again based on schemas where remember a schema is a variant of the it's a copy of the workspace with with variations those variations could actually be replacing source dependencies with binary dependencies now we don't have to mean we don't have to have this work all the time but if we're if we're going to do a release that we we want to be available to people with with binary dependencies we want to make it available on maven central we could do that with with a schema replacing all their source dependencies hoping we can find a coherent set that allows our project to compile and then that that's actually everything we need to publish to maven central if we if we wanted to I mean I don't care too much but I think you probably do care maven Central's not going to go away overnight so let's talk about the release for fury people have been asking me quite a lot recently about when it's going to be when it's gonna be released people seem very enthusiastic and I appreciate the enthusiasm I'm it the more enthusiasm I hear the more nervous I get but that people are going to be disappointed it and like if I've just sort of slipped it out the door a few months ago maybe that would have been better but instead I've gone around mostly Europe giving talks about fury and getting people's feedback and people have heard about it and and now they have great expectations so I'm I'm afraid of disappointment so I'm I'm instinctively holding back on on doing the release in fact that's all I've got on the release slide for now hold that thought we'll come back to it so any any bill tool needs support and I guess most people here are using SBT and that's received excellent support from Eugene and formerly Dale light Bend for a few years now and people get a good experience from that that support now I can say that fury will be fully supported by pensive now you may be think more preventive that's that's just you that's your Twitter handle which is true but preventive is also my company which is just me so where is the value in this in this this claim here so maybe you know a little bit about about what I do I do I do some training I organized a conference and I write open source software and and all these three things here this one owns me money this one breaks even and this one is a huge drain on my resources but but I like I like all of them but I do spend a lot of time writing open source software and not getting paid for it so you maybe maybe wonder how will propensity on find time to support theory so yeah small business and anyone adopting a new bill tool is is taking a leap of faith and I don't I don't take that that lightly so it's my intention to give you confidence in anything I I propose that it's not going to go away in two months and six months if I get run over by a bus there will be people to to support it that's what I that's the confidence I want to give people to use fury so I agreed a partnership deal with virtus lab maybe you know virtus they're growing very fast software development company in Krakov in Poland and they have given me a small team of people to work on fury starting next month and I am super excited about this this gives me so much freedom to explore more possibilities with fury that I wouldn't otherwise be able to do it should give you the confidence that it's you're not relying on one one guy who travels around the world and doesn't even have a permanent home you're relying on a stable established company that think that can support it so I'll be working closely with them over over the next few months and hopefully that should add credibility to fury as a viable product so if they've got over a hundred developers they have huge experience working with toolies they've got a lot of tooling work already they organized a conference in crackle of each year and I'm going to America to do lists for them so support for Windows it's not something I care about but I think it should be cared about that's on their list improvements to performance because they are particularly experts in that area integration testing I don't even know I don't even nearly enough testing the ability to export to SBT now why would I why would I do this well it's part of the confidence argument as well if I can tell if I tell you to adopt fury and once you get one to adopt fury you're locked in that's less of a viable prospect than if I say to you adopt fury and if anything goes wrong you can always export to SBT so that's something I want to provide people not because I think anyone should ever use it but so that you can you can try it out without worrying if you need to publishing to maven central implementing the build server protocol I don't have time to talk about that but general bug-fixing and also work on several of my other libraries so maybe you know I work on of Magnolia I'm going to give a talk on that tomorrow contextual kaleidoscope and I've forgotten - I've got to close the parentheses there oh no that it continues probation there's a I've even missed I've misspelled my library I I published it yesterday so I modified these slides like it's been to be called gastronomy anyway I've got a load of micro libraries which virtus will be helping me with because historically I haven't done a great job of providing excellent maintenance of these and having some help is going to be a huge benefit on my to-do list I've got some code cleanup to do I have support for Scala - yes the Scala native - to integrate Co coverage benchmarking and at there's a full list of issues which I I try to use to track threat project over it over at github the project's called preventative slash fury and I'm doing some work converting the ecosystem all of the bills that already exist out there for SBT I'm slowly converting them to two fury so what I would like you to do is try out fury you can't do that yet because I haven't published it that's what this little red asterisk is I can see that my time is up I'm aware you can you can help me out once you've started trying it you can come to Scala well next September and and help keep me fed and if you if your employer will be interested in sponsoring scholarship please come and talk to sponsoring Scala Wells to come and come and talk to me or ask me about training I can I can do advanced type level training now the road map let's talk about the road map I won first one out synchronized with Scala 2:13 so that we can have a bit of a race as to see who can publish the ecosystem faster for the new version of Scala I'm starting work with virtus lab on on the 1st of December and this says that the source code will be released pretty soon 2:57 on 15th of November and actually that's meant to say well I opened the I open the private beta to to a few users at the end of end of October it's 258 now you're familiar with things that's getting later and later ok ok let's let let's actually stand by what I said so I think all I need to do is that and if you if you check if you check the fury repository where is it over here I just refresh that the source code is now live so the source code is live but I that does come with the proviso that you have no way of building it and several of its dependencies aren't published but you can you can have a look at the source code and now I finally got I finally got it published which means I can now I now no longer have that hanging over my head instead I have the the fear that you will look closely at my sources and you'll realize I'm a terrible programmer so just to wrap up there is a private beta opening very very soon I've got a few more issues to fix as soon as the stuff I broke last night is is fixed I'll start sending out those those binaries go to preventative calm and follow the link to fury and there is a link there to sign up I just take a few details like what terminals go using and that's that's all I've got and I just want to say I've run out of time and I've gone over and I'm going around for next three days so please come and ask me questions I'm happy to answer anything and thank you for coming and listening [Applause]