<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Thoughts of Software Engineer]]></title><description><![CDATA[I'm a software developer with almost 20 years of experience, eager to share knowledge earned during my journey in programming. Worked as Engineering Manager, St]]></description><link>https://blog.bielawski.tech</link><generator>RSS for Node</generator><lastBuildDate>Thu, 14 May 2026 03:53:18 GMT</lastBuildDate><atom:link href="https://blog.bielawski.tech/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Improve PHP code quality with static analysis]]></title><description><![CDATA[Shortly about static code analyzing

Static code analysis is a method of debugging by examining source code before a program is run. It's done by analyzing a set of code against a set (or multiple sets) of coding rules. Static code analysis and stati...]]></description><link>https://blog.bielawski.tech/improve-php-code-quality-with-static-analysis</link><guid isPermaLink="true">https://blog.bielawski.tech/improve-php-code-quality-with-static-analysis</guid><category><![CDATA[PHP]]></category><category><![CDATA[Programming Tips]]></category><dc:creator><![CDATA[Joseph Bielawski]]></dc:creator><pubDate>Fri, 03 Jun 2022 06:38:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/N135eczYTAs/upload/v1654179506816/Ya65mVbzr.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-shortly-about-static-code-analyzing">Shortly about static code analyzing</h3>
<blockquote>
<p>Static code analysis is a method of debugging by examining source code before a program is run. It's done by analyzing a set of code against a set (or multiple sets) of coding rules. Static code analysis and static analysis are often used interchangeably, along with source code analysis.</p>
</blockquote>
<h3 id="heading-what-is-phpstan">What is PHPStan?</h3>
<p>One of the most popular static analysis tools for the PHP language right now is <a target="_blank" href="https://phpstan.org/">PHPStan</a>:</p>
<blockquote>
<p>PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code can be checked before you run the actual line.</p>
</blockquote>
<h3 id="heading-find-a-problem-and-propose-a-solution">Find a problem and propose a solution</h3>
<h4 id="heading-why-you-should-be-worried-about-catching-the-throwable-exception">Why you should be worried about catching the <code>\Throwable</code> exception?</h4>
<p>Lets start with a code example:</p>
<pre><code class="lang-php"><span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// do whatever you want</span>
} <span class="hljs-keyword">catch</span> (\<span class="hljs-built_in">Throwable</span> $e) {
    <span class="hljs-comment">// hide everything, even PHP errors</span>
}
</code></pre>
<p>This is dangerous, due to the usage of the top-level exception interface <a target="_blank" href="https://www.php.net/manual/en/class.throwable.php"><code>\Throwable</code></a>, which means that every other exception must implement this interface. PHP fatal errors, built-in and user-land exceptions will be caught in such cases. This is dangerous as it increases the maintenance cost, and potentially hides code issues from developers.</p>
<h4 id="heading-phpstan-for-a-rescue">PHPStan for a rescue!</h4>
<p>PHPStan's core concepts are:</p>
<ul>
<li>Abstract Syntax Tree,</li>
<li>Scope,</li>
<li>Type System,</li>
<li>Trinary Logic,</li>
<li>Reflection,</li>
<li>Dependency Injection &amp; Configuration.</li>
</ul>
<p>I will not get into all details in this article, as our custom rule will base just on the AST:</p>
<blockquote>
<p><a target="_blank" href="https://phpstan.org/developing-extensions/abstract-syntax-tree">Abstract Syntax Tree (AST)</a> is the way analyzed source code is represented in the static analyzer so that it can be queried for useful information.</p>
</blockquote>
<p>For more information about the PHPStan core concept, I recommend reading an <a target="_blank" href="https://phpstan.org/developing-extensions/core-concepts">official documentation</a>.</p>
<h4 id="heading-new-custom-rule-to-prevent-catching-throwable-interface">New custom rule to prevent catching <code>\Throwable</code> interface</h4>
<p>Writing custom rules for PHPStan will allow it to detect this bug-prone code part and force developers to write it in a better way, with more <em>bullet-proof</em> code.</p>
<p>First let's create a new class: <code>DisallowCatchingThrowableExceptionRule</code>, we need also to implement <code>PHPStan\Rules\Rule</code> interface:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span> <span class="hljs-keyword">declare</span>(strict_types=<span class="hljs-number">1</span>);

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">PhpParser</span>\<span class="hljs-title">Node</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">PHPStan</span>\<span class="hljs-title">Analyser</span>\<span class="hljs-title">Scope</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">PHPStan</span>\<span class="hljs-title">Rules</span>\<span class="hljs-title">Rule</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DisallowCatchingThrowableExceptionRule</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Rule</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getNodeType</span>(<span class="hljs-params"></span>): <span class="hljs-title">string</span>
    </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>;
    }

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@return</span> string[]
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processNode</span>(<span class="hljs-params">Node $node, Scope $scope</span>): <span class="hljs-title">array</span>
    </span>{
         <span class="hljs-keyword">return</span> [];
    }
}
</code></pre>
<p>Our new rule will work on the PHPParser statements classes, and in fact, it will be two of those:</p>
<ul>
<li><code>PhpParser\Node\Stmt\TryCatch</code>, related to <code>try {} catch () {}</code> code fragment,</li>
<li><code>PhpParser\Node\Stmt\Catch_</code>, related to <code>catch ()</code> code fragment.</li>
</ul>
<p>We now also need to change the value of the <code>getNodeType()</code> method, to point PHP parser that we will work on statement level. </p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span> <span class="hljs-keyword">declare</span>(strict_types=<span class="hljs-number">1</span>);

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">PhpParser</span>\<span class="hljs-title">Node</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">PhpParser</span>\<span class="hljs-title">Node</span>\<span class="hljs-title">Stmt</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">PHPStan</span>\<span class="hljs-title">Analyser</span>\<span class="hljs-title">Scope</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">PHPStan</span>\<span class="hljs-title">Rules</span>\<span class="hljs-title">Rule</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DisallowCatchingThrowableExceptionRule</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Rule</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getNodeType</span>(<span class="hljs-params"></span>): <span class="hljs-title">string</span>
    </span>{
        <span class="hljs-keyword">return</span> Stmt::class;
    }

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@return</span> string[]
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processNode</span>(<span class="hljs-params">Node $node, Scope $scope</span>): <span class="hljs-title">array</span>
    </span>{
        <span class="hljs-keyword">if</span> ($node <span class="hljs-keyword">instanceof</span> Stmt\TryCatch) {
            <span class="hljs-keyword">return</span> [];
        }

        <span class="hljs-keyword">return</span> [];
    }
}
</code></pre>
<p>When you inspect the object of <code>Stmt\TryCatch</code>, you will notice it contains the <code>$catches</code> variable, which is an array of nodes: <code>Stmt\Catch_</code>. Now we can check what class name was used in it and compare it against the name of the <code>\Throwable</code> interface!</p>
<pre><code class="lang-php">    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@return</span> string[]
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processNode</span>(<span class="hljs-params">Node $node, Scope $scope</span>): <span class="hljs-title">array</span>
    </span>{
        <span class="hljs-keyword">if</span> ($node <span class="hljs-keyword">instanceof</span> Stmt\TryCatch) {
            <span class="hljs-keyword">foreach</span> ($node-&gt;catches <span class="hljs-keyword">as</span> $catch) {
                <span class="hljs-keyword">foreach</span> ($catch-&gt;types <span class="hljs-keyword">as</span> $type) {
                    <span class="hljs-comment">// To compare object against string value, we need to cast it back to string,</span>
                    <span class="hljs-comment">// we can use toString() helper method for that.</span>
                    <span class="hljs-keyword">if</span> (\<span class="hljs-built_in">Throwable</span>::class !== $type-&gt;toString()) {
                        <span class="hljs-keyword">continue</span>;
                    }
                }
            }

            <span class="hljs-keyword">return</span> [];
        }

        <span class="hljs-keyword">return</span> [];
    }
</code></pre>
<p>Now we need to mark that <code>try {} catch () {}</code> statement as <em>broken</em>. To do that we should add a custom attribute on the <code>$catch</code> that was a match against the <code>\Throwable</code> interface:</p>
<pre><code class="lang-php">    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@return</span> string[]
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processNode</span>(<span class="hljs-params">Node $node, Scope $scope</span>): <span class="hljs-title">array</span>
    </span>{
        <span class="hljs-keyword">if</span> ($node <span class="hljs-keyword">instanceof</span> Stmt\TryCatch) {
            <span class="hljs-keyword">foreach</span> ($node-&gt;catches <span class="hljs-keyword">as</span> $catch) {
                <span class="hljs-keyword">foreach</span> ($catch-&gt;types <span class="hljs-keyword">as</span> $type) {
                    <span class="hljs-keyword">if</span> (\<span class="hljs-built_in">Throwable</span>::class !== $type-&gt;toString()) {
                        <span class="hljs-keyword">continue</span>;
                    }

                    <span class="hljs-comment">// Name of the attribute should be unique one to prevent issues with other PHPStan rules</span>
                    $catch-&gt;setAttribute(<span class="hljs-string">'__THROWABLE_NODE_ATTRIBUTE__'</span>, <span class="hljs-string">'You cannot catch the \Throwable exception'</span>);

                    <span class="hljs-comment">// We already found a "broken" catch, no need for further checks</span>
                    <span class="hljs-keyword">break</span> <span class="hljs-number">2</span>;
                }
            }

            <span class="hljs-keyword">return</span> [];
        }

        <span class="hljs-keyword">return</span> [];
    }
</code></pre>
<p>We have marked the <em>broken</em> part of the code, but it's not yet reported by PHPStan. To do that, we need to check if any processed node contains our newly set attribute and if so return an array of errors.</p>
<pre><code class="lang-php">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> THROWABLE_NODE_ATTRIBUTE = <span class="hljs-string">'__THROWABLE_NODE_ATTRIBUTE__'</span>;

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@return</span> string[]
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processNode</span>(<span class="hljs-params">Node $node, Scope $scope</span>): <span class="hljs-title">array</span>
    </span>{
        <span class="hljs-keyword">if</span> ($node <span class="hljs-keyword">instanceof</span> Stmt\TryCatch) {
            <span class="hljs-keyword">foreach</span> ($node-&gt;catches <span class="hljs-keyword">as</span> $catch) {
                <span class="hljs-keyword">foreach</span> ($catch-&gt;types <span class="hljs-keyword">as</span> $type) {
                    <span class="hljs-keyword">if</span> (\<span class="hljs-built_in">Throwable</span>::class !== $type-&gt;toString()) {
                        <span class="hljs-keyword">continue</span>;
                    }

                    $catch-&gt;setAttribute(<span class="hljs-built_in">self</span>::THROWABLE_NODE_ATTRIBUTE, <span class="hljs-string">'You cannot catch the \Throwable exception'</span>);

                    <span class="hljs-keyword">break</span> <span class="hljs-number">2</span>;
                }
            }

            <span class="hljs-keyword">return</span> [];
        }

        <span class="hljs-keyword">if</span> ($node <span class="hljs-keyword">instanceof</span> Stmt\Catch_ &amp;&amp; $node-&gt;hasAttribute(<span class="hljs-built_in">self</span>::THROWABLE_NODE_ATTRIBUTE)) {
            <span class="hljs-keyword">return</span> [$node-&gt;getAttribute(<span class="hljs-built_in">self</span>::THROWABLE_NODE_ATTRIBUTE)];
        }

        <span class="hljs-keyword">return</span> [];
    }
</code></pre>
<p>Last but not least, you need to declare the newly created rule in your <code>phpstan.neon</code> file:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">rules:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">App\DisallowCatchingThrowableExceptionRule</span>
</code></pre>
<p>If everything goes well, on the next usage of PHPStan you will notice a new error reported if your code contains: <code>catch (\Throwable $e)</code>:</p>
<pre><code class="lang-bash">$ vendor/bin/phpstan analyse some_file.php
Note: Using configuration file /srv/phpstan.neon.
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ ----------------------------------------------------------
  Line   some_file.php
 ------ ----------------------------------------------------------
  666    You cannot catch the \Throwable exception
 ------ ----------------------------------------------------------
</code></pre>
<h3 id="heading-summary">Summary</h3>
<p>From this article, you could learn the basics of static analysis in the PHP language and how you could start writing your own custom rules for PHPStan. For more details, I highly recommend reading official PHPStan documentation about <a target="_blank" href="https://phpstan.org/developing-extensions/rules">custom rules development</a>.</p>
<h4 id="heading-ready-to-use-class-as-a-gist">Ready to use class as a gist:</h4>
<p>Easy to copy version of this rule can be found <a target="_blank" href="https://gist.github.com/stloyd/8a2f6fa3612c141fee8f75e1f6fef2e5">in this gist</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Not Invented Here: history repeating]]></title><description><![CDATA[Hold my beer, I can do it on my own!
NIH (Not Invented Here) syndrome is often considered an opportunity to prove to ourselves that we can do the same thing, but better, faster, nicer, and more secure than the original.
According to Wikipedia, we can...]]></description><link>https://blog.bielawski.tech/not-invented-here-history-repeating</link><guid isPermaLink="true">https://blog.bielawski.tech/not-invented-here-history-repeating</guid><category><![CDATA[management]]></category><category><![CDATA[technology]]></category><category><![CDATA[development]]></category><category><![CDATA[team]]></category><dc:creator><![CDATA[Joseph Bielawski]]></dc:creator><pubDate>Fri, 08 Apr 2022 08:41:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/gPRvTP0sZ2M/upload/v1649406193653/8iWoKZoDh.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-hold-my-beer-i-can-do-it-on-my-own">Hold my beer, I can do it on my own!</h3>
<p>NIH (Not Invented Here) syndrome is often considered an opportunity to prove to ourselves that we can do the same thing, but better, faster, nicer, and more secure than the original.
According to <a target="_blank" href="https://en.wikipedia.org/wiki/Not_invented_here">Wikipedia</a>, we can summarize NIH syndrome as:</p>
<blockquote>
<p>Not invented here (NIH) is the tendency to avoid using or buying products, research, standards, or knowledge from external origins. It is usually adopted by social, corporate, or institutional cultures. Research illustrates a strong bias against ideas from the outside.</p>
</blockquote>
<p>Sometimes NIH is considered a shortcut of NIHS (Not invented here syndrome).</p>
<h3 id="heading-buy-vs-build-the-management-problems">Buy vs build - the management problems</h3>
<p>When deciding to either buy software or build it in-house, staff management must take care to not follow NIH syndrome. While it may not be obvious when looking from the perspective of staff and chief level management, <strong>NIHS</strong> is quite a big part of the build decision. Developers may want to prove that they can do the job well. </p>
<p>NIHS can lead to not only expensive, time-consuming tasks, but may require managing hidden costs like maintenance. Other hidden risks from build decisions that may show up in the future are <a target="_blank" href="https://blog.bielawski.tech/what-happens-if-your-development-team-is-hit-by-a-bus">Bus Factor</a> and <strong>Technical Debt</strong>.</p>
<h3 id="heading-pay-vs-create-persons-dilemma">Pay vs create - person’s dilemma</h3>
<p>Similar to staff+ management decisions problems about what to do (buy vs build), people also often reach a dilemma: pay someone else or do something on their own. That dilemma is not only limited to software development but also to research, standards, or knowledge that others may provide for a price. In software development, this problem is more visible, because programmers love to prove themselves.</p>
<p>The time spent on developing, improving, or maintaining the created software is not usually taken into account when validating the price someone else asks us to pay for getting something ready to use.</p>
<h3 id="heading-not-invented-here-andlt-reinventing-the-wheel">Not invented here &lt; reinventing the wheel</h3>
<p>The syndrome is often considered an alias for <strong>reinventing the wheel</strong>. Those two terms differ in many layers. The meaning of the first is threatened in a pejorative sense, while the second is more in an ameliorative sense.</p>
<p>As an example of NIH syndrome: developers create a new internal framework for the company, instead of grabbing the existing and well-tested solution available on the market.</p>
<p>Reinventing the wheel led the PHP community to create the Composer package manager, the JavaScript community created NPM, and later Yarn. A lot of awesome projects started by reinventing some tools from one community into another. The same goes for programming languages which adopt features from different languages to evolve.</p>
<p>Consider reinventing the wheel a positive version of NIH syndrome.</p>
<h3 id="heading-should-i-be-scared-of-nih-syndrome">Should I be scared of NIH syndrome?</h3>
<p>In the PHP community we usually say:</p>
<blockquote>
<p>Every programmer must write, at least once in a life, his/her framework</p>
</blockquote>
<p>While the tone is sarcastic, it also highlights an opportunity to learn something new, prove ourselves, and give back knowledge to the community. While being unaware of failing into that syndrome may be dangerous and lead to other problems like <a target="_blank" href="https://blog.bielawski.tech/what-happens-if-your-development-team-is-hit-by-a-bus">low Bus Factor scores</a> and high Technical Debt, being aware of possible problems and issues allows us to follow <em>reinventing the wheel</em>.</p>
<p>Now you know the basics about what NIH syndrome is and how it can affect you, your team, or even the whole company. While it may lead to improving your skills, knowledge, and experience, it may cause you other problems if you’re not careful to avoid its trap.</p>
<hr />
<p>If you want to learn more about the <a target="_blank" href="https://tech.bielawski.com/what-happens-if-your-development-team-is-hit-by-a-bus">Bus Factor</a>, check out this article:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://stloyd.hashnode.dev/what-happens-if-your-development-team-is-hit-by-a-bus">https://stloyd.hashnode.dev/what-happens-if-your-development-team-is-hit-by-a-bus</a></div>
]]></content:encoded></item><item><title><![CDATA[What happens if your development team is hit by a bus?]]></title><description><![CDATA[A little bit of history
While the title may sound quite extreme, a similar sentence was asked publicly by Michael McLay in 1994:

If Guido was hit by a bus? (Guido van Rossum is the creator of the Python language)

That question led to the creation o...]]></description><link>https://blog.bielawski.tech/what-happens-if-your-development-team-is-hit-by-a-bus</link><guid isPermaLink="true">https://blog.bielawski.tech/what-happens-if-your-development-team-is-hit-by-a-bus</guid><category><![CDATA[management]]></category><category><![CDATA[developers]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[team]]></category><dc:creator><![CDATA[Joseph Bielawski]]></dc:creator><pubDate>Fri, 25 Mar 2022 12:10:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/5g4Zr0qFMWI/upload/v1648048781064/es5z1R6kCz.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-a-little-bit-of-history">A little bit of history</h3>
<p>While the title may sound quite extreme, a similar sentence was asked publicly by <a target="_blank" href="https://en.wikipedia.org/wiki/Bus_factor#History">Michael McLay in 1994</a>:</p>
<blockquote>
<p>If Guido was hit by a bus? (<a target="_blank" href="https://en.wikipedia.org/wiki/Guido_van_Rossum">Guido van Rossum</a> is the creator of the Python language)</p>
</blockquote>
<p>That question led to the creation of the <strong>Bus Factor</strong>, known also as <em>bus problem,</em> <em>truck factor</em>, <em>lorry factor</em>, or even <em>lottery factor</em>.</p>
<h3 id="heading-what-is-a-bus-factor">What is a “Bus Factor”?</h3>
<p>While there are several slightly different definitions on the Web, we may summarize them as:</p>
<blockquote>
<p>The Bus Factor is the total number of people who would need to be incapacitated, as by getting hit by a bus so that the project would be left for dead.</p>
</blockquote>
<p>To make this more descriptive, the <strong>Bus Factor score</strong> is an estimation of people who are so vital to your project that without them it will stall. If those people disappeared from the project for any reason (like an "accident" or even taking holiday, got fired, or left the project), no one would be able to maintain the project. </p>
<p>The lowest possible Bus Factor score is just 1, which means that if one person leaves the project it will stall or die. From a more technical point of view, this could be considered a <a target="_blank" href="https://en.wikipedia.org/wiki/Single_point_of_failure">single point of failure</a> within the project. A much larger Bus Factor score is preferable, but not always easy to achieve.</p>
<p><a target="_blank" href="https://xkcd.com/2347/"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1648058583185/nQ5vla14K.png" alt="https://xkcd.com/2347/" class="image--center mx-auto" />
Author: https://xkcd.com/2347/</a></p>
<h3 id="heading-php-community-problem">PHP Community problem</h3>
<p>At end of 2021, the PHP community received the sad information that after 10 years of implementing innumerable bug fixes, features &amp; maintaining PHP, one of the main contributors: <strong>Nikita Popov</strong>, decided to focus on working in a completely different language and community (Rust &amp; LLVM), of which he had already been apart for a few years.</p>
<p>Similar to the history of the Python language, that decision showed the PHP language has a really big problem with such a low Bus Factor score. It put the future of the language that powers up ~78% of the Web in a dangerous position.</p>
<p>To improve the current state, people and companies working on PHP joined forces and started a new initiative: <a target="_blank" href="https://opencollective.com/phpfoundation">PHP Foundation</a>.</p>
<blockquote>
<p>The <strong>PHP Foundation</strong> is a non-profit organization whose mission is to ensure the long life and prosperity of the PHP language.</p>
</blockquote>
<p>The first decision made by the foundation was to hire/sponsor new developers to work on PHP core components. That way they could start increasing the Bus Factor score to a safer level. This is one of many steps that need to be taken by the community to make PHP's future safe and stable.</p>
<h3 id="heading-company-problems">Company problems</h3>
<p>Plenty of companies I worked for, from startups to corporations, often were hit hard by the Bus Factor. Many of their teams (most of the time not intentionally) fell into <a target="_blank" href="https://blog.bielawski.tech/not-invented-here-history-repeating">NIH (Not Invented Here)</a>, which led to problems with maintenance, higher entry-level for newcomers, as more &amp; more things were created by people who could leave the project at any moment. This has often led to high Technical Debt (which I will try to explain in a later post).</p>
<p>A <strong>low Bus Factor score</strong> is often part of the fast-growing time when only a few developers create most of the functionality that later becomes the base for an increasingly complex project. Most companies start big hiring plans during such growth, but that's not something that can increase the Bus Factor alone.</p>
<h3 id="heading-how-to-increase-a-low-bus-factor-score">How to increase a low Bus Factor score?</h3>
<h4 id="heading-coaching-sessions-andamp-pair-programming">Coaching sessions &amp; pair programming</h4>
<p>Each new member should have at least 30 minutes of a pair programming session with one of the <em>senior</em> people within the project she/he is joining. During such sessions, a less experienced person should do most of the coding, while the senior mentors, leads by example and suggests parts that may help to achieve the goal of the task.</p>
<h4 id="heading-your-bus-factor-person-as-a-teacher">Your Bus Factor person as a teacher</h4>
<p>When you identify <em>Bus Factor people</em>, you should focus on how they can share the knowledge they aggregated during all those years in your project. Their knowledge is one of the biggest values for your team. Have them focus more on writing documentation, creating cheatsheets, doing internal presentations, and sharing knowledge in one-on-one sessions with teammates. Their focus on programming should be <em>reduced</em>.</p>
<h4 id="heading-code-review-culture">Code Review Culture</h4>
<p>While adoption of the Code Review Culture is done by teams to improve the code quality and the review process, the less obvious outcome is direct knowledge sharing between people in the project. Reviews must not be just like giving a stamp of approval. They should point out why something was done that way, not another, leading to constructive discussions between seniors &amp; other teammates about what could be done differently, from the perspective of seniors. Reviews must lead to discussion.</p>
<h4 id="heading-reducing-projects-complexity">Reducing project(s) complexity</h4>
<p>Often the problem of fast-growing companies is fast-growing Technical Debt, which leads to a low Bus Factor score. One of the effective techniques is reducing the complexity of projects by splitting them into smaller, more dedicated ones. This leads to lower entry-level, faster adoption, and easier maintenance. All these points allow increasing the overall Bus Factor quite effectively. The biggest issue you must avoid during reducing the complexity of projects is to always involve teams (even small ones) in refactoring to avoid creating the very same problem in the new <em>sub-project(s)</em>.</p>
<h4 id="heading-team-shuffling">Team "shuffling"</h4>
<p>This can be the most effective way of increasing the Bus Factor score, but it's also the most difficult and dangerous one. You need to deeply plan every possibility to prevent losing team morale. "Shuffling" should not be forced, but proposed to team members on a regular basis, like: once every two quarters; teammates cannot change teams too often as they will need to be onboarded like a newcomer. If well planned &amp; executed, your teams will get much wider experience in different domains, sharing the knowledge learned while working with other teams.</p>
<h4 id="heading-training-budget">Training budget</h4>
<p>Planning training budgets for your developers can also increase the Bus Factor score as people will gather a wider range of experience, and expand your team to have more people in each seniority rank within your company hierarchy.</p>
<h3 id="heading-summary">Summary</h3>
<p>It’s not that easy, cheap, or quick to increase your team Bus Factor score. There are cases when you don't want (or even can't) easily increase that score, for example when the project contains sensitive data and you can't trust your new hires to start handling it. But now you know some of the basics that can help you prevent having your operations grind to a halt due to a "bus accident".</p>
]]></content:encoded></item><item><title><![CDATA[The Phoenix Project - Short Book Review]]></title><description><![CDATA[Recently I have read a book: The Phoenix Project by Kevin Behr, Gene Kim and George Spafford; 
About what the book is?
It's a business novel, where fiction is used to point the reader to some of the business values, but unfortunately in my opinion it...]]></description><link>https://blog.bielawski.tech/the-phoenix-project-short-book-review</link><guid isPermaLink="true">https://blog.bielawski.tech/the-phoenix-project-short-book-review</guid><category><![CDATA[review]]></category><category><![CDATA[books]]></category><category><![CDATA[management]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Joseph Bielawski]]></dc:creator><pubDate>Tue, 22 Mar 2022 16:28:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1648310958212/McuG1v9F_.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Recently I have read a book: <strong>The Phoenix Project</strong> by Kevin Behr, Gene Kim and George Spafford; </p>
<h3 id="heading-about-what-the-book-is">About what the book is?</h3>
<p>It's a business novel, where fiction is used to point the reader to some of the business values, but unfortunately in my opinion it makes reading a bit harder. The story is about a newly promoted IT manager who struggles to learn how to evolve outdated approaches in a <em>big company</em>, starting from "nothing" with plenty of legacy projects to handle, into a full <strong>DevOps</strong> based approach, with <strong>agile</strong> &amp; <strong>lean management</strong> technics.</p>
<h3 id="heading-from-that-book-you-will-learn-about">From that book <strong>you will learn</strong> about:</h3>
<ul>
<li>basics about Technical Debt,</li>
<li>how unproductive meetings make morale lower,</li>
<li>how "unexpected requests" can affect the work of everyone in the company,</li>
<li>how a "small fix" on a production server can lead to a P1 issue for the whole weekend,</li>
<li>that you probably know a person like one of the heroes of that story: Brent,</li>
<li>how <a target="_blank" href="https://tech.bielawski.com/what-happens-if-your-development-team-is-hit-by-a-bus"><strong>Bus Factor</strong></a> can stop all the work of the IT department,</li>
</ul>
<h3 id="heading-for-whom-i-would-recommend-it-for-sure">For whom I would recommend it? For sure:</h3>
<ul>
<li>everyone who starts her/his journey with IT,</li>
<li>every developer or anyone else aspiring to become a Product Manager or Engineering Manager,</li>
<li>programers or DevOps will find a lot of "memories" (<em>good</em> and <em>bad</em> as well) in that novel.</li>
</ul>
<hr />
<p>If you are interested to read more about <a target="_blank" href="https://tech.bielawski.com/what-happens-if-your-development-team-is-hit-by-a-bus">Bus Factor</a>, please check out this article:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://stloyd.hashnode.dev/what-happens-if-your-development-team-is-hit-by-a-bus">https://stloyd.hashnode.dev/what-happens-if-your-development-team-is-hit-by-a-bus</a></div>
]]></content:encoded></item></channel></rss>