<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pedro Marques</title>
    <description>The latest articles on DEV Community by Pedro Marques (@pitermarx).</description>
    <link>https://dev.to/pitermarx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F83323%2Fe9758fef-7768-4df7-a53f-c36b62223915.jpeg</url>
      <title>DEV Community: Pedro Marques</title>
      <link>https://dev.to/pitermarx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pitermarx"/>
    <language>en</language>
    <item>
      <title>Software is art</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Mon, 30 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/pitermarx/software-is-art-3233</link>
      <guid>https://dev.to/pitermarx/software-is-art-3233</guid>
      <description>&lt;p&gt;My workstation at my job is not a local computer. Its a remote virtual machine that I connect to through the internet.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Preach GPT!</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Sun, 30 Jun 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/pitermarx/preach-gpt-2m13</link>
      <guid>https://dev.to/pitermarx/preach-gpt-2m13</guid>
      <description>&lt;p&gt;I really can’t do web design. I’m terrible at it. My aesthetic sense is similar to that of a color-blind guinea pig.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Broken Windows</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Thu, 13 Jun 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/pitermarx/broken-windows-39h7</link>
      <guid>https://dev.to/pitermarx/broken-windows-39h7</guid>
      <description>&lt;p&gt;In criminology, the broken windows theory states that visible signs of crime, antisocial behavior and civil disorder create an urban environment that encourages further crime and disorder, including serious crimes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Free dotnet hosting! Or... having fun with dotnet</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Fri, 19 Apr 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/pitermarx/free-dotnet-hosting-or-having-fun-with-dotnet-4p9m</link>
      <guid>https://dev.to/pitermarx/free-dotnet-hosting-or-having-fun-with-dotnet-4p9m</guid>
      <description>&lt;p&gt;I’ve been wanting to test the new features of dotnet, and language syntax, and also to learn more about observability and specifically OpenTelemetry.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Feedback Loops</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Wed, 04 Oct 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/pitermarx/feedback-loops-1mnj</link>
      <guid>https://dev.to/pitermarx/feedback-loops-1mnj</guid>
      <description>&lt;p&gt;I’ve been thinking recently about feedback loops. In control theory, one way to manage dynamic systems is via feedback loops.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>New dotnet tool: SqlServerCoverage</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Thu, 10 Nov 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/pitermarx/new-dotnet-tool-sqlservercoverage-48ej</link>
      <guid>https://dev.to/pitermarx/new-dotnet-tool-sqlservercoverage-48ej</guid>
      <description>&lt;p&gt;I've developed a tool inspired by the work of &lt;a href="https://github.com/GoEddie/SQLCover" rel="noopener noreferrer"&gt;GoEddie&lt;/a&gt; that can collect and report coverage data of SQL code on a SQLServer database.&lt;br&gt;
I've called it - not very creatively - &lt;a href="https://github.com/pitermarx/SqlServerCoverage" rel="noopener noreferrer"&gt;SqlServerCoverage&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install dotnet tool:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sqlservercoverage.commandline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Start coverage session:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$cnx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Collect coverage:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;collect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$cnx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--summary&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Cleanup:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$cnx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Details
&lt;/h2&gt;

&lt;p&gt;This tool allows us to know how much of the stored procedures are covered by some action&lt;/p&gt;

&lt;p&gt;It uses &lt;a href="https://docs.microsoft.com/en-us/sql/relational-databases/extended-events/extended-events" rel="noopener noreferrer"&gt;XEvents&lt;/a&gt; on sql server to track which statements were used in the time a trace session was open.&lt;br&gt;
Unfortunately Views, Scalar functions and inlined table functions are not trackable via this mecanism. Only Stored procedures, Triggers and Table Valued functions are tracked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Data Source=.\SQLEXPRESS;Integrated Security=True"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DatabaseName"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# start a session and get the ID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$LASTEXITCODE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-ne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# returns a list of session IDs on the server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# now do some stuff on the database&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# collect coverage data.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# export an html report, an opencover report, a sonar report and a console summary&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$outputDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"somewhere"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;collect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;--html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--opencover&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--sonar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--summary&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$outputDirectory&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# manual cleanup is necessary to stop the XEvents session&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# you can do this&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# or stop all sessions on the server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stop-all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# or stop all sessions if the corresponding db does not exist anymore&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;sql-coverage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stop-all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--connection-string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--only-missing-dbs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a sample summary from the console and attached is a sample HTML report&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wu63po3kl004qh1lscr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wu63po3kl004qh1lscr.png" alt="Image description" width="800" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a screenshot of the terminal summary, created with &lt;a href="https://spectreconsole.net/" rel="noopener noreferrer"&gt;Spectre.Console&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7szz5zttkuxqcoa5s2ds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7szz5zttkuxqcoa5s2ds.png" alt="Image description" width="800" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The OpenCover xml report also exports the source objects that can then be used by &lt;a href="https://danielpalme.github.io/ReportGenerator/" rel="noopener noreferrer"&gt;ReportGenerator&lt;/a&gt; to generate a report&lt;/p&gt;

&lt;p&gt;It can also export on the &lt;a href="https://docs.sonarqube.org/latest/analysis/generic-test/" rel="noopener noreferrer"&gt;sonar generic coverage&lt;/a&gt; format&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>sql</category>
      <category>coverage</category>
    </item>
    <item>
      <title>How to respond to recruiters</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Tue, 17 May 2022 11:25:29 +0000</pubDate>
      <link>https://dev.to/pitermarx/how-to-respond-to-recruiters-3ofl</link>
      <guid>https://dev.to/pitermarx/how-to-respond-to-recruiters-3ofl</guid>
      <description>&lt;p&gt;Hello [name]&lt;/p&gt;

&lt;p&gt;Thanks so much for reaching out. I’m always interested in hearing about what new and exciting opportunities are out there.&lt;/p&gt;

&lt;p&gt;As a software engineer with over [number] years of experience I’m sure you can imagine that I get a very high volume of recruiters reaching out on LinkedIn. It is a wonderful position of privilege to be in and I’m thankful for it.&lt;/p&gt;

&lt;p&gt;It does however mean that I don’t have the time to hop on a call with everyone who reaches out. A lot of the times, incoming messages represent a very poor fit indeed.&lt;/p&gt;

&lt;p&gt;I would love to continue the conversation, but before I do, I’d like to level set around the level of seniority that you’re looking for.&lt;/p&gt;

&lt;p&gt;Can you send along the company/project name, role description and the total compensation details for the role you’re reaching out in reference to?&lt;/p&gt;

&lt;p&gt;I look forward to hearing from you.&lt;/p&gt;

&lt;p&gt;Pedro&lt;/p&gt;

</description>
      <category>original</category>
      <category>shorts</category>
      <category>dev</category>
    </item>
    <item>
      <title>Why delete code?</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Mon, 07 Feb 2022 16:54:21 +0000</pubDate>
      <link>https://dev.to/pitermarx/why-delete-code-3i2p</link>
      <guid>https://dev.to/pitermarx/why-delete-code-3i2p</guid>
      <description>&lt;p&gt;While it may be necessary to use code to build value on software projects, there are many not so great things that increase the more code we have. Let’s make the &lt;strong&gt;10 commandments of&lt;/strong&gt; &lt;em&gt;&lt;strong&gt;No Code &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--McnUPhsE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s.w.org/images/core/emoji/13.1.0/72x72/2122.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--McnUPhsE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s.w.org/images/core/emoji/13.1.0/72x72/2122.png" alt="™" width="72" height="72"&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; has no bugs&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; has no technical debt&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; has no cognitive load on developers&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; builds in no time&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; does checkout in no time&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; makes our tooling faster&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; has 100% code coverage&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; is easier to read than some code&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; scales infinitely&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;No Code&lt;/em&gt; is no one’s problem&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the impossibility to write &lt;em&gt;No Code &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--McnUPhsE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s.w.org/images/core/emoji/13.1.0/72x72/2122.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--McnUPhsE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s.w.org/images/core/emoji/13.1.0/72x72/2122.png" alt="™" width="72" height="72"&gt;&lt;/a&gt;,&lt;/em&gt; let’s simply write less code.&lt;br&gt;&lt;br&gt;
Let’s only write the minimum code necessary.&lt;br&gt;&lt;br&gt;
Let’s delete all unnecessary or unused code! (while keeping all functionality)&lt;/p&gt;

</description>
      <category>original</category>
      <category>shorts</category>
      <category>dev</category>
    </item>
    <item>
      <title>Cake.Console 1.2.0</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Thu, 09 Sep 2021 16:07:30 +0000</pubDate>
      <link>https://dev.to/pitermarx/cakeconsole-120-3bdi</link>
      <guid>https://dev.to/pitermarx/cakeconsole-120-3bdi</guid>
      <description>&lt;p&gt;After a bit of work, I have found Cake.&lt;a href="https://blog.pitermarx.com/2021/09/presenting-cake-console/"&gt;Console&lt;/a&gt; stable enough for a&lt;a href="https://www.nuget.org/packages/Cake.Console/"&gt;first release&lt;/a&gt;. I decided to version it with the same number as Cake itself. If needed I will update the revision number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Create a new project referencing Cake.Console. It will look something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Project Sdk="Microsoft.NET.Sdk"&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net5.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;OutputType&amp;gt;exe&amp;lt;/OutputType&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include="Cake.Console" Version="1.2.0" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a single Program.cs file with the code. Take advantage of &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements"&gt;top-level statements&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are 2 ways of using Cake.Console:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Building an IScriptHost. This is the implicit object in the .cake scripts, so we can use it to register tasks, perform setup, etc.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var host = new CakeHostBuilder().BuildHost(args);

host.Setup(() =&amp;gt; { do something });
host.Task("TaskName").Does(c =&amp;gt; c.Information("Hello"));
host.RunTarget(host.Context.Arguments.GetArgument("target"));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Using the Cake Cli, that includes arguments like –target, –version, –info, –tree, –description, –exclusive…
It’s very similar to &lt;a href="https://cakebuild.net/docs/running-builds/runners/cake-frosting"&gt;frosting&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new CakeHostBuilder()
    .WorkingDirectory&amp;lt;WorkingDirectory&amp;gt;()
    .ContextData&amp;lt;BuildData&amp;gt;()
    .RegisterTasks&amp;lt;CakeTasks&amp;gt;()
    .InstallNugetTool("NuGet.CommandLine", "5.9.1")
    .RunCakeCli(args);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we dont have access to the host, so we need to define the build with the 4 extensions that come with Cake.Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WorkingDirectory&amp;lt;&amp;gt;&lt;/li&gt;
&lt;li&gt;RegisterTasks&amp;lt;&amp;gt;&lt;/li&gt;
&lt;li&gt;ContextData&amp;lt;&amp;gt;&lt;/li&gt;
&lt;li&gt;InstallNugetTool&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  WorkingDirectory&amp;lt;&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Here we can use a class that has the interface IWorkingDirectory and implements the string WorkingDirectory property.&lt;/p&gt;

&lt;p&gt;The class can receive in the constructor any part of the cake infrastructure (ICakeContext, ICakeLog, ICakeArguments, ICakeConfiguration…)&lt;/p&gt;

&lt;h2&gt;
  
  
  RegisterTasks&amp;lt;&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Here we can use a class that has the interface ICakeTasks.&lt;/p&gt;

&lt;p&gt;The class can receive in the constructor any part of the cake infrastructure (ICakeContext, ICakeLog, ICakeArguments, ICakeConfiguration…)&lt;/p&gt;

&lt;p&gt;All the methods that have the signature &lt;code&gt;void Name(CakeTaskBuilder builder)&lt;/code&gt; will be called, and the name of the method will be the name of the task.&lt;/p&gt;

&lt;h2&gt;
  
  
  ContextData&amp;lt;&amp;gt;
&lt;/h2&gt;

&lt;p&gt;Here we can use any class that will then be available for use in the task’s definitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  InstallNugetTool
&lt;/h2&gt;

&lt;p&gt;Given a package name and a version, installs a nuget package as a &lt;a href="https://cakebuild.net/docs/writing-builds/tools/installing-tools"&gt;Cake tool&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Putting it all together&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Cake.Common.Diagnostics;
using Cake.Console;
using Cake.Core;

new CakeHostBuilder()
    .WorkingDirectory&amp;lt;WorkingDir&amp;gt;()
    .ContextData&amp;lt;ContextData&amp;gt;()
    .RegisterTasks&amp;lt;CakeTasks&amp;gt;()
    .InstallNugetTool("xunit.runner.console", "2.4.1")
    .RunCakeCli(args);

record WorkingDir(string WorkingDirectory = ".") : IWorkingDirectory;

class ContextData
{
    public string SomeVeryImportantData { get; set; } = "Cake is awesome!";
    public ContextData(ICakeArguments args)
    {
        if (args.HasArgument("tone-down"))
        {
            SomeVeryImportantData = "Cake is pretty good...";
        }
    }
}

class CakeTasks : ICakeTasks
{
    private readonly ICakeContext ctx;

    public CakeTasks(ICakeContext ctx) =&amp;gt; this.ctx = ctx;

    public void TaskName(CakeTaskBuilder b) =&amp;gt; b
        .Description("Some task")
        .Does(() =&amp;gt; ctx.Information("Something"));

    public void AnotherTask(CakeTaskBuilder b) =&amp;gt; b
        .IsDependentOn(nameof(TaskName))
        .Does&amp;lt;ContextData&amp;gt;(data =&amp;gt; ctx.Information(data.SomeVeryImportantData));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>longs</category>
      <category>original</category>
      <category>dev</category>
    </item>
    <item>
      <title>Presenting Cake.Console</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Mon, 06 Sep 2021 09:09:27 +0000</pubDate>
      <link>https://dev.to/pitermarx/presenting-cakeconsole-3bna</link>
      <guid>https://dev.to/pitermarx/presenting-cakeconsole-3bna</guid>
      <description>&lt;p&gt;I wanted to run &lt;a href="https://cakebuild.net/"&gt;Cake&lt;/a&gt; inside a console app, without the penalty of pre-processing the .cake DSL, and have the all the power of an IDE (refactorings, find usages,…). I had 2 possibilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://cakebuild.net/docs/running-builds/runners/cake-frosting"&gt;Cake.Frosting&lt;/a&gt;
This was the best option, but I really didn’t like a couple of things like, the ceremony of writing a class for each task or using attributes for describing tasks instead of the fluent syntax of cake scripts&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/devlead/Cake.Bridge/"&gt;Cake.Bridge&lt;/a&gt;
This was more in line with what I wanted, but It missed some stuff like tool installing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, it was time to roll up my sleeves and get to work. Presenting &lt;a href="https://github.com/pitermarx/Cake.Console"&gt;Cake.Console&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;![var cake = new CakeHostBuilder(args)&lt;br&gt;
    .InstallNugetTool("xunit.runner.console", "2.4.1")&lt;br&gt;
    .Build();&lt;/p&gt;

&lt;p&gt;cake.Task("Hello")&lt;br&gt;
    .Description("This is just like a cake script")&lt;br&gt;
    .IsDependeeOf("World")&lt;br&gt;
    .Does(c =&amp;gt; c.Information("but methods are on the 'cake' object"));&lt;/p&gt;

&lt;p&gt;cake.Task("World")&lt;br&gt;
    .Does(c =&amp;gt; c.Information("Hello world"));&lt;/p&gt;

&lt;p&gt;var target = cake.Context.Argument("target", "hello");&lt;br&gt;
cake.RunTarget(target);](&lt;a href="https://blog.pitermarx.com/wp-content/uploads/2021/09/image-1024x606.png"&gt;https://blog.pitermarx.com/wp-content/uploads/2021/09/image-1024x606.png&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;It’s a fairly simple project, but I learned a lot about cake’s internals.&lt;/p&gt;

&lt;p&gt;Cake has an architecture where every piece of functionality is behind an interface and is injected into objects as needed. Then the registering of interfaces into implementations is defined in “Modules”. There is a &lt;em&gt;ICakeContainerRegistrar&lt;/em&gt; Object that can receive registrations. I needed to implement a registrar if I wanted to take advantage of internal implementations of interfaces from Cake. So I did create a &lt;a href="https://github.com/pitermarx/Cake.Console/blob/main/Cake.Console/Internals/CakeContainer.cs"&gt;CakeContainer&lt;/a&gt; that can receive registrations from Cake.Core and Cake.Nuget modules and then create an &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.iserviceprovider?view=net-5.0"&gt;IServiceProvider&lt;/a&gt; that can instantiate the needed parts of cake.&lt;/p&gt;

&lt;p&gt;After understanding this part, It’s just a case of wiring some moving parts and I got it to work. The only “hand coded” part was the parsing of commandline arguments, which was done very naively.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UOKHKps6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-1-1024x477.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UOKHKps6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-1-1024x477.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I got was a piece of code that can give me a IScriptHost object, which is the implicit object that is called on .cake scripts when we define Tasks or use Addins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RRkKqgzU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-2-1024x403.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RRkKqgzU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-2-1024x403.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I still needed one thing, the installation of &lt;a href="https://cakebuild.net/docs/writing-builds/tools/"&gt;tools&lt;/a&gt;. I then added 2 things, a way to register stuff into the &lt;em&gt;ICakeContainerRegistrar&lt;/em&gt; and a special interface &lt;em&gt;IHostBuilderBehaviour&lt;/em&gt; that executes a Run() method before returning the IScriptHost, to add functionality into Cake.Console. What I got was a very simple CakeHostBuilder that I can then extend via extension methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VXWcL0ne--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-3-1024x823.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VXWcL0ne--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-3-1024x823.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all this infrastructure in place I then added 5 extensions that fulfilled all my needs in this project&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Installing Tools&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I added the interface &lt;em&gt;ICakeToolReference&lt;/em&gt;, and the &lt;em&gt;&lt;a href="https://github.com/pitermarx/Cake.Console/blob/main/Cake.Console/HostBuilderBehaviours/ToolInstallerBehaviour.cs"&gt;ToolInstallerBehaviour&lt;/a&gt;&lt;/em&gt;. Created also a &lt;em&gt;&lt;a href="https://github.com/pitermarx/Cake.Console/blob/main/Cake.Console/Internals/CakeNugetTool.cs"&gt;CakeNugetTool&lt;/a&gt;_class to create the correct Url for a nuget package.&lt;br&gt;&lt;br&gt;
Then it’s just a matter of registering _ICakeToolReference_s into the _ICakeContainerRegistrar&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FEaO9Zz0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-7-1024x325.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FEaO9Zz0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-7-1024x325.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Tasks from methods&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I added the &lt;em&gt;ICakeTasks&lt;/em&gt; interface and the &lt;em&gt;&lt;a href="https://github.com/pitermarx/Cake.Console/blob/main/Cake.Console/HostBuilderBehaviours/TaskRegisteringBehaviour.cs"&gt;TaskRegisteringBehaviour&lt;/a&gt;&lt;/em&gt;, which instantiates the &lt;em&gt;ICakeTasks&lt;/em&gt;, and calls all the methods that receive a &lt;em&gt;CakeTaskBuilder&lt;/em&gt;. This CakeTaskBuilder will already have created the Task with the same name as the method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ONG7FxiG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-6-1024x731.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ONG7FxiG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-6-1024x731.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Changing WorkingDirectory&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Once more I added the &lt;em&gt;IWorkingDirectory&lt;/em&gt; interface which has working directory string a and the &lt;em&gt;&lt;a href="https://github.com/pitermarx/Cake.Console/blob/6842a38b6c/Cake.Console/HostBuilderBehaviours/WorkingDirectoryBehaviour.cs"&gt;WorkingDirectoryBehaviour&lt;/a&gt;&lt;/em&gt;, that converts it to an absolute path and changes the working directory. Useful when your build scripts are not in the same tree as the code itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rZoQfAJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-8-1024x509.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rZoQfAJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-8-1024x509.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto setup context data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Setup callback on the &lt;em&gt;IScriptHost&lt;/em&gt; can return an object that can then be used in the CakeTaskBuilder extensions. This is called a &lt;a href="https://cakebuild.net/docs/writing-builds/sharing-build-state#typed-context"&gt;Typed Context&lt;/a&gt;. I wanted a typed context that could tap into the internals of cake, so it needed to be registered into the &lt;em&gt;ICakeContainerRegistrar&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Once more I created a &lt;a href="https://github.com/pitermarx/Cake.Console/blob/6842a38b6c/Cake.Console/HostBuilderBehaviours/SetupContextDataBehaviour.cs"&gt;SetupContextDataBehaviour&lt;/a&gt;, and I’m good to go. I can even register multiple typed context and use the needed one on different tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J6ZJSozx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-9-1024x777.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J6ZJSozx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-9-1024x777.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run target&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I found myself hating that part of the script that reads the “target” from the arguments. It just breaks the fluent vibe from the code! So I extended the &lt;em&gt;CakeHostBuilder&lt;/em&gt; to have a Run method that simply reads the target from the arguments and runs it. Putting it all together…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KTkER2vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-11-1024x446.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KTkER2vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.pitermarx.com/wp-content/uploads/2021/09/image-11-1024x446.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All modesty aside, I really think it is looking great!&lt;/p&gt;

</description>
      <category>longs</category>
      <category>original</category>
      <category>dev</category>
    </item>
    <item>
      <title>Goodbye!</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Fri, 26 Mar 2021 09:53:04 +0000</pubDate>
      <link>https://dev.to/pitermarx/goodbye-ee5</link>
      <guid>https://dev.to/pitermarx/goodbye-ee5</guid>
      <description>&lt;p&gt;In March 2021, I left the company and the project that I worked for 9 years. This is my goodbye message.&lt;/p&gt;

&lt;p&gt;If I’m going to be completely honest, I never liked to read this kind of goodbye messages, but now that it’s my turn to go, I feel compelled to write something. Now more than ever when we cannot see each other face to face, I want to leave a few words to you. People seem to think that when we are going through this kind of transition, suddenly we are filled with a burst of wisdom and thus are more willing to hear us out.&lt;/p&gt;

&lt;p&gt;I’ve been a part of &lt;a href="https://www.linkedin.com/company/critical-software/"&gt;Critical Software&lt;/a&gt; since 2012 and had my share of high and low moments, but overall I &lt;strong&gt;know&lt;/strong&gt; this has been an invaluable experience. As our last &lt;a href="https://www.linkedin.com/in/goncaloquadros/"&gt;CEO&lt;/a&gt; used to say, this company is a real “&lt;em&gt;school of engineering&lt;/em&gt;“, for those that are willing to learn. It’s not because we are so much smarter than everyone else, but because we are willing to empower ourselves to experiment, learn and improve on the job.&lt;/p&gt;

&lt;p&gt;In these 9 years I’ve only worked on &lt;strong&gt;&lt;em&gt;one&lt;/em&gt;&lt;/strong&gt; project, &lt;a href="https://www.linkedin.com/company/verticalla/"&gt;Verticalla&lt;/a&gt;‘s &lt;a href="http://www.verticalla.ch/en/solutions/vision-center/overview"&gt;VisionCenter&lt;/a&gt;. I can affirm proudly that I’m in part responsible for it’s success. Nevertheless, even though I enjoyed very much the work I’ve done, upon some reflection I’ve come to the realization that what stays most fondly in my memory are the relationships I’ve built over the years.&lt;/p&gt;

&lt;p&gt;Those who know me, are aware that I’m &lt;strong&gt;not&lt;/strong&gt; very good at building and keeping such relationships but I’m &lt;strong&gt;grateful&lt;/strong&gt; that some of you took the time and patience to get to know me and become more than mere co-workers. I advise everyone get to know the people that you work with and befriend them, even though some of them (like myself) are not very friendly. It will bring benefits not only to your personal life (it’s nice to have friends) but also to your work! When we like the ones we work with, we are &lt;sup&gt;(1)&lt;/sup&gt; more available to listen to them and &lt;sup&gt;(2)&lt;/sup&gt; to be more sympathetic to their shortcomings. This raises the levels of trust, which in turn increases productivity, morale, team work and overall happiness.&lt;/p&gt;

&lt;p&gt;Some of the friends I’ve made at Critical Software, are no longer working there – like &lt;a href="https://www.linkedin.com/in/nesousa/"&gt;Nuno Sousa&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/rjguerra/"&gt;Ricardo Guerra&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/pedro-f-da-costa/"&gt;Pedro Costa&lt;/a&gt;, my mentors – but many still are. Thank you &lt;a href="https://www.linkedin.com/in/tiagocarrega/"&gt;Tiago Carregã&lt;/a&gt; for the chess games (I know I suck), &lt;a href="https://www.linkedin.com/in/luisa-barbosa-9267659b/"&gt;Luisa Barbosa&lt;/a&gt; for telling me to shut up, &lt;a href="https://www.linkedin.com/in/catarina-azevedo1512/"&gt;Catarina Azevedo&lt;/a&gt; for the good mood in the office, &lt;a href="https://www.linkedin.com/in/agn%C4%97-pustovoitait%C4%97-97b5a183/"&gt;Agne Pustovoitaite&lt;/a&gt; for the Lithuanian lessons, Paulo Silva for the music, &lt;a href="https://www.linkedin.com/in/mattbrake/"&gt;Matt Brake&lt;/a&gt; for being very approachable&lt;/p&gt;

&lt;p&gt;Also, from &lt;a href="https://www.linkedin.com/company/sauter/"&gt;Sauter&lt;/a&gt; side, I really enjoyed working with &lt;a href="https://www.linkedin.com/in/patrice-hell-454b8744/"&gt;Patrice Hell&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/hartmut-melchin-49923998/"&gt;Hartmut Melchin&lt;/a&gt;, both being top quality professionals. I cannot name you all but, thanks to &lt;a href="https://www.linkedin.com/in/benjamim/"&gt;Benjamim Cardoso&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/carla-machado-b3440329/"&gt;Carla Machado&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/telmoinacio"&gt;Telmo Inácio&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/jorge-alves-8ab0742/"&gt;Jorge Ribeiro&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/hansousa/"&gt;Hugo Sousa&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/ricardo-lamar%C3%A3o/"&gt;Ricardo Lamarão&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/lnors/"&gt;Luís Silva&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/nunoalexandrealves/"&gt;Nuno Alves&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/jo%C3%A3o-carloto-7993b164/"&gt;João Carloto&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/braselina-sousa-85a5463/"&gt;Braselina Sousa&lt;/a&gt; and so many others that had a good influence on me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you’re brave enough to say goodbye, life will reward you with a new hello&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;Paulo Coelho&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So thank you all and goodbye!&lt;/p&gt;




&lt;p&gt;As we’re approaching &lt;a href="https://en.wikipedia.org/wiki/Easter"&gt;Easter&lt;/a&gt;, and this is one of the most important times of the year for a christian like me, I want also to leave you with some thoughts about Jesus and his resurrection.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Christianity is a fact-based religion and the resurrection is the most important of those facts. &lt;/li&gt;
&lt;li&gt;If Jesus did not rise from the dead, then Christianity is false and life ends on the grave

&lt;ul&gt;
&lt;li&gt;There is no heaven or hell&lt;/li&gt;
&lt;li&gt;There is no punishment for evil&lt;/li&gt;
&lt;li&gt;There is no reward for good&lt;/li&gt;
&lt;li&gt;Jesus’ death is just another death&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If Jesus did rise from the dead, then Christianity is true and life does not end on the grave

&lt;ul&gt;
&lt;li&gt;There is hope of heaven&lt;/li&gt;
&lt;li&gt;Evil will be punished&lt;/li&gt;
&lt;li&gt;Good will be rewarded&lt;/li&gt;
&lt;li&gt;Jesus’ death unlocks the door to eternal life&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we have assurance of the fact of the resurrection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;However bad things get in this life, heaven is secure for us.&lt;/li&gt;
&lt;li&gt;We have peace over the death of our loved ones, because they are not gone forever.&lt;/li&gt;
&lt;li&gt;Christ’s resurrection is the basis of the trust we have of our own resurrection. He conquered death.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, being sure that the resurrection really occurred, is of great importance. Don’t take my word for it. Check for yourselves!&lt;/p&gt;

&lt;p&gt;If you do the research and find out I’m wrong, you just lost a bit of time.&lt;/p&gt;

&lt;p&gt;If you do the research and find out I’m right, you also lost a bit of time but gained eternity.&lt;/p&gt;




&lt;p&gt;Some resources to get you started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From Dr. &lt;a href="http://www.reasonablefaith.org"&gt;William Lane Craig&lt;/a&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.reasonablefaith.org/writings/popular-writings/jesus-of-nazareth/the-resurrection-of-jesus/"&gt;https://www.reasonablefaith.org/writings/popular-writings/jesus-of-nazareth/the-resurrection-of-jesus/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=4qhQRMhUK1o"&gt;https://www.youtube.com/watch?v=4qhQRMhUK1o&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=6SbJ4p6WiZE"&gt;https://www.youtube.com/watch?v=6SbJ4p6WiZE&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;From Dr. &lt;a href="http://www.garyhabermas.com"&gt;Gary Habermas&lt;/a&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/-/pt/gp/product/B08P9JD6J7/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i1"&gt;https://www.amazon.com/-/pt/gp/product/B08P9JD6J7/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.garyhabermas.com/articles/articles.htm"&gt;www.garyhabermas.com/articles/articles.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=ay_Db4RwZ_M"&gt;https://www.youtube.com/watch?v=ay_Db4RwZ_M&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;From Dr. &lt;a href="https://www.risenjesus.com/"&gt;Mike Licona&lt;/a&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Resurrection-Jesus-New-Historiographical-Approach/dp/0830827196"&gt;https://www.amazon.com/Resurrection-Jesus-New-Historiographical-Approach/dp/0830827196&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.academia.edu/3684318/Michael_Licona_The_Resurrection_of_Jesus_A_New_Historiographical_Approach_TLC_"&gt;https://www.academia.edu/3684318/Michael_Licona_The_Resurrection_of_Jesus_A_New_Historiographical_Approach_TLC_&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=LcoxS8mJGG8"&gt;https://www.youtube.com/watch?v=LcoxS8mJGG8&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>longs</category>
      <category>original</category>
      <category>christianity</category>
      <category>dev</category>
    </item>
    <item>
      <title>Dependence</title>
      <dc:creator>Pedro Marques</dc:creator>
      <pubDate>Tue, 23 Mar 2021 12:00:54 +0000</pubDate>
      <link>https://dev.to/pitermarx/dependence-57mg</link>
      <guid>https://dev.to/pitermarx/dependence-57mg</guid>
      <description>&lt;p&gt;I’ve been thinking about the stuff I depend upon to keep this blog, and in particular about &lt;a href="https://en.wikipedia.org/wiki/Link_rot"&gt;link rot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Most of the stuff I post here is sharing something I saw elsewhere.&lt;/p&gt;

&lt;p&gt;I depend on other sites I link to to keep the links alive. I could mitigate this by always linking via the &lt;a href="https://web.archive.org/"&gt;Wayback Machine&lt;/a&gt;, but I would also be dependent on them…&lt;/p&gt;

&lt;p&gt;I depend on YouTube for the videos I share. I could copy and host them myself, but that would increase a LOT the cost of keeping all the stuff. I depend on Spotify for the songs I share. I could copy the audio and host them myself, but that might be considered a copyright violation.&lt;/p&gt;

&lt;p&gt;And even for stuff I own and have a backup for, I depend on &lt;a href="https://www.flickr.com/photos/pitermarx/"&gt;Flickr&lt;/a&gt; to keep my photos, on &lt;a href="https://soundcloud.com/pitermarx"&gt;SoundCloud&lt;/a&gt; to keep my music, on &lt;a href="https://github.com/pitermarx"&gt;GitHub&lt;/a&gt; to keep my code. The list goes on and on…&lt;/p&gt;

&lt;p&gt;Dependence and trust. This is what makes the web go round.&lt;/p&gt;

&lt;p&gt;Speaking of trust…&lt;/p&gt;

&lt;p&gt;Should I go live in a cabin in the woods?&lt;/p&gt;

</description>
      <category>original</category>
      <category>shorts</category>
      <category>dev</category>
    </item>
  </channel>
</rss>
