Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Devkit. By the People, For the People.

Devkit. By the People, For the People.

We are still not working together on our projects. And that leads to frustration and hinders productivity.

See how by using a common developer tool you enforce a common process and a common language, boosting your projects and making developers happier.

475493db5519a08372c9367d879ef9ad?s=128

Vítor Brandão

April 11, 2018
Tweet

Transcript

  1. Devkit By the People, For the People. @noiselabs Vítor Brandão

    April 2018 ·
  2. https://noiselabs.io @noiselabs Vítor Brandão member since January 2015! member Noiselabs

    Consulting
  3. We are still not working together

  4. But we should.

  5. We ought to get rid of wasteful processes and strive

    for efficiency. But we should.
  6. We ought to get rid of wasteful processes and strive

    for efficiency. But we should. I'm committed to this.
  7. None
  8. ah you need to run the db script too Hi,

    how do I setup my environment? I see... oh, just git clone the app repo and run docker-compose up sometimes it fails so make sure you clear the cache
  9. I have a zsh script for this hmm, Matt might

    have a more complete script ...but it needs ruby, I think
  10. Enough.

  11. Sounds familiar? (if not, I'm happy for you)

  12. team "A group of individuals working together to achieve a

    goal." noun \ ˈtēm \
  13. Why are we not cooperating?

  14. Collaboration requires individual effort.
 


  15. Collaboration requires individual effort.
 
 You have to be mindful

    of others.
  16. Collaboration requires individual effort.
 
 You have to be mindful

    of others. 
 And you'll need to make concessions.
  17. Introducing a common tool may be hard.


  18. Introducing a common tool may be hard.
 But it's worth

    it.
 

  19. Introducing a common tool may be hard.
 But it's worth

    it.
 
 common tool ↝ common process
  20. Devkit developer toolkit

  21. This talk is not about a tool. It's about your

    team's tool.
  22. By the People, For the People* * s/People/Team

  23. None
  24. •Pick the mainstream programming language, not just the in-house ninja-

    rockstar favourite.

  25. •Pick the mainstream programming language, not just the in-house ninja-

    rockstar favourite.
 •Be inclusive: make it work across different OSes and setups and invite everyone to contribute.

  26. •Pick the mainstream programming language, not just the in-house ninja-

    rockstar favourite.
 •Be inclusive: make it work across different OSes and setups and invite everyone to contribute.
 •...but don't go too far, apply standard setups where needed. Compromise.
  27. •Make it dead easy to push fixes. This ain't production

    code.

  28. •Make it dead easy to push fixes. This ain't production

    code.
 •Think about non-devs.

  29. •Make it dead easy to push fixes. This ain't production

    code.
 •Think about non-devs.
 •Self-documentation is nice.

  30. •Make it dead easy to push fixes. This ain't production

    code.
 •Think about non-devs.
 •Self-documentation is nice.
 •Documentation is even nicer. A simple README.md will suffice.
  31. What do I get in return?

  32. •Fix it once, fix it everywhere, for everybody.


  33. •Fix it once, fix it everywhere, for everybody.
 •Speak a

    common language.

  34. •Fix it once, fix it everywhere, for everybody.
 •Speak a

    common language.
 •The setup is now (self-)documented.
 

  35. •Fix it once, fix it everywhere, for everybody.
 •Speak a

    common language.
 •The setup is now (self-)documented.
 
 On-boarding will be much easier, much faster.
  36. "There should be one-- and preferably only one --obvious way

    to do it." -- The Zen of Python
  37. devkit@noiselabs (a devkit to get you started)

  38. https://github.com/noiselabs/devkit

  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. // devkit/DevkitApplication.php abstract class DevkitApplication extends SymfonyConsoleApplication { public function

    __construct(?string $name = null, ?string $version = null) { // ... $this->container = new \Pimple\Container(); $this->buildContainer(); $this->registerCommands(); } private function buildContainer(): void { $this->setService('app_settings', function () { return AppSettings::fromConfig(); }); $this->setService('env', function (Container $c) { return new Environment($c['app_settings']); }); $this->setService('local_executor', function () { return new LocalExecutor(); }); $this->setService('docker_remote_executor', function (Container $c) { return new DockerRemoteExecutor($c['env']->getDockerDir()); }); $this->setService('vagrant_remote_executor', function (Container $c) { return new DockerRemoteExecutor($c['env']->getVagrantDir()); }); }
  48. // devkit/DevkitApplication.php abstract class DevkitApplication extends SymfonyConsoleApplication { // ...

    public function setService(string $name, $service): void { $this->container[$name] = $service; } public function getService(string $name): string { if (!isset($this->container[$name])) { throw new RuntimeException(sprintf('Service "%s" is not available.', $name)); } return $this->container[$name]; } private function registerCommands(): void { $this->addCommands([ new Command\Docker\DockerLogs, new Command\Docker\DockerShell, new Command\Docker\DockerStart, new Command\Docker\DockerStop, new Command\PhpQa\Phan, new Command\PhpQa\Phpstan, new Command\Phpqa\QaList, new Command\Vagrant\VagrantHalt, new Command\Vagrant\VagrantUp, ]); } }
  49. // devkit/Infra/Command/DockerCompose.php /** * Define and run multi-container applications with

    Docker. */ class DockerCompose { /** * build: Build or rebuild services. */ public static function build(?string $service = null, ?string $command = null, array $options = []): DockerRemoteCommand { return self::buildDockerCommand('build', $service, $command, $options); } /** * exec: Execute a command in a running container. */ public static function exec(string $service, string $command, array $options = []): DockerRemoteCommand { return self::buildDockerCommand('exec', $service, $command, $options); } /** * run: Run a one-off command. */ public static function run(string $service, string $command, array $options = []): DockerRemoteCommand { return self::buildDockerCommand('run --rm', $service, $command, $options); } // ...
  50. // app/bin/devkit <?php use Noiselabs\DevkitApp\Application; $autoloadFilePath = __DIR__ . '/../../vendor/autoload.php';

    require_once $autoloadFilePath; $application = new Application(); $application->run();
  51. <?php namespace Noiselabs\DevkitApp; use Noiselabs\Devkit\DevkitApplication; use Noiselabs\DevkitApp\Command as Command; class

    Application extends DevkitApplication { const APP_NAME = 'DevkitApp'; const APP_VERSION = '0.1.0'; public function __construct( ?string $name = self::APP_NAME, ?string $version = self::APP_VERSION) { parent::__construct($name, $version); $this->setService('remote_executor', $this->getService('docker_remote_executor')); $this->addCommands([ new Command\EnvDown, new Command\EnvReload, new Command\EnvSetup, new Command\EnvUp, ]); } }
  52. // app/src/Command/EnvUp.php namespace Noiselabs\DevkitApp\Command; // ... class EnvUp extends DevkitCliCommand

    { protected function configure() { $this->setName('env:up'); $this->setDescription('Boots the development environment'); } protected function execute(InputInterface $input, OutputInterface $output): void { $io = $this->getConsoleIo($input, $output); $io->writeln(Environment::OUTPUT_TITLE_PREFIX . 'Booting the development environment...'); $this->getApplication()->find('cache:clear')->run(new ArrayInput([]), $output); $this->executeRemoteCommand(DockerCompose::up(null, ['-d']), $input, $output); $this->getApplication()->find('database:reset')->run(new ArrayInput([]), $output); } }
  53. None
  54. Before you go

  55. •communicate •collaborate •be efficient •be happy

  56. By the People, For the People. Devkit Thank You https://joind.in/talk/96595

    @noiselabs Vítor Brandão