Tumgik
guzart · 7 years
Text
Domain Events from Entities
The best approach to using Domain Events in your application is to separate the responsibility of creating the events from the responsibility of dispatching the events.
The responsability of creating the events should be delegated to either the Entity or the Domain Service, while the responsability of dispatching the events is an Application level concern.
One technique to do this in OOP is to add an events list to your entity, the entity uses this list to "queue" the events that have been generated from its internal operations.
Let's talk code now.
class ShoppingCart < Entity # ... attr_reader :domain_events def initialize(...args) @domain_events = [] end def add_product(product) # ... event = ProductAddedEvent.new(...) domain_events.push(event) end end
Then later the application service in charge of persistance, and any other requirements can dispatch the entity events.
class ShoppingCartService # ... def add_product(product_id) product = policy_scope(Product).find(product_id) shopping_cart.add_product(product) dispatch_events shopping_cart.domain_events end end
0 notes
guzart · 7 years
Text
Elm and CSS
In a previous post I described how to use neutrino along with the neutrino-preset-elm package to build production ready Elm applications.
In order to add stylesheets using elm-css, you can use the [email protected] version to support stylesheets
❯ yarn add [email protected]
The preset will look for required files whose name finishes with Stylesheets.elm and load them using elm-css-webpack-loader.
All you have to do in your code is require an elm module that has an elm-css port.
// src/index.js require('./MyAppStylesheets.elm'); var Elm = require('./Main.elm'); Elm.Main.embed(document.getElementById('root'));
An example of the Stylesheets elm module
-- MyAppStylesheets.elm port module Stylesheets exposing (..) import Css.File exposing (CssFileStructure, CssCompilerProgram) import MyCss port files : CssFileStructure -> Cmd msg fileStructure : CssFileStructure fileStructure = Css.File.toFileStructure [ ( "index.css", Css.File.compile [ MyCss.css ] ) ] main : CssCompilerProgram main = Css.File.compiler files fileStructure
1 note · View note
guzart · 7 years
Text
Git commits manipulation
A very simple way of manipulating the commits in a git branch is to use the rebase command on its own branch.
❯ git rebase -i HEAD~6
In this example we want an interactive screen where we can choose what to do with the last six commits, just follow the instructions to pick, squash or skip commits and save the document.
1 note · View note
guzart · 7 years
Text
Rails with Wercker and Heroku
Wercker is an incredibly versatile CI/CD Automation Platform. The fact that it’s based on Docker means that all Docker containers are available for your CI environment.
TLDR; Here’s the configuration for running Rails automated tests (including capybara features) using Wercker.
box: guzart/rails-app:020407070021 build: services: - id: mysql tag: 5.7 env: MYSQL_ROOT_PASSWORD: 123SecretPassword MYSQL_DATABASE: fancy_app_test steps: # https://github.com/wercker/step-npm-install/blob/master/run.sh - script: name: yarn-install cwd: web/ code: | mkdir -p "$WERCKER_CACHE_DIR/wercker/yarn" yarn config set cache-folder "$WERCKER_CACHE_DIR/wercker/npm" yarn install - wercker/bundle-install - script: name: wait-for-mysql code: | curl -O https://raw.githubusercontent.com/vishnubob/wait-for-it/55c54a5abdfb32637b563b28cc088314b162195e/wait-for-it.sh chmod +x ./wait-for-it.sh ./wait-for-it.sh $MYSQL_PORT_3306_TCP_ADDR:$MYSQL_PORT_3306_TCP_PORT -t 30 - script: name: rails-setup-database code: | export FANCY_APP_DATABASE_HOST="$MYSQL_PORT_3306_TCP_ADDR" export FANCY_APP_DATABASE_PASSWORD="123SecretPassword" export FANCY_APP_DATABASE_PORT="$MYSQL_PORT_3306_TCP_PORT" export FANCY_APP_DATABASE_USERNAME="root" export FANCY_APP_DATABASE="fancy_app_test" bundle exec rails db:migrate - script: name: rspec code: xvfb-run -a bundle exec rspec
We start by defining the container to use, if you are running exclusively a rails application you can use the ruby:2.4 container, however since I am running a Rails application in conjuction with a React SPA, I created my own container that includes Ruby, Node.js and Yarn.
box: guzart/rails-app:020407070021
Next, we start the declaration of the build pipeline; the build pipeline will be where we get the container ready to run the tests and then run the tests.
Add any database services that your application needs, in this example we add a MySQL database.
build: services: - id: mysql tag: 5.7 env: MYSQL_ROOT_PASSWORD: 123SecretPassword MYSQL_DATABASE: fancy_app_test
After declaring the services needed by our application, we start the declaration of the steps that are needed to get the application ready for running the tests.
steps:
Because in my project there is a React SPA application in the web/ subdirectory, we install the SPA node modules using Yarn. Notice we change the CWD (current working dictory) to the web subdirectory.
# https://github.com/wercker/step-npm-install/blob/master/run.sh - script: name: yarn-install cwd: web/ code: | mkdir -p "$WERCKER_CACHE_DIR/wercker/yarn" yarn config set cache-folder "$WERCKER_CACHE_DIR/wercker/npm" yarn install
Then install the bundle gems, using a pre-existing Step.
- wercker/bundle-install
We must make sure that the MySQL service is up and running before continuing with the next steps, We’ve run the dependency installations first to give the MySQL service time to fire up the engines.
- script: name: wait-for-mysql code: | curl -O https://raw.githubusercontent.com/vishnubob/wait-for-it/55c54a5abdfb32637b563b28cc088314b162195e/wait-for-it.sh chmod +x ./wait-for-it.sh ./wait-for-it.sh $MYSQL_PORT_3306_TCP_ADDR:$MYSQL_PORT_3306_TCP_PORT -t 30
Now we can create the Rails application database and run the migrations.
- script: name: rails-setup-database code: | export FANCY_APP_DATABASE_HOST="$MYSQL_PORT_3306_TCP_ADDR" export FANCY_APP_DATABASE_PASSWORD="123SecretPassword" export FANCY_APP_DATABASE_PORT="$MYSQL_PORT_3306_TCP_PORT" export FANCY_APP_DATABASE_USERNAME="root" export FANCY_APP_DATABASE="fancy_app_test" bundle exec rails db:migrate
This steps assumes that you have a database.yml with the following configuration:
default: &default adapter: mysql2 collation: utf8mb4_unicode_ci encoding: utf8mb4 host: password: pool: 5 port: socket: /tmp/mysql.sock username: test:
And finally we run the tests using the xvfb-run utility.
- script: name: rspec code: xvfb-run -a bundle exec rspec
0 notes
guzart · 7 years
Text
Docker: Ruby, Node.js and Yarn container
For my latest project I created a Docker container with Ruby, NodeJs and Yarn. This allowed me to easily run a Ruby on Rails API with a React SPA in a single container.
Since I run the automated “end-to-end” tests using Capybara-webkit, I also needed the xvfb package to run a vitual screen on the CI server.
FROM ruby:2.4 # Install capybara-webkit deps RUN apt-get update \ && apt-get install -y xvfb qt5-default libqt5webkit5-dev \ gstreamer1.0-plugins-base gstreamer1.0-tools gstreamer1.0-x # Node.js RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - \ && apt-get install -y nodejs # yarn RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -\ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ && apt-get update \ && apt-get install -y yarn CMD [ "bash" ]
Feel free to use the guzart/rails-app container, if you don’t want to create your own.
0 notes
guzart · 7 years
Text
Simple Elm production builds
As stated in the Elm tutorial.
The Elm reactor is great for prototyping simple applications, but for a bigger app it falls short.
To easily get a production quality build for your Elm application you can use Neutrino a fantastic tool built by Mozilla for building application using Webpack.
By default, Neutrino will look for your application entry point at src/indes.js, so we’ll need to ensure we mount the Elm application in that file.
❯ mkdir src && touch src/index.js ❯ npm init ❯ npm install --save-dev neutrino neutrino-preset-elm
// src/index.js const Elm = require('./Main.elm'); const mountNode = document.getElementById('root'); const app = Elm.Main.embed(mountNode);
Next make sure to tell your Elm application to load the Elm files from the src directory.
// elm-package.json { "source-directories": [ "src" ] }
Finally, tell neutrino to use the neutrino-preset-elm package and add some conveniece scripts.
// package.json { "scripts": { "start": "neutrino start", "build": "neutrino build" }, "neutrino": { "use": [ "neutrino-preset-elm" ] } }
That’s it you can start the development server using npm start, or make a production build using npm run build.
0 notes
guzart · 7 years
Text
Running Webpack from RSpec
For my latest project I created a mono repo with a Rails API and an React SPA with Webpack.
Doing “end-to-end” testing is very easy when you do it on the Rails side using capybara, because you have full control over the database and can take full advantage of factories.
To run the Webpack server and run your “end-to-end” tests on your SPA using Capybara you can use the childprocess gem to run the webpack.
Add this configuration to your spec/support folder:
# spec/support/capybara.rb require 'capybara/rails' require 'capybara/rspec' WEB_TEST_PORT = '5005'.freeze WEB_TEST_URL = "http://localhost:#{WEB_TEST_PORT}".freeze def capybara_wait_for_neutrino 10.times.each do |_| begin Net::HTTP.get(URI(WEB_TEST_URL)) return rescue Errno::ECONNREFUSED sleep 1 end end end # https://github.com/thoughtbot/capybara-webkit#configuration Capybara::Webkit.configure do |config| config.raise_javascript_errors = true end # https://github.com/teamcapybara/capybara/blob/master/lib/capybara.rb#L35 Capybara.configure do |config| config.register_server :puntastic do |app, port, host| process = ChildProcess.build('yarn', 'start') # process.io.inherit! # uncomment for debugging process.environment['WEB_PORT'] = WEB_TEST_PORT process.environment['API_URL'] = "#{host}:#{port}" process.cwd = Rails.root.join('web') process.leader = true process.detach = true begin Net::HTTP.get(URI(WEB_TEST_URL)) rescue process.start at_exit { process.stop unless process.exited? } capybara_wait_for_neutrino end options = { Host: host, Port: port, Threads: "0:4", Silent: true } Rack::Handler::Puma.run(app, options) end config.default_driver = :webkit config.javascript_driver = :webkit config.server = :puntastic config.run_server = true config.app_host = WEB_TEST_URL end
0 notes
guzart · 11 years
Text
rbenv PATH in production
export PATH="$HOME/.rbenv/bin:$PATH"
Now lets say you are deploying with Capitrano which executes the commands using 'sh' as opposed the the commonly used 'bash', you should set the path at /etc/profile.d/username.sh
0 notes
guzart · 11 years
Text
Rebuild the RPM DB
$ rm -f /var/lib/rpm/__db*
$ yum clean all
$ rpm –-rebuilddb
0 notes
guzart · 11 years
Text
perl locale issues?
List your server locales and choose one
$ locale -a
Now setup the locale on you /etc/profile file, add it before the export to PATH, around the middle of the file
export LC_ALL="en_US.utf8"
Or you can add the following line to /etc/default/locale
LC_CTYPE=en_US.utf8
On debian you can select the locales by running
sudo apt-get install debconf sudo dpkg-reconfigure locales sudo locale-gen
0 notes
guzart · 11 years
Text
Find Your Public IP
wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'
0 notes
guzart · 11 years
Text
Homebrew Maintenance
Every once in a while do some maintenance to your Homebrew install by pruning, cleaning, and repairing.
$ brew prune $ brew cleanup $ brew update $ brew tap --repair $ brew doctor
0 notes
guzart · 11 years
Text
Precompile Ember Templates with Guard and Nodejs
To precompile Ember templates you need to do it in a context with Ember loaded. That is because Ember adds some helpers to Handlebars.
To compile the templates in an Ember context I used the ember-precompile Node.js package. This means that Node.js is another development dependency, but I think the optimisation benefit you get from precompiling the templates is worth it.
I wrote the following guard plugin, to compile and merge the watched templates into a single output file.
0 notes
guzart · 11 years
Text
Rvm install ree on Mountain Lion
Install XCode command-line tools
Install gcc-4.2
$ brew tap homebrew/dupes $ brew install apple-gcc42
Install xquarts (X11)
Install ree
$ CPPFLAGS=-I/opt/X11/include \    CC=/usr/local/bin/gcc-4.2 \    rbenv install ree-1.8.7-2012.02
0 notes
guzart · 11 years
Text
Setup Git - Bitbucket - Redmine 1.x
Follow the instructions to install the Avalarion's Redmine Bitbucket plugin.
I had to manually install the 'json' gem by adding it manually to the Redmine Gemfile and running:
$ bundle install
You now have a folder within the redmine install, that you can change in the plugin settings. Or, you should create it.
Clone the repo to your plugin repo path
$ cd path/to/plugin/repo/path $ git clone --bare https://bitbucket.org/author/my_code
Rename the repo folder to include the author username as a prefix of the repo path.
$ mv my_code.git author_my_code.git
Give the server application the ownership.
$ chown www-data:www-data author_my_code
Note for Apache-Passenger users: www-data is the default user for apache, it's not recommended that you give permission to this user. Best if you create a 'rails' user and assign it as the Passenger user. (#PassengerUser)
Test that you can run a git fetch as your web app user
$ cd path/to/redmine/repo $ sudo -u user git fetch
Note: Make sure the user has the ssh keys to pull from the server, or that the git remote url has the username and password (Not recommended). 
Add the following settings to the repo, so that it will pull all commits and all tags for all branches using a "git fetch"
$ git config remote.origin.fetch +refs/heads/*:refs/heads/* $ git config --add remote.origin.fetch +refs/tags/*:refs/tags/*
0 notes
guzart · 11 years
Text
Generate SSH Keys
# Generate the key $ ssh-keygen -t rsa -C "[email protected]"
# Copy to clipboard $ pbcopy < ~/.ssh/id_rsa.pub
0 notes
guzart · 11 years
Text
Copy SSH keys to server
Using ssh-copy-id utility:
ssh-copy-id -i .ssh/id_rsa.pub username:password@hostname
Standard pipe
cat ~/.ssh/id_rsa.pub | ssh user@hostname 'cat >> ~/.ssh/authorized_keys'
0 notes