-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeed.rss
403 lines (363 loc) · 72.3 KB
/
feed.rss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content"><channel><title>Alexander Ross</title><description>I like to build apps, websites, other tools and solutions to make the day more fun and efficient. I want to share as much as possible here as often as possible. But normaly I end up with a few posts per year right now. Work and family takes time as well 😇.</description><link>https://aross.se</link><language>en</language><lastBuildDate>Thu, 14 Jan 2021 13:31:33 +0100</lastBuildDate><pubDate>Thu, 14 Jan 2021 13:31:33 +0100</pubDate><ttl>250</ttl><atom:link href="https://aross.se/feed.rss" rel="self" type="application/rss+xml"/><item><guid isPermaLink="true">https://aross.se/posts/2021-01-14-Install-ruby%2021-on-macos-big-sur</guid><title>Install ruby 2.1 on macOS Big Sur</title><description>Install ruby 2.1 on macOS Big Sur</description><link>https://aross.se/posts/2021-01-14-Install-ruby%2021-on-macos-big-sur</link><pubDate>Thu, 14 Jan 2021 12:00:00 +0100</pubDate><content:encoded><![CDATA[<h1>Install ruby 2.1 on macOS Big Sur</h1><p>Installing ruby 2.1 on macOS Big Sur may be cumbersome. You should probably not use 2.1 for new projects but if you like me you may have an old project around that needs an upgrade. And testing in the old ruby version the project was written for first is not a bad start.</p><p>However when I tried to install the Ruby 2.1.10 for the project I got a lot of compilation errors and Google suggested a lot of solutions for me that did not work. But a combination of them did. So here is a TLDR version of the solution that did work for me.</p><p>Install OpenSSL 1.0 with Homebrew. This can live side by side with the latest version of OpenSSL available in Homebrew.</p><pre data-language="bash"><code>brew install rbenv/tap/[email protected]
</code></pre><p>Install Ruby 2.1.10 using <code>asdf</code> with some additional compiler configurations.</p><pre data-language="bash"><code>PKG_CONFIG_PATH=<span class="hljs-string">"<span class="hljs-variable">$(brew --prefix [email protected])</span>/lib/pkgconfig"</span> \
LDFLAGS=<span class="hljs-string">"-L<span class="hljs-variable">$(brew --prefix [email protected])</span>/lib"</span> \
CPPFLAGS=<span class="hljs-string">"-I<span class="hljs-variable">$(brew --prefix [email protected])</span>/include"</span> \
PATH=<span class="hljs-string">"<span class="hljs-variable">$(brew --prefix [email protected])</span>/bin:<span class="hljs-variable">$PATH</span>"</span> \
CONFIGURE_OPTS=<span class="hljs-string">"--with-openssl-dir=<span class="hljs-variable">$(brew --prefix [email protected])</span>"</span> \
RUBY_CONFIGURE_OPTS=<span class="hljs-string">"--with-openssl-dir=<span class="hljs-variable">$(brew --prefix [email protected])</span> --with-readline-dir=<span class="hljs-variable">$(brew --prefix readline)</span>"</span> \
optflags=<span class="hljs-string">"-Wno-error=implicit-function-declaration"</span> \
asdf install ruby 2.1.10
</code></pre><p><code>asdf</code> is using <code>ruby-build</code> behind the scene. So do most <code>rbenv</code> installations as well. So if you use <code>rbenv</code> you should be able to replace the last part <code>asdf install ruby 2.1.10</code> with <code>rbenv install 2.1.10</code>.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/script-with-swift</guid><title>Script with swift</title><description>Script with Swift</description><link>https://aross.se/posts/script-with-swift</link><pubDate>Mon, 20 Jan 2020 01:00:00 +0100</pubDate><content:encoded><![CDATA[<h1>Script with swift</h1><p>If you are a swift developer you probably know already how to create an executable swift package or an command line tool using XCode. But then you also have to build the binary and place it in a executable path. Sometimes we just want to write a file and execute it as is. It's kind of common to do that with bash or ruby as small tools.</p><p>If we would create a bash file and execute it we could create a file named <code>bashscript</code> and add this content.</p><pre data-language="bash"><code><span class="hljs-meta">#!/usr/bin/env bash
</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello, World!"</span>
</code></pre><p>Then you need to make it executable with <code>$ chmod u+x bashscript</code> and now you can execute the file with <code>$ ./bashscript</code>.</p><p>But this is not limited to runtime languages. The magic commend with "#!" tells what program to use when evaluating the content of the file. So you can use that with swift as well.</p><p>Lets create a file called <code>swiftscript</code> and add this content.</p><pre data-language="swift"><code>#!/usr/bin/env swift
<span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello, World!"</span>)
</code></pre><p>Then again, make it executable with <code>$ chmod u+x swiftscript</code> and now you can execute that script with <code>$ ./swiftscript</code>.</p><p>This is a great way to build small tools that you need and you can modify your script whenever you need without the need to manually recompile.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2019-08-03-create-iso-image-from-directory</guid><title>Create ISO image from directory</title><description>How to create an ISO image from any directory using hdiutil on macOS</description><link>https://aross.se/posts/2019-08-03-create-iso-image-from-directory</link><pubDate>Sat, 3 Aug 2019 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Create ISO image from directory</h1><p>I was using VirtualBox to run an older version of OS X. I had some files that I needed from my host computer but hadn't set up any shared directories. I was using <code>hdiutil</code> to create an ISO for the OS X and figured that I could move files from my host computer using another ISO because it can be mounted without any restarts.</p><p>No additional tools is needed since <code>hdiutil</code> comes with OS X/macOS.</p><p>This is basically it:</p><pre data-language="bash"><code>hdiutil makehybrid -o ~/Desktop/image.iso /directory/to/make/iso/of -iso -joliet
</code></pre><p>You could use the command above as is and just change <code>/directory/to/make/iso/of</code> to the path you would like an iso of. But if you are interested in a breakdown of the command it comes here.</p><ul><li><code>hdiutil</code> a tool that comes with macOS to manipulate disk images</li><li><code>makehybrid -o [image] [source]</code> the hdiutil verb to generate a read-only disk image with given image and source path</li><li><code>-iso</code> create the disk image as an ISO which is an cross-platform format</li><li><code>-joliet</code> the filesystem for the disk image. OS X/macOS will prefer the Joliet filesystem according to the man pages of hdiutil.</li></ul>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2019-01-12-make-all-new-commits-verified-at-github</guid><title>Make all new commits verified at GitHub</title><description>A guide to add GPG signatures on all your git commits. Expects that you already have git and HomeBrew installed on your macOS machine.</description><link>https://aross.se/posts/2019-01-12-make-all-new-commits-verified-at-github</link><pubDate>Sat, 12 Jan 2019 12:00:00 +0100</pubDate><content:encoded><![CDATA[<h1>Make all new commits verified at GitHub</h1><p><em>A guide to add GPG signatures on all your git commits. Expects that you already have git and HomeBrew installed on your macOS machine.</em></p><p>When you create a git commit you are free to set any author. For example, let say you would like to create a git commit and make it look like DHH, the creator of <a href="https://rubyonrails.org">Ruby on Rails</a> and founder of <a href="https://basecamp.com">Basecamp</a>, did the commit. The only thing you need to do is to set the author like this.</p><pre data-language="bash"><code>$ git commit --author=<span class="hljs-string">"dhh <[email protected]>"</span>
</code></pre><p>So you can't actually be sure who did commit the code. A solution is to GPG sign the commits to add a verified symbol on GitHub that the commit is authorized by you.</p><p>A signed commit will look like this on GitHub.</p><img src="https://dsc.cloud/aross/Screenshot-2019-01-12-at-15.05.01-ChEdIEJ3F8UXcYZiWs5LTRpKqFGp745VJFtm5fCgFnveSqOEBQusR2LWx6tfG7Z9ZoefoRwbzh3HfXlxYRqVyakEXkwncVHpgyge.png" alt="Image of signed commit from DHH"/><p>An unsigned commit will look like this on GitHub.</p><img src="https://dsc.cloud/aross/Screenshot-2019-01-12-at-15.05.07-lESI8EJ6Eu15AHR3TZk1sYjToFFyEInkUOJGo6UTgfSq5tZ7rD3xAwLzHKCi2pIsqopYBE3Qob8ySfJcLOo0jpY9zpdtaiZE8qJx.png" alt="Image of unsigned commit from DHH"/><h2>Generate GPG key</h2><p>You need GnuPG to get started. Lets install it using HomeBrew.</p><pre data-language="bash"><code>$ brew install gnupg
</code></pre><p>Run the command below and enter your name when asked to. And when asked for your email address, make sure you set the same as the one you use with git.</p><p>Make sure you set a good pass phrase and remember it or store it in a password manager like 1Password and LastPass if you have to write it down anywhere.</p><pre data-language="bash"><code>$ gpg --default-new-key-algo rsa4096 --gen-key
</code></pre><h2>Export public key and add to GitHub</h2><p>First you need to know your key-id. Run the following.</p><pre data-language="bash"><code>$ gpg --list-secret-keys --keyid-format LONG
/Users/foobar/.gnupg/pubring.kbx
------------------------------
sec rsa4096/3AA5C34371567BD2 2019-01-12 [SC] [expires: 2021-01-11]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid My Name <[email protected]>
</code></pre><p>In the example above the key-id is <code>3AA5C34371567BD2</code>. Copy your public key using command below, replace the <code><key-id></code> with your key-id.</p><pre data-language="bash"><code>$ gpg --armor --<span class="hljs-built_in">export</span> <key-id> | pbcopy
</code></pre><p>The public key will know be in your clipboard and you can paste it using <code>⌘v</code>. So lets go to your SSH and GPG keys at GitHub.</p><p>Either you click at this link <a href="https://github.com/settings/keys">https://github.com/settings/keys</a> or you navigate to GitHub, click at your profile image at the top right corner, click at settings and then SSH and GPG keys in the left menu.</p><p>Click at "New GPG key". Paste your public key and confirm.</p><h2>Use pinentry-mac to remember pass phrase in macOS Keychain</h2><p>The pass phrase should be secure and hard to guess and it would be great if you don't have to remember it in your head. So let make sure the macOS Keychain will remember it for you.</p><p>Install pinentry-mac.</p><pre data-language="bash"><code>$ brew install pinentry-mac
</code></pre><p>Connect GPG agent to macOS Keychain via pinentry. Storing it in Keychain via pinentry will allow us to setup automatically key signing.</p><pre data-language="bash"><code>$ mkdir -p ~/.gnupg
$ <span class="hljs-built_in">echo</span> <span class="hljs-string">"pinentry-program /usr/local/bin/pinentry-mac"</span> > ~/.gnupg/gpg-agent.conf
</code></pre><h2>Configure git to automatically gpgsign your commits</h2><p>Get your key id just as we did at "Export public key and add to GitHub". Then run the following in the terminal. Replace the <code><key-id></code> with your key-id.</p><pre data-language="bash"><code>$ git config --global user.signingkey <key-id>
$ git config --global commit.gpgsign <span class="hljs-literal">true</span>
$ git config --global tag.forceSignAnnotated <span class="hljs-literal">true</span>
</code></pre><h2>Try it out</h2><p>If you had GPG agent installed before we recommend that you kill it to make sure it will restart with new settings.</p><pre data-language="bash"><code>$ killall gpg-agent
</code></pre><p>Create a test git directory</p><pre data-language="bash"><code>$ mkdir gittest
$ <span class="hljs-built_in">cd</span> gittest
$ git init
$ <span class="hljs-built_in">echo</span> <span class="hljs-string">"test"</span> > test.txt
$ git add test.txt
$ git commit -m <span class="hljs-string">"test"</span>
</code></pre><p>First time you commit a pine entry popup will appear and ask for the pass phrase. Make sure you also save it in Keychain so that you don't need to type in pass phrase every time.</p><img src="https://dsc.cloud/aross/Screenshot-2019-01-12-at-16.10.48-XO9aFzqMZIkLwr5SAeAByzQqSCzFInRQleiACDYv1wI7QGi5AYezLHFuwdhVFnZEUMFEsrX6qvnaIMmYpQUedLzQY23hDqtcE3PU.png" alt="Image of popup window from Pinentry Mac"/><p>If you create and push the repository to GitHub you will now see that it contains a verified commit.</p><img src="https://dsc.cloud/aross/Screenshot-2019-01-12-at-16.19.24-5yjz5AknDg7daHt38lAc83QD7pyPQvI5v5lIJWXsherJS6oT2ugj7DLMq2GKoIjGVkKuPmbV6GexzAX8f4dzezftx1cTY99aEOBo.png" alt="Image of verified test commit"/>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2018-06-17-ios-ui-tests-for-custom-url-scheme</guid><title>iOS UI tests for custom URL scheme</title><description></description><link>https://aross.se/posts/2018-06-17-ios-ui-tests-for-custom-url-scheme</link><pubDate>Sun, 17 Jun 2018 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>iOS UI tests for custom URL scheme</h1><p>UI tests is a great way to test that your application behaves as you expect it to and also to verify that you don't break any features in the future. If you are used to write unit tests you may also be used to write your code using dependency injections or to mock and stub dependencies. In UI tests however, you don't have access to your code and to simulate a user as close as possible you will probably write your tests and interact with other services just as a regular user. Then you can be quite sure that your app is working as it should.</p><p>In this post I will go through how to write UI tests for a custom URL scheme in iOS. If you haven't read or need to know how to implement custom URL scheme you can take another look at my blog post "<a href="https://aross.se/posts/2018-05-21-implement-custom-url-scheme-in-ios/">Implement custom URL scheme in iOS</a>". I will continue with the source code created using that blog post. So if you would like to test it yourself you can go back and implement it or download the source code by the link below.</p><p><a href="https://github.com/alex-ross/URLViewer/archive/1.zip">Download source code</a>.</p><h2>Create a UI Test target</h2><p>We need a UI test target to run UI tests on the simulator or our development device. So lets create one first.</p><p>Go to the "test navigator", see the image below.</p><img src="https://aross.se/images/posts/2018-06-17/show-test-navigator.png"/><p>Then at the bottom left corner you will find a "+" button, click on that one and then on "New UI Test Target..."</p><img src="https://aross.se/images/posts/2018-06-17/add-ui-test-target-1.png"/><p>You will probably have everything pre filled now, but make sure that the project is the same as the current one and that "target to test" is the actually iOS application that you are testing.</p><img src="https://aross.se/images/posts/2018-06-17/add-ui-test-target-2.png"/><p>Click "Finish" and your test target should now be created. It will also create a test file that you can open, it will be named "URLViewerUITests.swift".</p><h2>Write the tests</h2><p>Usually I start to remove all comments in the generated files because it just creates a lot of noise. You can also remove the <code>tearDown</code>, we will not use that right now. Finally I also like to have a variable called <code>app</code> for the application itself. So lets add that one and set it up in the <code>setUp</code> method. You should end up with something similar to the code below. Feel free to copy that one if you need.</p><pre data-language="swift"><code><span class="hljs-keyword">import</span> XCTest
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">URLViewerUITests</span>: <span class="hljs-title">XCTestCase</span> </span>{
<span class="hljs-keyword">var</span> app: <span class="hljs-type">XCUIApplication!</span>
<span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">setUp</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword">super</span>.setUp()
continueAfterFailure = <span class="hljs-literal">false</span>
app = <span class="hljs-type">XCUIApplication</span>()
app.launch()
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">testExample</span><span class="hljs-params">()</span></span> {
}
}
</code></pre><p>You can run all tests using <code>⌘</code>+<code>u</code>. It should open the application in the simulator and then tell you that all tests passes because we don't assert anything right now.</p><p>In our first test we would like to test that the application launches as usual and that it has the correct default text. This is a simple test and should look like this.</p><pre data-language="swift"><code><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">testDefaultLabelWhenOpenApp</span><span class="hljs-params">()</span></span> {
<span class="hljs-type">XCTAssert</span>(app.staticTexts[<span class="hljs-string">"Label"</span>].exists)
}
</code></pre><p>It will basically check that we have the static text "Label" in our application which we should have because it's the default text we did set to the label. So if that will change anytime, the test will fail. If you run the tests using</p><p><code>⌘</code>+<code>u</code> again it should still pass. But try to change the text to something else and you will see that it will not pass any more.</p><p>But we would also like to test that the application changes the URL to the one that it was opened with. We do know that we can use Safari in the simulator simulate that the application was opened using an URL. We can automate other applications in the UI tests as well and use Accessibility Inspector to find the identifiers for the components we would like to tap or interact with.</p><p>Use Xcode meny bar and open Accessibility Inspector. You will find it at <strong>Xcode</strong> ‣ <strong>Open Developer Tools</strong> ‣ <strong>Accessibility Inspector</strong>.</p><img src="https://aross.se/images/posts/2018-06-17/accessibility-inspector-open.png"/><p>Then you can activate the inspection by tapping the button in the circle at the image below. You will se that the pointer is at the address bar and it will tell you that the address bar component has the identifier "URL". We can use that to target the component and tap it.</p><img src="https://aross.se/images/posts/2018-06-17/accessibility-inspector-inspect.png"/><p>Se the complete test below.</p><pre data-language="swift"><code><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">testLabelTextWhenOpenedByURL</span><span class="hljs-params">()</span></span> {
<span class="hljs-comment">// Get the safari app using its bundle identifier</span>
<span class="hljs-keyword">let</span> safari = <span class="hljs-type">XCUIApplication</span>(bundleIdentifier: <span class="hljs-string">"com.apple.mobilesafari"</span>)
<span class="hljs-comment">// Launch safari</span>
safari.launch()
<span class="hljs-comment">// Ensure that safari is running in foreground before we continue</span>
<span class="hljs-number">_</span> = safari.wait(<span class="hljs-keyword">for</span>: .runningForeground, timeout: <span class="hljs-number">30</span>)
<span class="hljs-comment">// Access the address bar component and tap it</span>
safari.buttons[<span class="hljs-string">"URL"</span>].tap()
<span class="hljs-comment">// You will now have a cursor in the address field. So lets type in the text for our URL</span>
safari.typeText(<span class="hljs-string">"urlviewer://example"</span>)
<span class="hljs-comment">// Make a new line character to simulate that the user taps the return key</span>
safari.typeText(<span class="hljs-string">"\n"</span>)
<span class="hljs-comment">// An pop-up will open and ask you to launch the application. Tap it's "Open" button to confirm</span>
safari.buttons[<span class="hljs-string">"Open"</span>].tap()
<span class="hljs-comment">// Wait for your application to be the one in foreground</span>
<span class="hljs-number">_</span> = app.wait(<span class="hljs-keyword">for</span>: .runningForeground, timeout: <span class="hljs-number">5</span>)
<span class="hljs-comment">// Now we can assert that we do display the URL in our application</span>
<span class="hljs-type">XCTAssert</span>(app.staticTexts[<span class="hljs-string">"urlviewer://example"</span>].exists)
}
</code></pre><p>Run the test again and make sure it still passes.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2018-05-21-implement-custom-url-scheme-in-ios</guid><title>Implement custom URL scheme in iOS</title><description></description><link>https://aross.se/posts/2018-05-21-implement-custom-url-scheme-in-ios</link><pubDate>Mon, 21 May 2018 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Implement custom URL scheme in iOS</h1><p>Custom URL schemes is a great way to enable automation in your application for power users or to allowing users or other developers to go to a view or a state in your app by using a URL just like browsing the web.</p><p>This blog post will help you create a application with a label that displays whatever URL it was open with. Using URLs can be very powerful and you could basically automate any tasks using them. But keep in mind to be responsible and validate the URLs later on, especially if your users has important data in the application and you allowing them to delete everything using an URL. Maybe you don't want that to happened just because the user clicked a link on the web.</p><p>You could for example in the same application, or from another one open this application with this code.</p><pre data-language="swift"><code><span class="hljs-type">UIApplication</span>.shared
.<span class="hljs-keyword">open</span>(<span class="hljs-type">URL</span>(string: <span class="hljs-string">"urlviewer://HelloWorld"</span>)!,
options: [:],
completionHandler: <span class="hljs-literal">nil</span>)
</code></pre><p>You can use this feature also to link to places inside your own application</p><h2>Create the application</h2><p>Launch Xcode and create a new Xcode project. Select "iOS" and "Single View App". Name the project whatever you like. I will name my application "URLViewer". We will not use tests or core data right know so leave them unchecked. Make sure you select the language "Swift".</p><h2>Create a view where we can view that it works</h2><p>Open "Main.storyboard" and place a label into the middle of the screen. Add constraints around the label so it is 8 points from left, right, top and bottom of the safe area.</p><p>Select "Character Wrap" in the "Line Break" option to make sure that the URL will be fully displayed even if it's a long one.</p><p>Open the "ViewController.swift" file in the assistant editor by holding down option key while you click on the file in the file tree.</p><p>Select the label, then click and hold on the label while dragging the mouse cursor to the view controller. Drag the cursor to an empty place inside the view controller class and drop it where it fits, you will get an blue horizontal line where you can drop it. Name the outlet <code>urlLabel</code>. It should create a row that looks like this.</p><pre data-language="swift"><code><span class="hljs-meta">@IBOutlet</span> <span class="hljs-keyword">weak</span> <span class="hljs-keyword">var</span> urlLabel: <span class="hljs-type">UILabel!</span>
</code></pre><p>You should now be able to start the application and see that you have a simple label in the middle of the screen.</p><h2>Register the URL scheme</h2><p>Open the file "Info.plist" and add a new entry called "URL types". To add a new entry you can select any existing one, for example "Bundle name" and press the enter/return-key on your keyboard.</p><p>Expand "URL types" and the first child element, you will now see a element with the key "URL identifier". This should be the same identifier as your application. So it is easiest to enter <code>$(PRODUCT_BUNDLE_IDENTIFIER)</code> and it will use whatever bundle identifier you already setup.</p><p>Now you should add a new key just under the "URL identifier". Call it "URL Schemes". It will be an array of strings and we open that one and add our URL scheme as the first item. I will call it <code>urlviewer</code>.</p><p>When the app is launched iOS will now register that url scheme for the application. Note that it should be kind of unique, but their is now validation of that in iOS or from Apple. So anyone could basically create an application with the same scheme and you and the user will not be the one that decides which app it will open in. So don't include to much secrets into the URLs.</p><img src="https://aross.se/images/posts/2018-05-21/infoplist.png" width="90%" alt="Info.plist Screenshot" /><p>You can test that the application responds to the url scheme already by running the application, go to home and open safari on the device. Now you enter and submit <code>urlviewer://</code> in the adress field and it will ask you to open the application.</p><p>When we open the application with the URL it will do nothing. So in next step, lets add whatever URL the user typed with that scheme to our url label that we created earlier.</p><h2>Read the URL the user launched the app with</h2><p>To read the URL you need to implement the method <code>application(_:open:options)</code> in the <code>AppDelegate</code>. Write it like below.</p><pre data-language="swift"><code><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">application</span><span class="hljs-params">(<span class="hljs-number">_</span> app: UIApplication,
<span class="hljs-keyword">open</span> url: URL,
options: [UIApplicationOpenURLOptionsKey : <span class="hljs-keyword">Any</span>] = [:])</span></span> -> <span class="hljs-type">Bool</span> {
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
}
</code></pre><p>This method will be called when the application is launched with a URL. The URL will be accessible for us in the variable <code>url</code>. So lets take that and add it to our label.</p><p>We can access the root view controller through the window. We only have one controller in the project we can also be sure that it's the <code>ViewController</code>.</p><pre data-language="swift"><code><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">application</span><span class="hljs-params">(<span class="hljs-number">_</span> app: UIApplication,
<span class="hljs-keyword">open</span> url: URL,
options: [UIApplicationOpenURLOptionsKey : <span class="hljs-keyword">Any</span>] = [:])</span></span> -> <span class="hljs-type">Bool</span> {
<span class="hljs-keyword">let</span> vc = window?.rootViewController <span class="hljs-keyword">as</span>! <span class="hljs-type">ViewController</span>
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
}
</code></pre><p>Now when we have access to the view controller we can set the label text to the same as the url.</p><pre data-language="swift"><code><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">application</span><span class="hljs-params">(<span class="hljs-number">_</span> app: UIApplication,
<span class="hljs-keyword">open</span> url: URL,
options: [UIApplicationOpenURLOptionsKey : <span class="hljs-keyword">Any</span>] = [:])</span></span> -> <span class="hljs-type">Bool</span> {
<span class="hljs-keyword">let</span> vc = window?.rootViewController <span class="hljs-keyword">as</span>! <span class="hljs-type">ViewController</span>
vc.urlLabel.text = url.absoluteString
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
}
</code></pre><p>Run the application again. First you will only see the text "Label" as before. But if you go to Safari and enter <code>urlviewer://foobar</code> it will show that instead, and <code>urlviewer://example</code> will change it to that value.</p><p>Hope you did well following along. Please comment and tell me what you are planning to use custom url schemes for.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2017-10-14-start-delayed-job-on-boot-and-restart-on-deploy</guid><title>Start Delayed Job on boot and restart on deploy</title><description></description><link>https://aross.se/posts/2017-10-14-start-delayed-job-on-boot-and-restart-on-deploy</link><pubDate>Sat, 14 Oct 2017 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Start Delayed Job on boot and restart on deploy</h1><p>If you have an rails application that is running delayed job for its background processes you probably would like it to start automatically whenever the server restarts. But you will also need it to restart if your rails applications are deployed so you can be sure that it is running the latest version of it.</p><p>The process below should work great on Ubuntu 14.04 and newer versions.</p><h2>Create an Upstart script</h2><p>Lets say that we have a rails application that are running as the user myapp and that it needs to initialise rbenv. Then this is the script you would like to add in <code>/etc/init/delayed_job.conf</code></p><pre data-language="bash"><code><span class="hljs-comment"># /etc/init/delayed_job.conf</span>
description <span class="hljs-string">"Delayed Job Background Worker"</span>
<span class="hljs-comment"># Set user that will run the service</span>
setuid myapp
setgid myapp
env HOME=/home/myapp
<span class="hljs-comment"># Start when system enters runlevel 2 (multi-user mode).</span>
start on runlevel 2
<span class="hljs-comment"># Restart the process if it dies with a signal</span>
<span class="hljs-comment"># or exit code not given by the 'normal exit' stanza.</span>
respawn
<span class="hljs-comment"># Give up if restart occurs 10 times in 90 seconds.</span>
respawn <span class="hljs-built_in">limit</span> 10 90
script
<span class="hljs-comment"># this script runs in /bin/sh by default</span>
<span class="hljs-comment"># respawn as bash so we can source in rbenv</span>
<span class="hljs-built_in">exec</span> /bin/bash <<<span class="hljs-string">'EOT'</span>
<span class="hljs-comment"># Set home path</span>
<span class="hljs-built_in">export</span> HOME=/home/myapp
<span class="hljs-comment"># Add rbenv to path</span>
<span class="hljs-built_in">export</span> PATH=<span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.rbenv/bin:<span class="hljs-variable">$PATH</span>"</span>
<span class="hljs-comment"># Initialize rbenv</span>
<span class="hljs-built_in">eval</span> <span class="hljs-string">"<span class="hljs-variable">$(rbenv init -)</span>"</span>
<span class="hljs-comment"># Add rbenv plugins to path</span>
<span class="hljs-built_in">export</span> PATH=<span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.rbenv/plugins/ruby-build/bin:<span class="hljs-variable">$PATH</span>"</span>
<span class="hljs-comment"># Set rails environment</span>
<span class="hljs-built_in">export</span> RAILS_ENV=production
<span class="hljs-comment"># Go to the application directory</span>
<span class="hljs-built_in">cd</span> /var/www/myapp/current
<span class="hljs-comment"># Run delayed job</span>
<span class="hljs-built_in">exec</span> bin/delayed_job run
EOT
end script
</code></pre><p>Now, allow root to read and write but the rest should only be able to read the file.</p><pre data-language="bash"><code>$ sudo chmod 644 /etc/init/delayed_job.conf
</code></pre><p>Now delayed job will be started when your server starts.</p><p>You can start it now by running this command:</p><pre data-language="bash"><code>$ sudo initctl start delayed_job
</code></pre><h2>Allow user to start and stop delayed job without password</h2><p>This step is kind of a preparation for the next step when we need to restart on deploy. The delayed job service that the user of the application should be able to control. We will now make the user able to start and stop the process using sudo but without password. That will enable us to create a script for capistrano later on which can execute the task.</p><p>Create your new sudo override file using this command</p><pre data-language="bash"><code>$ sudo visudo -f /etc/sudoers.d/delayed_job
</code></pre><p>Add this content</p><pre data-language="bash"><code><span class="hljs-comment"># /etc/sudoers.d/delayed_job</span>
myapp ALL=NOPASSWD:/sbin/initctl start delayed_job, /sbin/initctl status delayed_job, /sbin/initctl stop delayed_job
</code></pre><h2>Restart Delayed Job on deploy</h2><p>When you make a new deployment of your source code you don't want the delayed job process to still be running on the old version of the code. To fix that we should restart delayed job on deployment.</p><p>If you had delayed job in your application before you may have this line in your <code>Capfile</code>.</p><pre data-language="ruby"><code><span class="hljs-keyword">require</span> <span class="hljs-string">'capistrano/delayed-job'</span>
</code></pre><p>You must remove that one now if you have it. It basically does the same thing that we will add now but without using upstart.</p><p>We will now create a new file that will host our start, stop and restart tasks. Create a file at <code>lib/capistrano/tasks/delayed_job.rake</code> and add the content below.</p><pre data-language="ruby"><code><span class="hljs-comment"># lib/capistrano/tasks/delayed_job.rake</span>
namespace <span class="hljs-symbol">:delayed_job</span> <span class="hljs-keyword">do</span>
<span class="hljs-comment"># Fetches the role for delayed job. Using :app as default</span>
<span class="hljs-comment"># if delayed_job_server_role was not set.</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">delayed_job_roles</span></span>
fetch(<span class="hljs-symbol">:delayed_job_server_role</span>, <span class="hljs-symbol">:app</span>)
<span class="hljs-keyword">end</span>
desc <span class="hljs-string">'Stop the delayed_job process'</span>
task <span class="hljs-symbol">:stop</span> <span class="hljs-keyword">do</span>
on roles(delayed_job_roles) <span class="hljs-keyword">do</span>
execute <span class="hljs-symbol">:sudo</span>, <span class="hljs-symbol">:initctl</span>, <span class="hljs-symbol">:stop</span>, <span class="hljs-symbol">:delayed_job</span>
<span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
desc <span class="hljs-string">'Start the delayed_job process'</span>
task <span class="hljs-symbol">:start</span> <span class="hljs-keyword">do</span>
on roles(delayed_job_roles) <span class="hljs-keyword">do</span>
execute <span class="hljs-symbol">:sudo</span>, <span class="hljs-symbol">:initctl</span>, <span class="hljs-symbol">:start</span>, <span class="hljs-symbol">:delayed_job</span>
<span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
desc <span class="hljs-string">'Restart the delayed_job process'</span>
task <span class="hljs-symbol">:restart</span> <span class="hljs-keyword">do</span>
on roles(delayed_job_roles) <span class="hljs-keyword">do</span>
execute <span class="hljs-symbol">:sudo</span>, <span class="hljs-symbol">:initctl</span>, <span class="hljs-symbol">:stop</span>, <span class="hljs-symbol">:delayed_job</span>
execute <span class="hljs-symbol">:sudo</span>, <span class="hljs-symbol">:initctl</span>, <span class="hljs-symbol">:start</span>, <span class="hljs-symbol">:delayed_job</span>
<span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre><p>To make the restart command runs when you deploy, add this to your <code>config/deploy.rb</code> file.</p><pre data-language="ruby"><code>after <span class="hljs-string">'deploy:publishing'</span>, <span class="hljs-string">'delayed_job:restart'</span>
</code></pre><p>Now whenever someone deploys a new version using <code>cap production deploy</code> for example it will also restart the delayed job process. It will also respawn on failure and start it when the server reboots.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2017-07-24-yatzy-protocol-for-iphone</guid><title>Yatzy Protocol for iPhone</title><description></description><link>https://aross.se/posts/2017-07-24-yatzy-protocol-for-iphone</link><pubDate>Mon, 24 Jul 2017 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Yatzy Protocol for iPhone</h1><p>Yatzy is a game you play with 5 dices together with your friends.</p><p>If you don't have any yatzy protocol papers you can use an app I created called Yatzy Protocol which is available on App Store for iPhone.</p><img src="https://aross.se/images/posts/2017-07-24/yatzy%20app%20iphone%20screenshot.jpeg" width="35%" alt="iPhone Screenshot" /><a href="https://appsto.re/se/4VUplb.i" target="_blank">
<img src="https://aross.se/images/posts/2017-07-24/Download_on_the_App_Store_Badge_US-UK_135x40.svg" alt="Download on App Store" />
</a><p>Please use the comments for any questions or discussion about the game. You can also send me an email at [email protected] about any questions regarding the iPhone application.</p><h2>Rules</h2><p>This is a game for one or more people. You play with 5 dices. First player roll all the dices at once. The player then decides which dices to keep an which to re roll. You can re roll 2 times (So a 3 rolls per turn totally).</p><p>When the player have rolled the dices 3 times she picks a category to place the score in. For all valid dice you get the same number of points as you have dots on the dices. So a six gives you 6 points and a four gives you four points and so on. Yatzy and bonus is an exception for this rule.</p><h3>Upper section</h3><p>The upper section contains the following categories:</p><ul><li>ones</li><li>twos</li><li>threes</li><li>fours</li><li>fives</li><li>sixes</li></ul><p>If you choose to place your scores at sixes you will get six points per dice with a six on it. If you choose fives you get five points per dice with a five on it. And so on.</p><p>So the maximum score for each category is 5 for ones, 10 for twos, 15 for threes, 20 for fours, 25 for fives and 30 for sixes.</p><h3>Bonus</h3><p>If the summary of the upper section is 63 or more you get 50 bonus points.</p><h3>Lower section</h3><p>The lower section contains the following categories:</p><ul><li><strong>pair</strong>: If 2 dices has the same value they are a pair. You score the total number of the dices. Lowest is 2 if you get two dices with the value 1. Highest are 12 if you get 2 dices of the value 6.</li><li><strong>2 pair</strong>: Same as pair but 2 pair of dices with the same value. Dices that also counts as 4 of kind are not a valid 2 pair. Lowest score are 6 if you score 2 dices of value 1 and 2 dices of value 2. Highest are 22 if you have pair in 5 and 6.</li><li><strong>3 of a kind</strong>: 3 dices of the same value. You score the number of the 3 dices together.So 3 points if you get 3 of 1 and 18 points if you get 3 of 6.</li><li><strong>4 of a kind</strong>: 4 dices of the same value. You score the number of the 4 dices together.So 4 points if you get 4 of 1 and 24 points if you get 4 of 6.</li><li><strong>full house</strong>: 3 of a kind together with a pair.</li><li><strong>small straight</strong>: The dices are a straight from 1-5. This will give you 15 points (1+2+3+4+5=15)</li><li><strong>large straight</strong>: The dices are a straight from 2-6. This will give you 20 points (2+3+4+5+6=20).</li><li><strong>chance</strong>: Everything is valid as a chance. You get the total number of all 5 dices.</li><li><strong>yatzy</strong>: 5 dices of the same value. This will always give you 50 points.</li></ul><p>So all valid dices will give you the same number of points as the value on the dices except from yatzy which are always worth 50 points.</p><h3>Strike</h3><p>If your result won't fit in any category or if the category is already used you have to strike any of the category you have left. You do that by placing zero points in it.</p><h3>The winner</h3><p>When all players played all their categories the winner is the one with highest score.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2015-12-07-configure-rubocop-for-your-project</guid><title>Configure RuboCop for your project</title><description>RuboCop is a Ruby static code analyzer. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide.</description><link>https://aross.se/posts/2015-12-07-configure-rubocop-for-your-project</link><pubDate>Mon, 7 Dec 2015 19:24:00 +0100</pubDate><content:encoded><![CDATA[<h1>Configure RuboCop for your project</h1><blockquote><p>RuboCop is a Ruby static code analyzer. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide.</p></blockquote><p>-- From their <a href="rubocop">GitHub README.md</a></p><p>We use RuboCop for most of our projects at <a href="standout">Standout AB</a> . It will help the team to follow the style guide we all agreed on. If we change our opinion it is also easy to just change the <code>.rubocop.yml</code> file to match it.</p><p>Installing and configure RuboCop is pretty simple if you are following <a href="ruby_style_guide">this Ruby Style Guide</a>.</p><p>Just add it to your <code>Gemfile</code></p><pre data-language="ruby"><code>gem <span class="hljs-string">"rubocop"</span>, <span class="hljs-symbol">require:</span> <span class="hljs-literal">false</span>
</code></pre><p>And then run <code>bundle install</code> in your terminal to install it.</p><p>You will already be able to run <code>rubocop</code> in the terminal to analyze your code.</p><h2>Project specific configurations</h2><p>If you're not completely satisfied with the Ruby Style Guide as is you can create a file called <code>.rubocop.yml</code> and add your settings there. Take a look at the gem's <a href="default_config">default configuration files</a> to get an idea of what you can change to match your or your's team coding style.</p><p>Our configuration file looks like this:</p><pre data-language="yaml"><code><span class="hljs-comment"># .rubocop.yml</span>
<span class="hljs-attr">AllCops:</span>
<span class="hljs-attr">RunRailsCops:</span> <span class="hljs-literal">true</span>
<span class="hljs-attr">DisplayCopNames:</span> <span class="hljs-literal">true</span>
<span class="hljs-attr">DisplayStyleGuide:</span> <span class="hljs-literal">true</span>
<span class="hljs-attr">Exclude:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">"bin/*"</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">Capfile</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">config/boot.rb</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">config/environment.rb</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">config/initializers/version.rb</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">db/schema.rb</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">Gemfile</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">Guardfile</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">Rakefile</span>
<span class="hljs-attr">Metrics/LineLength:</span>
<span class="hljs-attr">Exclude:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">"config/**/*"</span>
<span class="hljs-attr">Style/ClassAndModuleChildren:</span>
<span class="hljs-attr">Enabled:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">Style/Documentation:</span>
<span class="hljs-attr">Enabled:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">Style/DoubleNegation:</span>
<span class="hljs-attr">Enabled:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">Style/SpaceAroundEqualsInParameterDefault:</span>
<span class="hljs-attr">EnforcedStyle:</span> <span class="hljs-string">no_space</span>
<span class="hljs-attr">Style/StringLiterals:</span>
<span class="hljs-attr">EnforcedStyle:</span> <span class="hljs-string">double_quotes</span>
<span class="hljs-attr">Style/TrivialAccessors:</span>
<span class="hljs-attr">AllowPredicates:</span> <span class="hljs-literal">true</span>
<span class="hljs-attr">Style/SingleSpaceBeforeFirstArg:</span>
<span class="hljs-attr">Enabled:</span> <span class="hljs-literal">false</span>
</code></pre><p>Feel free to copy and change. You can also get the up to date version with curl at any time.</p><pre data-language="bash"><code>curl -o .rubocop.yml https://raw.githubusercontent.com/standout/Coding/master/ruby/rubocop.yml
</code></pre><h2>Ignore current errors for bigger projects</h2><p>If you're not starting a new project you may find out that you already have a lot of errors and warnings when you run <code>rubocop</code>. If you have a huge code base and not the time to fix it all now, you can tell RuboCop to create you a todo file. The point of this file is to ignore all current errors and you should try to remove settings from this file over time until you can remove the hole file.</p><p>This file is called <code>.rubocop_todo.yml</code> and can be created using:</p><pre data-language="bash"><code>rubocop --auto-gen-config
</code></pre><p>You also need to add this at the top of your <code>.rubocop.yml</code> file to load it:</p><pre data-language="yaml"><code><span class="hljs-attr">inherit_from:</span> <span class="hljs-string">.rubocop_todo.yml</span>
</code></pre>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2015-07-27-how-to-ssh-through-ssh-proxy</guid><title>How to SSH through SSH proxy</title><description></description><link>https://aross.se/posts/2015-07-27-how-to-ssh-through-ssh-proxy</link><pubDate>Mon, 27 Jul 2015 17:58:00 +0200</pubDate><content:encoded><![CDATA[<h1>How to SSH through SSH proxy</h1><p>At our company we do not want any outsiders to access our servers through SSH. Often we prevent logins to root and prevent logins with password. But to be even more secure we started to only allow logins from the IP addresses at our office.</p><p>At our office we have an Mac Mini that is open for SSH to all employees. Here we can have a main list of allowed SSH keys and IP addresses and everyone can SSH Proxy through this one. This makes it a lot easier for us to manage access.</p><h2>So how do you SSH through another server</h2><p>Lets say that our computer we want to use as an SSH Proxy has the domain "proxy.example.com" and the server we will ssh to has "database.example.com". Lets also assume that the user for both servers in my case are "aross".</p><p>SSH has a lot of options we can use. The one we will use is called</p><p><code>ProxyCommand</code>. We will first give it user and host to the proxy server followed by the <code>-W</code>-flag where we tell it to which host and port we want to bind this proxy to. Instead of writing host and port in this case we can use the placeholders <code>%h</code> for <strong>h</strong>ost and <code>%p</code> for <strong>p</strong>ort and the ssh service will figure it all out by itself.</p><p>The command will look like this</p><pre data-language="undefined"><code>
ssh -o ProxyCommand='ssh [email protected] -W %h:%p' [email protected]
</code></pre><p>Thats basically it. If you do this allot you could simplify the process by editing your <code>~/.ssh/config</code> file.</p><p>Add this to <code>~/.ssh/config/</code></p><pre data-language="undefined"><code>
Host officeproxy
User aross
HostName proxy.example.com
Host database.example.com
HostName database.example.com
ProxyCommand ssh officeproxy -W %h:%p
</code></pre><p>Now when you do <code>ssh [email protected]</code> SSH will set up the proxy for you according to the config file.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2015-07-19-how-to-update-locate-database-on-osx</guid><title>How to update locate database on OS X</title><description>Use locate on mac to search for files</description><link>https://aross.se/posts/2015-07-19-how-to-update-locate-database-on-osx</link><pubDate>Sun, 19 Jul 2015 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>How to update locate database on OS X</h1><p><code>locate</code> is a great tool both on Linux and Mac when searching for files in the terminal. But sometimes the database will be out of sync with whats really on the hard drives. On Linux you typically can use the commands <code>updatedb</code> or</p><p><code>locate -u</code> (<code>-u</code> as in <strong>u</strong>pdate) to update it. These commands are not available on OS X though.</p><p>The feature it self is not gone of course. To update the database on OS X you have to run:</p><pre data-language="undefined"><code>
sudo /usr/libexec/locate.updatedb
</code></pre><p>This will take a few minutes but when it's done your database is up to date. This will also work to build the database if you didn't had one before.</p><p>If you would like to have the command <code>updatedb</code> to get a more consistent behavior between your Linux and Mac environment you can symlink it to</p><p><code>/usr/local/bin</code>.</p><pre data-language="undefined"><code>
cd /usr/local/bin
ln -s /usr/libexec/locate.updatedb updatedb
</code></pre><p>Now you can restart the terminal and have <code>updatedb</code> available.</p><p>If it is not available you may not have <code>/usr/local/bin</code> in your <code>$PATH</code> variable. Lets then add it to your <code>~/.bashrc</code> file.</p><pre data-language="undefined"><code>
# ~/.bashrc
export PATH="/usr/local/bin:$PATH"
</code></pre>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2015-06-22-create-and-apply-git-patch-files</guid><title>Create and apply Git patch files</title><description></description><link>https://aross.se/posts/2015-06-22-create-and-apply-git-patch-files</link><pubDate>Mon, 22 Jun 2015 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Create and apply Git patch files</h1><p>When working with Git most of us are used to have something like GitHub or Bitbucket where we can create pull requests and assign to people. This may not always be the case and then it is good to have another option. With Git you can also create a patch file which later on can be sent by email or transfered over an USB-stick to someone that will apply it in the main repository.</p><p>Let's assume that you and me are two awesome people in a train without internet and we have a really good project idea. We are going to write a story together using Git.</p><h2>Let me start by creating the first chapter</h2><p>I will create our project in the terminal and name it "The Pink Octopus" just as we agreed on, right?</p><pre data-language="bash"><code>mkdir the-pink-ocptopus
<span class="hljs-built_in">cd</span> the-pink-ocptopus
git init
</code></pre><p>I will also create our first chapter with some todos in it for you and make the first commit.</p><p>(I'm using <code>cat</code> and not vim or any other editor just to make it as copy-and-paste friendly as possible)</p><pre data-language="bash"><code>cat > chapter-1.md << THE_END
<span class="hljs-comment"># Chapter 1</span>
Once upon a time a pink octopus was borned.
It<span class="hljs-string">'s favorite color was FILL_IN, but the octopus didn'</span>t know how to change to
that color.
THE_END
git add chapter-1.md
git commit -m <span class="hljs-string">"Initial commit"</span>
</code></pre><p>Let's now pretend that I'm transferring this project to you with and USB-stick or similar.</p><h2>You can now fill in the missing content</h2><p>Create and navigate to the branch <code>choose-color</code>.</p><pre data-language="bash"><code>git checkout -b choose-color
</code></pre><p>Open the file <code>chapter-1.md</code> in your favorite editor and replace <code>FILL_IN</code> with any color of your choice. In the examples below I guessed that you choosed "yellow as a banana".</p><p>Commit your changes.</p><pre data-language="bash"><code>git commit -am <span class="hljs-string">"Pickes a favorite color for the octopus"</span>
</code></pre><p>Now when you run <code>git diff master</code> you will get something similar to this</p><pre data-language="undefined"><code>
diff --git a/chapter-1.md b/chapter-1.md
index c4b6233..d85aa9d 100644
--- a/chapter-1.md
+++ b/chapter-1.md
@@ -1,5 +1,5 @@
# Chapter 1
Once upon a time a pink octopus was borned.
-It's favorite color was FILL_IN, but the octopus didn't know how to change to
+It's favorite color was yellow as a banana, but the octopus didn't know how to change to
that color.
</code></pre><h2>Now you are ready to create your patch file</h2><p>To create the patch file use this</p><pre data-language="bash"><code>git format-patch master --stdout > choose-color.patch
</code></pre><p>This will now create a file in the same directory called <code>choose-color.patch</code>. If you skip the <code>--stdout > choose-color.patch</code>-part you will get one patch file per commit. That may work fine in this example because we have only one commit. Feel free to add another commit just to see what the difference will be if you skip that part.</p><p>Let's now again pretend that you are transferring this file to me over an USB-stick or another awesome method.</p><h2>I will now test the patch file and apply it</h2><p>(Checkout master using <code>git checkout master</code> just because I guess you are doing my part to.)</p><p>Before we apply the patch I like to check the diffstat which is kind of a summary of what the patch will do.</p><pre data-language="bash"><code>git apply --<span class="hljs-built_in">stat</span> choose-color.patch
</code></pre><p>This command will not apply anything. The output will be something similar to this.</p><pre data-language="undefined"><code>
chapter-1.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
</code></pre><p>Next step is to see if we will get any errors when we applying it.</p><pre data-language="bash"><code>git apply --check choose-color.patch
</code></pre><p>If I get no output I'm good to go. Lets apply this patch!</p><p>When applying the patch I will actually <strong>not</strong> use <code>git apply choose-color.patch</code>. If I do, I will only apply the changes to my git index but I will not obtain any commit messages. Instead I will use <code>git am</code> and I will also use the <code>--signoff</code> option so that other people can see in the history (using <code>git log</code>) that I was the one approving this changes.</p><pre data-language="bash"><code>git am --signoff < choose-color.patch
</code></pre><p>The output will be.</p><pre data-language="undefined"><code>
Applying: Pickes a favorite color for the octopus
</code></pre><p>Now your patch file is applied and we can continue writing our story on the train.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2014-10-01-install-nginx-side-by-side-with-apache</guid><title>Install Nginx side by side with Apache</title><description></description><link>https://aross.se/posts/2014-10-01-install-nginx-side-by-side-with-apache</link><pubDate>Wed, 1 Oct 2014 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Install Nginx side by side with Apache</h1><p>Before we start you should make sure your openssl is updated. Run <code>rpm -q openssl</code> and if this reports version <code>1.0.1e</code> and less than <code>1.0.1e-16.el6_5.4.0.1</code> then you are vulnerable to heartbleed. One of the biggest security issues. Read <a href="update_open_ssl">Update openssl on Red Hat</a> before you continue. We also need version <code>1.0.1</code> or higher to install Nginx.</p><p>First of you can check if Nginx is available on your system by running</p><p><code>yum info nginx</code>. It should now show you the available package with its version included, in my case <code>Version : 1.0.15</code>. If it's not available or if you get an old version like me (the latest one is currently <code>1.6.2</code>) then you need to add there official repo to yum. Create and open <code>/etc/yum.repos.d/nginx.repo</code> in your favorite editor and add the config below.</p><pre data-language="undefined"><code>
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/rhel/$releasever/$basearch/
gpgcheck=0
enabled=1
</code></pre><p>If you run <code>yum info nginx</code> again you should now get <code>Version : 1.6.2</code> or later. Then install it with <code>yum install nginx</code>.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2014-09-28-fix-unable-to-start-the-phusion-passenger-watchdog</guid><title>Fix: Unable to start the Phusion Passenger watchdog</title><description>[error] *** Passenger could not be initialized because of this error: Unable to start the Phusion Passenger watchdog (/usr/local/lib/ruby/gems/2.1.0/gems/passenger-4.0.52/buildout/agents/PassengerWatchdog): Permission denied (errno=13)</description><link>https://aross.se/posts/2014-09-28-fix-unable-to-start-the-phusion-passenger-watchdog</link><pubDate>Sun, 28 Sep 2014 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Fix: Unable to start the Phusion Passenger watchdog</h1><p>Does this look familiar for you? If it does, then you are on the right place.</p><pre data-language="undefined"><code>
# /var/log/httpd/error_log
[Wed Sep 24 18:21:20 2014] [notice] caught SIGTERM, shutting down
[Wed Sep 24 18:21:20 2014] [notice] SELinux policy enabled; httpd running as context unconfined_u:system_r:httpd_t:s0
[Wed Sep 24 18:21:20 2014] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Wed Sep 24 18:21:20 2014] [error] *** Passenger could not be initialized because of this error: Unable to start the Phusion Passenger watchdog (/usr/local/lib/ruby/gems/2.1.0/gems/passenger-4.0.52/buildout/agents/PassengerWatchdog): Permission denied (errno=13)
</code></pre><p>I did get this error while configured a new server with CentOS 6.5, Apache and Passenger for an Ruby on Rails application. If your setup looks different, then you may not be able to do exactly like me. I did google allot on `Unable to start the Phusion Passenger watchdog<code> and </code>Permission denied (errno=13)` but without success. I first thought it had something to do with file permissions but it wasn't. The real problem here are SELinux security policy. We do not want to turn this one of because it actually are trying to do good for us. After all it's there for our security.</p><p>We need to know which services that is prevented in order to start passenger and allow only those. To do that we start by setting SELinux into permissive mode. This will allow us to run all application without it being stoped by SELinux use but it will log warnings which we will use to create rule and permit what we need.</p><p>Open <code>/etc/selinux/config</code> and change <code>SELINUX=enforcing</code> to <code>SELINUX=permissive</code>.</p><pre data-language="bash"><code><span class="hljs-comment"># This file controls the state of SELinux on the system.</span>
<span class="hljs-comment"># SELINUX= can take one of these three values:</span>
<span class="hljs-comment"># enforcing - SELinux security policy is enforced.</span>
<span class="hljs-comment"># permissive - SELinux prints warnings instead of enforcing.</span>
<span class="hljs-comment"># disabled - No SELinux policy is loaded.</span>
SELINUX=permissive
<span class="hljs-comment"># SELINUXTYPE= can take one of these two values:</span>
<span class="hljs-comment"># targeted - Only targeted network daemons are protected.</span>
<span class="hljs-comment"># strict - Full SELinux protection.</span>
SELINUXTYPE=targeted
</code></pre><p>Now you need to reboot your server in order for these settings to take action.</p><p>Start the processes needed for your application to run (mysql, redis and so on) and then visit your page in the browser. It should now be working because everything is permitted but will create warnings.</p><p>Now we can create our rules by running the command bellow.</p><pre data-language="bash"><code>grep httpd_t /var/<span class="hljs-built_in">log</span>/audit/audit.log | audit2allow -m httpdrules > httpdrules.te
</code></pre><p>You can now also run <code>cat httpdrules.te</code> and make sure it doesn't contain anything suspicious. If it looks ok then we can make it permanent by running</p><pre data-language="bash"><code><span class="hljs-comment"># notice the capitalized -M instead of -m that we used before</span>
grep httpd_t /var/<span class="hljs-built_in">log</span>/audit/audit.log | audit2allow -M httpdrules
semodule -i httpdrules.pp
</code></pre><p>Next step to se if it all is working is to change <code>permissive</code> back to <code>enforcing</code> in our <code>/etc/selinux/config</code> file and reboot.</p><h2>Q & A</h2><dl>
<dt>It still doesn't work!</dt>
<dd>
If you get an similar error you can look at <a href="http://wiki.centos.org/HowTos/SELinux#head-aa437f65e1c7873cddbafd9e9a73bbf9d102c072">CentOS wiki</a>
how to customize these rules more. Else if you got another error this may just be one of a few errors in your stack. Google is your friend.
<dd>
<dt>How to install <code>audit2allow</code> if it's not available</dt>
<dd>
It comes with <code>policycoreutils-python</code> which is often installed with the system.
If this isn't on your system for any reason it can be installed with <code>yum install policycoreutils-python</code>.
</dd>
<dt>I don't use CentOS but i have the same error, will this work for me?</dt>
<dd>
This guide is written based on my experiences with CentOS, Apache, Passenger and
a Ruby on Rails application i tried to deploy. Some parts in this may still be
useful for you. But you will need to google a bit if your files don't look the same or if
they are not on the same location.
</dd>
<dt>I don't care about security, how to turn of SELinux completly?</dt>
<dd>
This is something you should only do if you not planing to go public with your
application. If this is true then just change your <code>SELINUX</code> option
in <code>/etc/selinux/config</code> to <code>disabled</code> and reboot.
</dd>
</dl>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2014-09-21-input-fields-in-rake-task</guid><title>Input fields in rake task</title><description>Add input data in to running rake task</description><link>https://aross.se/posts/2014-09-21-input-fields-in-rake-task</link><pubDate>Sun, 21 Sep 2014 12:00:00 +0200</pubDate><content:encoded><![CDATA[<h1>Input fields in rake task</h1><p>Rake is an awesome tool to automate workflows during development or for some other stuff.</p><p>But lets say we have a task called <code>customer:add</code> where we want to assign name and email to the new customer. In this case we must be able to interact with our task.</p><p>So we have this rake file as you can se below which just adds an new customer to an YAML file but they all will have the same name and email until we manually changes the file. Lets take a look how we could assign then while running the taks in next section.</p><pre data-language="ruby"><code><span class="hljs-comment"># Rakefile</span>
<span class="hljs-keyword">require</span> <span class="hljs-string">"yaml"</span>
namespace <span class="hljs-symbol">:customer</span> <span class="hljs-keyword">do</span>
task <span class="hljs-symbol">:add</span> <span class="hljs-keyword">do</span>
name = <span class="hljs-string">"Example name"</span>
email = <span class="hljs-string">"Example email"</span>
<span class="hljs-comment"># <span class="hljs-doctag">TODO:</span> Here we need to customize the attributes</span>
storage = <span class="hljs-string">'customers.yml'</span>
yaml = load_yaml_storage(storage)
yaml[<span class="hljs-string">"customers"</span>] <span class="hljs-params">||</span>= [] <span class="hljs-comment"># Make sure the key customer is defined</span>
yaml[<span class="hljs-string">"customers"</span>] << { <span class="hljs-comment"># Adds the new customer</span>
<span class="hljs-symbol">name:</span> name,
<span class="hljs-symbol">email:</span> email
}
File.write(storage, yaml.to_yaml) <span class="hljs-comment"># Saves the file with new data</span>
<span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_yaml_storage</span><span class="hljs-params">(storage)</span></span>
yaml = YAML.load_file(storage) <span class="hljs-comment"># Loads the yaml file</span>
yaml <span class="hljs-keyword">or</span> {}
<span class="hljs-keyword">rescue</span> Errno::ENOENT <span class="hljs-comment"># If the file doesn't exists we return an empty hash</span>
{}
<span class="hljs-keyword">end</span>
</code></pre><h2>Add input fields to our task</h2><p>The example above is an working one so you can copy it and paste it into your favorite editor and play along. To interact with the data before it's written to the file we can use <code>STDIN</code> from ruby.</p><p>Lets try it by starting <code>irb</code> from the terminal and test the code below</p><pre data-language="ruby"><code>value = STDIN.gets
<span class="hljs-comment"># Ruby will now wait for you to write something and press enter, try with Hello, World!</span>
value.inspect
<span class="hljs-comment"># => "Hello, World!\n"</span>
</code></pre><p>As you can se the value will also include an <code>\n</code> which we don't want. This can be removed with</p><pre data-language="ruby"><code>value.chomp
<span class="hljs-comment"># => "Hello, World!"</span>
</code></pre><p>So if we take our new experience from this and add it to the Rakefile it could look something like</p><pre data-language="ruby"><code><span class="hljs-comment"># Rakefile</span>
<span class="hljs-keyword">require</span> <span class="hljs-string">"yaml"</span>
namespace <span class="hljs-symbol">:customer</span> <span class="hljs-keyword">do</span>
task <span class="hljs-symbol">:add</span> <span class="hljs-keyword">do</span>
puts <span class="hljs-string">"What's the customer name?"</span>
name = STDIN.gets.chomp
puts <span class="hljs-string">"And email?"</span>
email = STDIN.gets.chomp
storage = <span class="hljs-string">'customers.yml'</span>
yaml = load_yaml_storage(storage)
yaml[<span class="hljs-string">"customers"</span>] <span class="hljs-params">||</span>= [] <span class="hljs-comment"># Make sure the key customer is defined</span>
yaml[<span class="hljs-string">"customers"</span>] << { <span class="hljs-comment"># Adds the new customer</span>
<span class="hljs-symbol">name:</span> name,
<span class="hljs-symbol">email:</span> email
}
File.write(storage, yaml.to_yaml) <span class="hljs-comment"># Saves the file with new data</span>
<span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_yaml_storage</span><span class="hljs-params">(storage)</span></span>
yaml = YAML.load_file(storage) <span class="hljs-comment"># Loads the yaml file</span>
yaml <span class="hljs-keyword">or</span> {}
<span class="hljs-keyword">rescue</span> Errno::ENOENT <span class="hljs-comment"># If the file doesn't exists we return an empty hash</span>
{}
<span class="hljs-keyword">end</span>
</code></pre><p>It should now be working. Lets try it out by running <code>rake customer:add</code> from your terminal.</p><img src="https://aross.se/images/posts/2014-09-21/result.gif" alt="/img/posts/2014-09-21/result.gif"/><p>Remember, you can add as many customers as you want. <code>STDIN</code> is pure ruby so this example could be applied to other ruby scripts as well.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2014-03-02-working-pow-setup</guid><title>Get pow running with ZSH and Rbenv</title><description></description><link>https://aross.se/posts/2014-03-02-working-pow-setup</link><pubDate>Sun, 2 Mar 2014 12:00:00 +0100</pubDate><content:encoded><![CDATA[<h1>Get pow running with ZSH and Rbenv</h1><p>Usually I'm using <code>rails s</code> with thin or webbrick when developing web applications because I've had lots of issues with pow and file uploads. But when I'm working on multiply projects within same day it's really handy to have pow installed.</p><p><em>Hey wait, what is pow?</em> Pow is according to there own website "a zero-config Rack server for Mac OS X". But it's still needs some configuration... It's really great when working on multiply rack applications. It will boot up the apps you visit in the browser and have support for subdomains so you don't have to mix with your DNS or hosts file. You can read more about pow on there website at <a href="http://pow.cx/">pow.cx</a>.</p><p>In my case the zero-config part did not apply. Whitout any configurations this is what I see. <img src="https://aross.se/images/posts/2014-03-02/bundler-setup.png" alt="LoadError: cannot load such file -- bundler/setup"/></p><p>Pow has a good <a href="https://github.com/basecamp/pow/wiki/Troubleshooting#rbenv">troubleshooting</a> with lots of examples for similar problems.</p><p>Because I'm using both ZSH and Rbenv I listen to there advise and put this content in my <code>~/.powconfig</code>.</p><pre data-language="bash"><code><span class="hljs-built_in">export</span> HOME=/Users/ross
<span class="hljs-built_in">export</span> PATH=<span class="hljs-string">"/usr/local/opt/rbenv/shims:/usr/local/opt/rbenv/bin:<span class="hljs-variable">$PATH</span>"</span>
</code></pre><p>Sadly I still have the exact same result as before.</p><p>I'm also adding <code>eval "$(rbenv init -)"</code> at the bottom of the file which I read in a issue they linked to in the troubleshooting. Now it tells me that I haven't installed the correct ruby version used for this project which I know I have installed.</p><img src="https://aross.se/images/posts/2014-03-02/wrong-ruby-version.png" alt="Error: rbenv: version <code>1.9.3-p327' is not installed</code>"/><p>From here I could guess that it's not finding the correct path to my rbenv. When I run <code>echo $(rbenv root)</code> in my terminal and found out that my root path is</p><p><code>/usr/local/var/rbenv</code>. I'm also know that rbenv uses <code>RBENV_ROOT</code> and `echo $RBENV_ROOT` gives the same path in return. So my problem may be that I have multiply versions of rbenv installed. Next step will be to tell pow to use the same version I'm using in my terminal. Just changing the PATH from</p><p><code>/usr/local/opt/rbenv</code> to <code>/usr/local/var/rbenv</code> didn't work but when I also set</p><p><code>RBENV_ROOT</code> to <code>/usr/local/var/rbenv</code> it did. Yey!!!</p><h2>My <code>~/.powconfig</code> file</h2><pre data-language="bash"><code><span class="hljs-built_in">export</span> HOME=/Users/ross
<span class="hljs-built_in">export</span> RBENV_ROOT=/usr/<span class="hljs-built_in">local</span>/var/rbenv
<span class="hljs-built_in">export</span> PATH=<span class="hljs-variable">$RBENV_ROOT</span>/shims:<span class="hljs-variable">$RBENV_ROOT</span>/bin:<span class="hljs-variable">$PATH</span>
<span class="hljs-built_in">eval</span> <span class="hljs-string">"<span class="hljs-variable">$(rbenv init -)</span>"</span>
</code></pre>]]></content:encoded></item><item><guid isPermaLink="true">https://aross.se/posts/2013-12-23-disable-osx-dashboard</guid><title>Disable OS X Dashboard</title><description>If you are like me and never uses Dashboard on your mac. Why should you still have it there?</description><link>https://aross.se/posts/2013-12-23-disable-osx-dashboard</link><pubDate>Mon, 23 Dec 2013 16:00:00 +0100</pubDate><content:encoded><![CDATA[<h1>Disable OS X Dashboard</h1><p>If you are like me and never uses Dashboard on your mac. Why should you still have it there?</p><p>I found out that it can be killed and disabled.</p><p>First you need to open up your terminal and type:</p><pre data-language="bash"><code>defaults write com.apple.dashboard mcx-disabled -boolean <span class="hljs-literal">true</span>
</code></pre><p>Then you just have to relaunch the dock by typing:</p><pre data-language="bash"><code>killall Dock
</code></pre><p>Now your done!</p><p>Source: <a href="http://www.techradar.com/news/software/operating-systems/20-os-x-mavericks-tips-and-tricks-1190830">Techradar</a></p>]]></content:encoded></item></channel></rss>