<?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: Yousef</title>
    <description>The latest articles on DEV Community by Yousef (@yousefmajidi).</description>
    <link>https://dev.to/yousefmajidi</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%2F1156077%2Fc24a455f-1acd-4e39-9820-3bee5d062abf.jpeg</url>
      <title>DEV Community: Yousef</title>
      <link>https://dev.to/yousefmajidi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yousefmajidi"/>
    <language>en</language>
    <item>
      <title>Reflecting on the Journey with Explore.CLI</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Mon, 11 Dec 2023 22:23:57 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/reflecting-on-the-journey-with-explorecli-1g8h</link>
      <guid>https://dev.to/yousefmajidi/reflecting-on-the-journey-with-explorecli-1g8h</guid>
      <description>&lt;p&gt;As I close this chapter of my contributions to &lt;a href="https://github.com/SmartBear-DevRel/explore-cli"&gt;Explore.CLI&lt;/a&gt;, it's time to reflect on the results, the learning process, and the invaluable interactions with the community that shaped this journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Achieving Goals and Implementing Technical Features
&lt;/h2&gt;

&lt;p&gt;The primary goal of enhancing the 'Import' feature with the &lt;code&gt;--names&lt;/code&gt; option has been successfully achieved. Other goals such as removing deprecated options and bug fixes have also been achieved and the &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/pull/19"&gt;pull request&lt;/a&gt; was merged seamlessly, marking a significant milestone. This achievement was not just about adding features. It demonstrated my growth in understanding the project's expectations and improving my testing skills to identify and address bugs proactively.&lt;/p&gt;

&lt;p&gt;The technical implementation of this feature was a critical aspect of my contributions to Explore.CLI. The process entailed modifying the &lt;code&gt;Option&lt;/code&gt; variable and command handler to make room for the new functionality. Additionally, it was necessary to incorporate logic that could process the provided list of names effectively. I provided more technical details in my &lt;a href="https://dev.to/yousefmajidi/explorecli-progress-51ce"&gt;previous blog post&lt;/a&gt;. The emphasis was on writing clean and efficient code to ensure that these new features integrated seamlessly into the existing framework without disrupting the user experience.&lt;/p&gt;

&lt;p&gt;Equally important was the rigorous testing and debugging phase, which went beyond merely verifying successful implementation. It was about ensuring that the introduction of new features did not give rise to new bugs. This step was instrumental in maintaining the integrity and reliability of the tool, reinforcing its value to the users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Expectations and Time
&lt;/h2&gt;

&lt;p&gt;Reflecting on the goals I had &lt;a href="https://dev.to/yousefmajidi/planning-more-enhancements-for-explorecli-5do9"&gt;initially set&lt;/a&gt;, my ambition was always high. This time, I deliberately chose issues within my capacity, learning from past experiences where I overestimated my bandwidth. Balancing this project with academic responsibilities taught me the importance of time management and setting realistic expectations. This approach of tackling problems incrementally not only made the workload manageable but also boosted my confidence and efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning from the Process and Community Interaction
&lt;/h2&gt;

&lt;p&gt;Throughout this journey, I've encountered a significant learning curve that has been nothing short of transformative. Additionally, the process has refined my coding abilities, particularly in optimizing and cleaning up the codebase. Removing deprecated features while ensuring existing functionalities remain unaffected has taught me the essential practice of maintaining a clean and efficient code structure.&lt;/p&gt;

&lt;p&gt;The role of the community surrounding Explore.CLI cannot be overstated. Collaborating with other contributors through GitHub issues and pull requests (and sometimes on other social media apps) proved to be a cornerstone of the problem-solving process. The diverse perspectives and alternative solutions offered by community members often shed light on issues and potential improvements I hadn't previously considered. Moreover, the constant stream of feedback was invaluable for fine-tuning the features I worked on. This two-way exchange allowed me not only to contribute my knowledge but also to benefit from the collective wisdom of the community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluding Thoughts
&lt;/h2&gt;

&lt;p&gt;Looking back, this experience with Explore.CLI has been about growth, technical challenges, and community engagement. It was more than just coding; it was about being part of an ecosystem where each contribution matters. As I move forward, the insights and skills gained from this project will undoubtedly influence my future endeavours in open-source development.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Explore.CLI - Progress</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Sat, 09 Dec 2023 15:52:57 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/explorecli-progress-51ce</link>
      <guid>https://dev.to/yousefmajidi/explorecli-progress-51ce</guid>
      <description>&lt;p&gt;Welcome back to the ongoing journey of enhancing &lt;a href="https://github.com/SmartBear-DevRel/explore-cli"&gt;Explore.CLI&lt;/a&gt;! As I &lt;a href="https://dev.to/yousefmajidi/planning-more-enhancements-for-explorecli-5do9"&gt;discussed last week&lt;/a&gt;, my focus has been on implementing new features and refining existing ones. In this update, I am excited to share the progress made and the intricacies of the latest improvements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhancing the 'Import' Feature
&lt;/h2&gt;

&lt;p&gt;Building upon the momentum of previous weeks, where I enhanced the &lt;code&gt;Export&lt;/code&gt; feature, I turned my attention to the &lt;code&gt;Import&lt;/code&gt; feature. The primary enhancement was the integration of the &lt;code&gt;--names&lt;/code&gt; option, similar to what was done for &lt;code&gt;Export&lt;/code&gt;. This required a few key updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modifying the &lt;code&gt;Option&lt;/code&gt; variable &lt;code&gt;names&lt;/code&gt; to indicate its dual functionality for both import and export.&lt;/li&gt;
&lt;li&gt;Adjusting the &lt;code&gt;importSpaceCommand&lt;/code&gt; to correctly utilize the &lt;code&gt;names&lt;/code&gt; option.&lt;/li&gt;
&lt;li&gt;Updating the &lt;code&gt;ImportSpaces&lt;/code&gt; method to handle a comma-separated list of names.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementation ensures a more intuitive and flexible import process, catering to specific user needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Refinement and Bug Fixing
&lt;/h2&gt;

&lt;p&gt;In addition to feature enhancement, a significant part of my focus was on refining existing code and addressing bugs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Removing Deprecated Features:&lt;/strong&gt; Following discussions on &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/issues/18"&gt;issue #18&lt;/a&gt;, I removed the &lt;code&gt;import-inspector-collections&lt;/code&gt; feature, ensuring the codebase remains streamlined and up-to-date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bug Fixing:&lt;/strong&gt; A small bug, &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/pull/17#issuecomment-1825865327"&gt;identified&lt;/a&gt; in my previous contributions, was addressed. The application now displays an appropriate message when no matching spaces are found during export or import, improving user experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Snippets
&lt;/h3&gt;

&lt;p&gt;Here's a glimpse of the key code changes implemented:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Modifying the &lt;code&gt;names&lt;/code&gt; option:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"--names"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"The names of the spaces to export or import"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;IsRequired&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Adjusting &lt;code&gt;importSpaceCommand&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;importSpacesCommand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"import-spaces"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;exploreCookie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;importFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;verbose&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;importSpacesCommand&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;ImportSpaces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;exploreCookie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;importFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Implementing checks for matching spaces during import and export:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// For Export&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namesList&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;namesList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AnsiConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MarkupLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"[orange3]'Skipped &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;': Name not found in list of names to export[/]"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// For Import&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;exportedSpace&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;exportedSpaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExploreSpaces&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namesList&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;exportedSpace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;namesList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exportedSpace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AnsiConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MarkupLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"[orange3]'Skipped &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;exportedSpace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;': Name not found in list of names to import[/]"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Documentation and Pull Request
&lt;/h3&gt;

&lt;p&gt;Finally, the &lt;code&gt;README.md&lt;/code&gt; file was meticulously updated to reflect these changes, aiding future contributors and users. All these updates are encapsulated in a &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/pull/19"&gt;pull request&lt;/a&gt;, which is currently under review. I have already addressed a minor typo pointed out by the repository owner and am eagerly awaiting the final approval.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This phase of enhancements to Explore.CLI has been a blend of expansion, refinement, and learning. It demonstrates the project's commitment to continuous improvement and user-centric development. As always, I am keen to hear feedback and look forward to sharing more updates soon.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Planning More Enhancements for Explore.CLI</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Fri, 01 Dec 2023 23:50:48 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/planning-more-enhancements-for-explorecli-5do9</link>
      <guid>https://dev.to/yousefmajidi/planning-more-enhancements-for-explorecli-5do9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Future Contributions
&lt;/h2&gt;

&lt;p&gt;As I continue my journey with the open-source project &lt;a href="https://github.com/SmartBear-DevRel/explore-cli"&gt;Explore.CLI&lt;/a&gt;, my focus shifts toward upcoming enhancements and learning from past experiences. Although I recently &lt;a href="https://dev.to/yousefmajidi/enhancing-explorecli-mn1"&gt;added new features&lt;/a&gt; and identified a minor bug in my previous work, the path ahead promises more growth and development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planned Enhancements and Strategy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Expanding the 'Import' Feature
&lt;/h3&gt;

&lt;p&gt;After fruitful discussions with the repository owner, I am set to extend the functionality of the &lt;code&gt;Import&lt;/code&gt; option, mirroring the expansion I previously implemented in the &lt;code&gt;Export&lt;/code&gt; feature. The main task involves integrating the &lt;code&gt;--names&lt;/code&gt; option into the &lt;code&gt;Import&lt;/code&gt; functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Removing Deprecated Feature
&lt;/h3&gt;

&lt;p&gt;A significant part of my upcoming work includes removing the now-deprecated &lt;code&gt;import-inspector-collections&lt;/code&gt; feature. This task necessitates a detailed review of the codebase to ensure complete and clean removal of all related components, ensuring the application remains efficient and up-to-date.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addressing Past Bugs
&lt;/h3&gt;

&lt;p&gt;In addition to these enhancements, I plan to rectify the bug identified in my previous contribution. It involves implementing a more accurate user notification system for scenarios where provided Space names do not match, affecting both the &lt;code&gt;Import&lt;/code&gt; and &lt;code&gt;Export&lt;/code&gt; features with the new changes planned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach and Reflections
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Learning and Adapting
&lt;/h3&gt;

&lt;p&gt;Reflecting on my previous experience, where I underestimated the workload, I intend to approach these tasks with a more segmented and manageable strategy. This approach aims to prevent overextension and ensures that each enhancement is given the attention it deserves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparatory Work
&lt;/h3&gt;

&lt;p&gt;Before diving into these tasks, I need to familiarize myself with the intricacies of the &lt;code&gt;Import&lt;/code&gt; feature, and understand its functionality, requirements, and code structure. This preparation is crucial for effective and efficient development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation Updates
&lt;/h3&gt;

&lt;p&gt;An important final step will be to update the &lt;code&gt;README.md&lt;/code&gt; file, reflecting the new changes and improvements made to the Explore-CLI project. This documentation will assist future contributors and users in navigating the enhanced application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion and Upcoming Update
&lt;/h2&gt;

&lt;p&gt;As I embark on these new challenges and opportunities for growth within the Explore-CLI project, I look forward to sharing insights and progress in my next update. Stay tuned for a detailed account of how these enhancements unfold and the lessons learned along the way.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The NuGet Publishing Puzzle</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Fri, 24 Nov 2023 19:45:09 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/the-nuget-publishing-puzzle-o08</link>
      <guid>https://dev.to/yousefmajidi/the-nuget-publishing-puzzle-o08</guid>
      <description>&lt;h3&gt;
  
  
  Navigating the Challenges with Learn2Blog
&lt;/h3&gt;

&lt;p&gt;Hello again, readers! Today, I want to share a recent experience that illustrates the complexities and unexpected hurdles in software development. Specifically, my journey in attempting to publish my project, &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog"&gt;Learn2Blog&lt;/a&gt;, to NuGet.&lt;/p&gt;

&lt;h4&gt;
  
  
  Preparing for NuGet Publication
&lt;/h4&gt;

&lt;p&gt;After weeks of diligent development on Learn2Blog, I reached a point where I was ready to publish it on NuGet. For those unfamiliar, NuGet is a package manager for the Microsoft development platform, and publishing a project on it involves creating a &lt;code&gt;.nupkg&lt;/code&gt; file – a packaged version of your project.&lt;/p&gt;

&lt;h4&gt;
  
  
  Adhering to the NuGet Documentation
&lt;/h4&gt;

&lt;p&gt;To ensure a smooth process, I turned to Microsoft's &lt;a href="https://learn.microsoft.com/en-us/nuget/create-packages/overview-and-workflow"&gt;Package creation workflow&lt;/a&gt; in the NuGet Documentation. This section meticulously outlines the necessary steps for packaging a project. The subsequent step involves creating an account on &lt;a href="https://www.nuget.org/users/account/LogOn"&gt;NuGet&lt;/a&gt; and uploading the &lt;code&gt;.nupkg&lt;/code&gt; file.&lt;/p&gt;

&lt;h4&gt;
  
  
  Facing the Unexpected
&lt;/h4&gt;

&lt;p&gt;Confidently, I followed the instructions, ensuring my project was correctly set up for packaging. However, when I ran the packaging command, nothing seemed to happen. No &lt;code&gt;.nupkg&lt;/code&gt; file was created. Increasing the verbosity with the &lt;code&gt;-v&lt;/code&gt; flag in a subsequent attempt, I analyzed the log for errors or warnings, only to find none. My next move was to use the &lt;code&gt;-o&lt;/code&gt; flag to specify an output directory, but again, no file was generated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Exploring Potential Issues
&lt;/h4&gt;

&lt;p&gt;At this point, I began to contemplate various potential issues that might be causing this behaviour. Could there be an unseen error in my project configuration? Was there a problem with the version of the .NET framework I was using? Or perhaps there was an issue with the NuGet package manager itself.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Stalemate and Further Exploration
&lt;/h4&gt;

&lt;p&gt;Despite exploring every avenue I could think of and scouring the internet for solutions, I found myself at an impasse. In an attempt to uncover some clue or insight, I even delved into other .NET open-source projects, hoping to stumble upon a similar issue or a hint that could lead me in the right direction.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Temporary Pause
&lt;/h4&gt;

&lt;p&gt;Faced with a persistent mystery and no clear path forward, I decided to step back from the issue, planning to revisit it if I came across any new information or insights. Sometimes, taking a break and returning with a fresh perspective can make all the difference in problem-solving.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reflecting on the Process
&lt;/h4&gt;

&lt;p&gt;This experience with NuGet and Learn2Blog is a reminder of the intricate and often unpredictable nature of software development. It highlights the importance of resilience, continuous learning, and the willingness to seek help from the community. &lt;/p&gt;

&lt;p&gt;Stay tuned for updates on this journey, and in the meantime, I encourage anyone who has faced similar challenges or has insights to share to reach out. Together, we can unravel these puzzles and continue to grow as developers.&lt;/p&gt;

&lt;p&gt;Until next time, keep coding and exploring!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Enhancing Explore.CLI</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Fri, 24 Nov 2023 19:00:03 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/enhancing-explorecli-mn1</link>
      <guid>https://dev.to/yousefmajidi/enhancing-explorecli-mn1</guid>
      <description>&lt;p&gt;Greetings, fellow developers! Today, I'm happy to share my recent adventure with the &lt;code&gt;Explore.Cli&lt;/code&gt; project, a journey marked by tackling challenging features and collaborative problem-solving, ultimately leading to the exciting release of Explore.CLI version 0.4.0.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to Explore.CLI
&lt;/h3&gt;

&lt;p&gt;During Hacktoberfest 2023, I discovered &lt;a href="https://github.com/SmartBear-DevRel/explore-cli"&gt;Explore.Cli&lt;/a&gt;, an intriguing command-line tool that piqued my curiosity. This tool offers a range of functionalities designed to enhance user experience working with &lt;a href="https://swagger.io/tools/swaggerhub/"&gt;SwaggerHub&lt;/a&gt;, sparking my interest to dive deeper and contribute.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Steps and First Contributions
&lt;/h3&gt;

&lt;p&gt;My first engagement with Explore.Cli involved fixing a bug in their &lt;code&gt;export&lt;/code&gt; feature, a process I detailed in a blog post you can find &lt;a href="https://dev.to/yousefmajidi/hacking-away-in-week-3-of-hacktoberfest-o2m"&gt;here&lt;/a&gt;. This initial step marked the beginning of a deeper journey into the project's development.&lt;/p&gt;

&lt;p&gt;As I familiarized myself with Explore.Cli, several open issues caught my attention. Despite initial hesitations, I revisited two particular issues, deciding to take on the challenge of resolving them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue #6: Enhancing Export Functionality
&lt;/h3&gt;

&lt;p&gt;The first issue I tackled was &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/issues/6"&gt;issue #6&lt;/a&gt;, aimed at adding the ability to specify both a path and a filename for exporting. This required the introduction of a new &lt;code&gt;Option&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;exportPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"--export-path"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"The path for exporting files. It can be either a relative or absolute path"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;IsRequired&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;exportPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAlias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-ep"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also adjusted the &lt;code&gt;Handler&lt;/code&gt; for the &lt;code&gt;exportSpacesCommand&lt;/code&gt; to integrate this new option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;exportSpacesCommand&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ep&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;ExportSpaces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ep&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;exploreCookie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exportPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exportName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Subsequently, the &lt;code&gt;ExportSpaces&lt;/code&gt; method was modified to include these new options, and the &lt;code&gt;README.md&lt;/code&gt; was updated to reflect these changes, culminating in &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/pull/13"&gt;pull request #13&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Upon the Foundation: Issue #4
&lt;/h3&gt;

&lt;p&gt;Next, I addressed &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/issues/4"&gt;issue #4&lt;/a&gt;, which involved adding a feature for users to select specific spaces to export. Building on my previous work, I ensured compatibility and consistency by developing this feature on top of the initial issue branch, incorporating all commits from pull request #13 into &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/pull/14"&gt;pull request #14&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refining and Resolving Challenges
&lt;/h3&gt;

&lt;p&gt;Throughout this process, I encountered various challenges, including aligning my code with the project's coding style, handling additional scenarios, and implementing file system permissions checks. Feedback from the project author prompted significant refinements and improvements, including code refactoring and unit testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflow and Platform-Specific Considerations
&lt;/h3&gt;

&lt;p&gt;An interesting twist occurred when some of my tests failed on a workflow run. This issue arose due to the &lt;code&gt;GetInvalidFileNameChars()&lt;/code&gt; and &lt;code&gt;GetInvalidFilePathChars()&lt;/code&gt; methods behaving differently on Linux compared to Windows. Initially, I addressed this by creating a custom array for invalid characters, but I later realized that this was unnecessary, as the project was intended for Windows use. This was a valuable lesson in understanding project scope and platform-specific considerations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Release of Explore.Cli v0.4.0
&lt;/h3&gt;

&lt;p&gt;Finally, after overcoming these challenges and learning from them, I'm excited to announce that &lt;a href="https://www.nuget.org/packages/Explore.Cli"&gt;Explore.Cli v0.4.0&lt;/a&gt; is &lt;a href="https://www.linkedin.com/posts/frank-kilcommins_explorecli-040-activity-7133859321150361601-r3Oi?utm_source=share&amp;amp;utm_medium=member_desktop"&gt;officially out!&lt;/a&gt;. This release marks a significant milestone in my open-source journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflecting on the Experience
&lt;/h3&gt;

&lt;p&gt;This experience with Explore.Cli` has been both challenging and rewarding, reinforcing the collaborative and supportive nature of the open-source community. Each contribution, from code to conversations, has been a valuable part of my growth as a developer.&lt;/p&gt;

&lt;p&gt;Stay tuned for more insights and developments, and as always, I encourage you to dive into the project, contribute, and share your expertise. Happy coding!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>GitHub Actions Workflow</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Sat, 18 Nov 2023 01:21:31 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/github-actions-workflow-5a2l</link>
      <guid>https://dev.to/yousefmajidi/github-actions-workflow-5a2l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this week's focus on enhancing the development process for &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog"&gt;Learn2Blog&lt;/a&gt;, I delved into the realm of Continuous Integration (CI) by implementing a GitHub Actions Workflow. Continuous Integration pipelines and workflows are pivotal in modern software development, providing automated checks and balances to ensure code quality and stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Workflow
&lt;/h2&gt;

&lt;p&gt;To start, I turned to the &lt;a href="https://github.com/actions/starter-workflows/tree/main/ci"&gt;starter-workflows&lt;/a&gt; repository, a valuable resource housing diverse YAML files for various project types. My project being in .NET, I checked out the &lt;code&gt;dotnet.yml&lt;/code&gt; file to get  insights into the setup process. Understanding the YAML syntax and keywords like &lt;code&gt;on&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;jobs&lt;/code&gt;, and &lt;code&gt;steps&lt;/code&gt; is crucial for crafting an effective workflow. In my case, I wanted to the workflow to trigger "on" any "pushes" on the &lt;code&gt;main&lt;/code&gt; branch. The job describes the specific task which can be given a name, and steps outline the necessary steps to run the job. &lt;/p&gt;

&lt;p&gt;You can also go the &lt;code&gt;Actions&lt;/code&gt; tab on your main repository page and and select &lt;code&gt;new workflow&lt;/code&gt; from the menu on the left hand side. GitHub will recommend some templates for you based on your project. You can always modify it to your specific needs. &lt;/p&gt;

&lt;p&gt;Drawing inspiration from another open-source project, &lt;a href="https://github.com/SmartBear-DevRel/explore-cli"&gt;explore-cli&lt;/a&gt;, I learned how to tailor the workflow to accommodate the nested structure of my tester project. This involved specifying the path to the test &lt;code&gt;.csproj&lt;/code&gt; file, a key adjustment for successful execution.&lt;/p&gt;

&lt;p&gt;My workflow encompasses several essential steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checking out the latest code from the &lt;code&gt;main&lt;/code&gt; branch.&lt;/li&gt;
&lt;li&gt;Setting up the .NET environment.&lt;/li&gt;
&lt;li&gt;Restoring dependencies (which ensures that the project has all the necessary packages) &lt;/li&gt;
&lt;li&gt;Building the application.&lt;/li&gt;
&lt;li&gt;Running the test files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a detailed view of the workflow, refer to the &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/blob/main/.github/workflows/dotnet.yml"&gt;dotnet.yml&lt;/a&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hiccups Along the Way
&lt;/h2&gt;

&lt;p&gt;Just when everything seemed to be working fine, an unexpected challenge arose. While the workflow passed when I ran it, a contributor's pull request triggered failures in seemingly unrelated tests. Despite the contributor's newly added test passing, other existing tests failed mysteriously. Investigating this remains something I had to leave behind for the time being and come back to it later, and the pull request is temporarily on hold. But if you know why, please let me know in the comments! &lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing to Node-TILify
&lt;/h2&gt;

&lt;p&gt;Beyond my project, I also contributed to &lt;a href="https://github.com/sdthaker/Node-TILify"&gt;Node-TILify&lt;/a&gt;, a similar project by my friend &lt;a class="mentioned-user" href="https://dev.to/sdthaker"&gt;@sdthaker&lt;/a&gt;. Although I have an aversion to JavaScript [cue laugh emoji], he threw me a challenge my way. Testing his workflow seemed like a good gig!&lt;/p&gt;

&lt;p&gt;There are of course many differences between Jest and xUnit. I am fairly familiar with Jest as I have worked with it in the past, so setting up a new test for him was not particularly difficult. I would say working with xUnit has actually been more challenging since I am very new to it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To wrap it up, Continuous Integration (CI) plays a pivotal role in safeguarding code quality and stability. Whether you're an external contributor or the project's main developer, CI systems act as a safety net, significantly reducing the likelihood of errors. Setting up CI for your project, ideally at an early stage, is a worthwhile investment in the long-term reliability and health of your codebase.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Unit Testing</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Sat, 11 Nov 2023 01:21:11 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/unit-testing-1l1o</link>
      <guid>https://dev.to/yousefmajidi/unit-testing-1l1o</guid>
      <description>&lt;p&gt;This week, my focus in the development of &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog"&gt;Learn2Blog&lt;/a&gt; centred on implementing unit testing, a crucial aspect of ensuring the reliability and stability of the project. In this blog post, I'll delve into the significance of unit testing and touch upon the broader concept of end-to-end testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Importance of Testing
&lt;/h3&gt;

&lt;p&gt;Unit testing and end-to-end testing are essential practices in software development, contributing to the overall quality and robustness of a project. Unit testing involves testing individual components or functions in isolation, ensuring they produce the expected output. On the other hand, end-to-end testing validates the entire system's functionality, simulating real-world scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  xUnit.net
&lt;/h2&gt;

&lt;p&gt;I opted to use xUnit.net, a testing framework recommended by &lt;a href="https://learn.microsoft.com/en-us/dotnet/core/testing/#testing-tools"&gt;Microsoft's dotnet documentation&lt;/a&gt;. xUnit.net is known for its simplicity and efficiency in writing and executing tests.&lt;/p&gt;

&lt;p&gt;To integrate xUnit.net into your project, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package xunit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For creating a testing project and class in Visual Studio (Code), consider adding the &lt;code&gt;xunit.runner.visualstudio&lt;/code&gt; package, ensuring it's applied to the testing project, not the main one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Testing Project
&lt;/h3&gt;

&lt;p&gt;A testing project is crucial for maintaining a clean separation between the main project and its tests. In xUnit.net, each class and its methods in the testing project correspond to the classes and functionalities being tested.&lt;/p&gt;

&lt;h4&gt;
  
  
  Importing Main Project
&lt;/h4&gt;

&lt;p&gt;To import the main project into the testing project, modify the &lt;code&gt;TestingProject.csproj&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ProjectReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Relative path to MainProject.csproj"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Ensure the path is correctly specified.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Writing Tests
&lt;/h4&gt;

&lt;p&gt;I organized my tests by creating separate test classes corresponding to classes in the main project. For instance, the main project class &lt;code&gt;CommandLineParser&lt;/code&gt; has a corresponding test class named &lt;code&gt;CommandLineParserTests&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Utilizing &lt;code&gt;ITestOutputHelper&lt;/code&gt; allows printing messages for each test and we can use it in our test class like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CommandLineParserTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ITestOutputHelper&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CommandLineParserTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITestOutputHelper&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="c1"&gt;// rest of the code...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example of one of the tests the return outcome of running the app without any arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TestNoArgumentReturnsNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Should return null when user passes no arguments"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;CommandLineOptions&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CommandLineParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseCommandLineArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, the &lt;code&gt;[Fact]&lt;/code&gt; attribute indicates it as a test method. It then creates an empty array to pass as args to simulate passing no arguments through the CLI and then asserts that &lt;code&gt;options&lt;/code&gt; is returned as &lt;code&gt;null&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;[Theory]&lt;/code&gt; in xUnit
&lt;/h3&gt;

&lt;p&gt;xUnit.net's &lt;code&gt;[Theory]&lt;/code&gt; attribute simplifies testing scenarios with different sets of input data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Theory&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-o"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--output"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TestOutputArgument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Should return option with OutputPath == 'testOutput'"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"testOutput"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;CommandLineOptions&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CommandLineParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseCommandLineArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;OutputPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;[Theory]&lt;/code&gt; attribute allows running the same test with different input values. In this example, the test checks if the &lt;code&gt;CommandLineParser&lt;/code&gt; correctly handles different forms of the output argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  Incomplete Tests
&lt;/h2&gt;

&lt;p&gt;While I successfully implemented several tests, some scenarios proved challenging. For example, testing the &lt;code&gt;-c / --config&lt;/code&gt; argument requires mocking the config file, a task I documented in &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/issues/18"&gt;issue #18&lt;/a&gt;. Moq, a common tool for this in C# projects, was attempted but not fully successful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Coverage
&lt;/h3&gt;

&lt;p&gt;Code coverage is an essential metric indicating the percentage of code exercised by tests. Although I haven't yet implemented it in Learn2Blog, Microsoft guides generating code coverage reports for .NET projects &lt;a href="https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-code-coverage?tabs=windows"&gt;here&lt;/a&gt;. The pursuit of 100% code coverage ensures a more comprehensive validation of code integrity.&lt;/p&gt;

&lt;h2&gt;
  
  
  End-to-End Testing
&lt;/h2&gt;

&lt;p&gt;As of now, Learn2Blog lacks a dedicated end-to-end test. While core features have been extensively tested in unit tests, &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/issues/20"&gt;issue #20&lt;/a&gt; has been created to address this gap.&lt;/p&gt;

&lt;p&gt;End-to-end testing involves validating the entire application's workflow, ensuring all components work harmoniously. It complements unit testing by verifying the integration of various modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;Reflecting on the testing process, it became evident that certain design flaws and bugs surfaced during testing. This emphasizes the importance of early test development, enabling the identification and rectification of issues before they escalate.&lt;/p&gt;

&lt;p&gt;Automated tests, both unit and end-to-end, play a pivotal role in uncovering hidden bugs. The experience also highlighted the need for modular code, making it easier to test and maintain.&lt;/p&gt;

&lt;p&gt;The bug with the &lt;code&gt;StringWriter&lt;/code&gt; instance revealed during testing underscores the value of running multiple tests consecutively, mimicking real-world usage scenarios.&lt;/p&gt;

&lt;p&gt;After squashing all of the different commits into a single one, it was merged into the &lt;code&gt;main&lt;/code&gt; branch. You can review all the changes in &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/commit/8e8edac789ab6b1ade79e217b1537f9e1b16d879"&gt;8e8edac&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, the journey of implementing unit testing in Learn2Blog has been enlightening, exposing both strengths and areas for improvement. Embracing automated testing from the early stages is key to building a resilient and reliable software application. As development progresses, addressing the identified issues and continually expanding test coverage will be a priority for ensuring the long-term integrity of the project.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>beginners</category>
      <category>testing</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Enhancing Your Open-Source Project with Static Analysis Tools</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Fri, 03 Nov 2023 20:05:57 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/enhancing-your-open-source-project-with-static-analysis-tools-1hj2</link>
      <guid>https://dev.to/yousefmajidi/enhancing-your-open-source-project-with-static-analysis-tools-1hj2</guid>
      <description>&lt;p&gt;In the world of open-source development, improving the quality and accessibility of your project is of utmost importance. This week, I delved into the realm of static analysis tools to enhance my open-source project, &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog"&gt;Learn2Blog&lt;/a&gt;. In this blog post, I'll share my experiences and the steps I took to make my project more contributor-friendly, maintainable, and error-free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Establishing a Solid Foundation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Contribution Guide: A Roadmap for Collaborators
&lt;/h3&gt;

&lt;p&gt;One of the first steps I took was to add a &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/blob/main/CONTRIBUTING.md"&gt;contribution guide&lt;/a&gt; to my project. This document serves as a roadmap for potential collaborators, outlining the process of contributing to the project. It's essential to separate this guide from the README.md file to provide a clear, dedicated resource for contributors. This ensures that everyone is on the same page when it comes to making contributions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code of Conduct: Fostering a Welcoming Environment
&lt;/h3&gt;

&lt;p&gt;To promote a positive and inclusive community around my project, I included a &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/blob/main/CODE_OF_CONDUCT.md"&gt;code of conduct&lt;/a&gt;. This document sets the expectations for behaviour within the project, emphasizing respect and collaboration. A clear code of conduct is vital to create a welcoming and productive environment for all contributors.&lt;/p&gt;

&lt;p&gt;I used bttger's &lt;a href="https://bttger.github.io/contributing-gen-web/"&gt;Contributing-Gen-Web&lt;/a&gt; tool to generate both the contribution guide and the code of conduct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting and Style Matters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Leveraging &lt;code&gt;.editorconfig&lt;/code&gt; for Consistency
&lt;/h3&gt;

&lt;p&gt;In my project, I incorporated a source code &lt;a href="https://github.com/dotnet/format"&gt;formatter&lt;/a&gt; provided by the dotnet framework. I also added &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/blob/main/.editorconfig"&gt;&lt;code&gt;.editorconfig&lt;/code&gt;&lt;/a&gt; file to the root directory of my project. This file defines formatting rules, such as &lt;code&gt;indent style&lt;/code&gt; and &lt;code&gt;indent size&lt;/code&gt;, ensuring consistency throughout the codebase. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.editorconfig&lt;/code&gt; file's rules help maintain a clean and organized codebase, making it easier for contributors to work together cohesively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streamlined Tasks with Visual Studio Code
&lt;/h3&gt;

&lt;p&gt;To simplify tasks for contributors, I updated the &lt;code&gt;task.json&lt;/code&gt; file, a part of the Visual Studio Code generated files. This file contains custom-defined &lt;a href="https://code.visualstudio.com/docs/editor/tasks"&gt;tasks&lt;/a&gt; that users can execute easily through the &lt;code&gt;Command Palette&lt;/code&gt;. Additionally, contributors can run the format command via the command line interface (CLI). These instructions within the &lt;code&gt;CONTRIBUTING.md&lt;/code&gt; file make it convenient for both experienced and novice contributors to participate effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping Code in Check
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Introduction to StyleCopAnalyzer
&lt;/h3&gt;

&lt;p&gt;For code quality and style enforcement, I integrated StyleCopAnalyzer from &lt;a href="https://github.com/DotNetAnalyzers/StyleCopAnalyzers"&gt;DotNetAnalyzers&lt;/a&gt;. This analyzer helps maintain code consistency and readability. It automatically checks the code every time you build the application.&lt;/p&gt;

&lt;p&gt;I created a &lt;a href="https://github.com/DotNetAnalyzers/StyleCopAnalyzers"&gt;&lt;code&gt;StyleCopAnalysers.ruleset&lt;/code&gt;&lt;/a&gt; file at the root of my project, which contains the ruleset for analysis. The tool not only identifies issues but also attempts to fix them, providing a log of any unresolved problems. In addition to running the analyzer upon build, the &lt;code&gt;dotnet format&lt;/code&gt; command also runs any external analyzers that it detects by default as well. &lt;/p&gt;

&lt;h3&gt;
  
  
  Customizing StyleCopAnalyzer
&lt;/h3&gt;

&lt;p&gt;While StyleCopAnalyzer offers valuable insights, it's important to adapt it to your project's specific needs. Style choices can be highly individual, and in my case, I modified the parameters to align with my personal preferences. For instance, I temporarily turned off the flag for the lack of documentation, with plans to address it later. The flexibility of this tool allows you to tailor it to your project's requirements easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing It All Together
&lt;/h2&gt;

&lt;p&gt;After making these improvements, I consolidated all my commits into a single one and merged the branch with the &lt;code&gt;main&lt;/code&gt; branch. The use of static analysis tools not only enhanced my project but also streamlined the contribution process and improved the overall quality.&lt;/p&gt;

&lt;p&gt;In conclusion, integrating static analysis tools can significantly benefit your open-source project. These tools help maintain consistency, enhance code quality, and foster a welcoming community of contributors. By following these steps, I've made Learn2Blog a more robust and accessible project. I encourage you to explore these tools and adapt them to your open-source endeavours, as the journey of open-source development is all about continuous improvement and collaboration.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>csharp</category>
      <category>beginners</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Hacktoberfest 2023: Recap</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Fri, 27 Oct 2023 19:01:29 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/hacktoberfest-2023-recap-3egj</link>
      <guid>https://dev.to/yousefmajidi/hacktoberfest-2023-recap-3egj</guid>
      <description>&lt;p&gt;As October comes to a close, so does my journey through &lt;a href="https://hacktoberfest.com"&gt;Hacktoberfest&lt;/a&gt;, a month-long celebration of open-source contributions. This year marked my first foray into this exciting world of collaborative coding, and I'm here to share the experiences and lessons learned during this remarkable journey. I'll be recapping my four-week progress through the lens of the blog posts I've written along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 1: Finding the Right Project
&lt;/h2&gt;

&lt;p&gt;In my first blog post, &lt;a href="https://dev.to/yousefmajidi/good-first-issue-3fg2"&gt;"Hacktoberfest: Good First Issue,"&lt;/a&gt; I shared my initial steps into the world of open source. Finding the right project to contribute to can be a daunting task, but I outlined various strategies for identifying suitable projects and issues to work on. I also emphasized the importance of understanding the project's guidelines and the value of contributing to documentation tasks.&lt;/p&gt;

&lt;p&gt;For my first contribution, I stumbled upon &lt;a href="https://github.com/kurnakovv/EnumConverter"&gt;EnumConverter&lt;/a&gt; and fixed an issue in their documentation. Despite a minor misunderstanding in the initial pull request, the open-source community proved to be incredibly helpful and friendly. This first step boosted my confidence and set the stage for more significant contributions in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 2: Beyond Code Contributions
&lt;/h2&gt;

&lt;p&gt;In the second week, I continued my journey and explored the non-coding aspects of open source. In &lt;a href="https://dev.to/yousefmajidi/hacktoberfest-week-2-41jh"&gt;"Hacktoberfest: Week 2,"&lt;/a&gt; I discussed the importance of understanding and adhering to project-specific guidelines, even for non-coding tasks. I shared my experience with enhancing podcast transcripts for &lt;a href="https://open.spotify.com/show/2wz1OneBIDXpbBYeuyIsJL?si=87d9a5f3a4694eb3"&gt;Software Engineering Unlocked&lt;/a&gt;, a podcast by &lt;a href="https://twitter.com/mgreiler"&gt;Michaela Greiler&lt;/a&gt;. This contribution involved improving the clarity and readability of podcast transcripts.&lt;/p&gt;

&lt;p&gt;The collaborative nature of open source became evident as I collaborated with the podcast's author to clarify various aspects of the transcripts. This taught me that open-source contributions come in various forms, and all forms of contributions are valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 3: Adding Value to Explore-cli
&lt;/h2&gt;

&lt;p&gt;Week 3 of Hacktoberfest presented a unique opportunity to contribute to &lt;a href="https://github.com/SmartBear-DevRel/explore-cli"&gt;explore-cli&lt;/a&gt;, a command-line tool for SwaggerHub Explore, an essential tool for API professionals. I focused on enhancing the &lt;code&gt;ExportedAt&lt;/code&gt; attribute within the codebase. The journey taught me about the collaborative spirit of open source, even when maintainers are actively involved in the project. External contributors can bring fresh perspectives and innovative solutions. I documented my contributions in depth in my previous post, &lt;a href="https://dev.to/yousefmajidi/hacking-away-in-week-3-of-hacktoberfest-o2m"&gt;"Hacking Away in Week 3 of Hacktoberfest."&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My contributions to &lt;code&gt;explore-cli&lt;/code&gt; emphasized the importance of code quality and consistency. This experience reminded me that every contribution, whether small or significant, adds value to the open-source landscape.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 4: Wrapping up with CrispyWaffle
&lt;/h2&gt;

&lt;p&gt;As the final week of Hacktoberfest approached, I delved into &lt;a href="https://github.com/guibranco/CrispyWaffle"&gt;CrispyWaffle&lt;/a&gt;, a toolkit for .NET projects. My contributions included code refactoring, removing unnecessary retry loops, and simplifying code logic. The experience was both rewarding and educational, emphasizing the significance of improving code quality. My post &lt;a href="https://dev.to/yousefmajidi/last-week-of-hacktoberfest-4538"&gt;"Last Week of Hacktoberfest"&lt;/a&gt; outlines my journey. &lt;/p&gt;

&lt;p&gt;My contributions to CrispyWaffle were quickly accepted by the project's maintainers, underscoring the collaborative nature of open source. This journey has been a testament to the power of community and the impact that small changes can make.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Hacktoberfest 2023 has been a remarkable journey. It began with finding the right project, expanded into non-code contributions, and then led me to explore various codebase improvements. Through it all, I learned that open-source contributions come in many forms, each valuable in its own right.&lt;/p&gt;

&lt;p&gt;Open source is not just about code; it's about community, collaboration, and the collective effort to improve technology. As this year's Hacktoberfest comes to a close, I'm eager to continue my journey in the open-source community, armed with the knowledge and experience gained during this exciting month. I look forward to more contributions, more collaboration, and more positive impact in the world of open source.&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>hacktoberfest23</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Last Week of Hacktoberfest</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Fri, 27 Oct 2023 18:42:02 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/last-week-of-hacktoberfest-4538</link>
      <guid>https://dev.to/yousefmajidi/last-week-of-hacktoberfest-4538</guid>
      <description>&lt;p&gt;As the last week of Hacktoberfest comes to a close, I'm thrilled to share my recent contributions to the open-source community, particularly to the CrispyWaffle project, a toolkit for .NET projects. In this blog, I'll recount my journey and the changes I made to improve the project. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;I kicked off my Hacktoberfest contributions by diving into &lt;a href="https://github.com/guibranco/CrispyWaffle"&gt;CrispyWaffle&lt;/a&gt;, a project that caught my attention due to its importance in the .NET ecosystem. The maintainers had an open &lt;a href="https://github.com/guibranco/CrispyWaffle/issues/211"&gt;issue #211&lt;/a&gt;, which required assistance in removing a retry check within one of their classes. After discussing the changes and receiving their initial approval, they encouraged me to seek additional areas for improvement within the codebase. Eager to make a positive impact, I accepted the challenge.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code Refactoring
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Removing the Retry Rule in &lt;code&gt;FtpClient.cs&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The first issue to tackle was in the &lt;code&gt;FtpClient.cs&lt;/code&gt; file, This class used a while loop to manage retry attempts. Here's a comparison between the old and new code:&lt;/p&gt;

&lt;h4&gt;
  
  
  Old Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CreateInternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;attempts&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// ... (rest of the code)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FtpClientException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPathOrFileName&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  New Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CreateInternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ... (rest of the code)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FtpClientException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPathOrFileName&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; The old code used a &lt;code&gt;while(true)&lt;/code&gt; loop for retry attempts, which is generally not a good practice. It also included a counter (&lt;code&gt;attempts&lt;/code&gt;) to track the number of retries and a subsequent &lt;code&gt;if&lt;/code&gt; statement to check if the maximum retry limit was reached. In the new code, I removed the loop and the unnecessary variables, simplifying the code and making it more readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Flipping &lt;code&gt;NOT&lt;/code&gt; Conditions
&lt;/h3&gt;

&lt;p&gt;In the original code, I noticed instances where conditions were negated, making them less intuitive. I proposed changing these &lt;code&gt;NOT&lt;/code&gt; conditions to a more straightforward format:&lt;/p&gt;

&lt;h4&gt;
  
  
  Old Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileExtension&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetFileSize&lt;/span&gt;
                    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListDirectory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  New Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileExtension&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListDirectory&lt;/span&gt;
                    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetFileSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; Writing code without negations is a better practice because it enhances code readability. The new code provides a more intuitive understanding of the logic, making it easier for other developers to follow.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Better Resource Handling in &lt;code&gt;ExistsInternal&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In the &lt;code&gt;ExistsInternal&lt;/code&gt; method, I found several areas where resource handling could be improved:&lt;/p&gt;

&lt;h4&gt;
  
  
  Old Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ExistsInternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;responseStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="k"&gt;try&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;LogConsumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
               &lt;span class="s"&gt;"Checking in FtpClient the path/file: {0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPathOrFileName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FtpWebRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;WebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Credentials&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NetworkCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileExtension&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
              &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetFileSize&lt;/span&gt;
              &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListDirectory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWriteTimeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;90000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UsePassive&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FtpWebResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="n"&gt;responseStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResponseStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseStream&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Response stream is null"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;responseStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EndOfStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;_files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadLine&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileExtension&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                   &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;FtpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileStatus&lt;/span&gt;
                   &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;FtpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpeningData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="k"&gt;finally&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;responseStream&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  New Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ExistsInternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;try&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;LogConsumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Checking in FtpClient the path/file: {0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPathOrFileName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FtpWebRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;WebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Credentials&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NetworkCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileExtension&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListDirectory&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebRequestMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ftp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetFileSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWriteTimeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;90000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UsePassive&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

          &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FtpWebResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;responseStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResponseStream&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EndOfStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                         &lt;span class="n"&gt;_files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadLine&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;

               &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileExtension&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;FtpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpeningData&lt;/span&gt;
                    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;FtpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileStatus&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;FtpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpeningData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; In the new code, I improved resource handling by using &lt;code&gt;using&lt;/code&gt; statements to ensure that resources are properly disposed of when they are no longer needed. Additionally, I removed the &lt;code&gt;result&lt;/code&gt; variable, simplifying the code and improving its clarity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;My Hacktoberfest journey has been both rewarding and educational. I've had the opportunity to contribute to the open-source community and make meaningful improvements to a valuable project. These changes not only enhance the project's functionality but also make it more accessible for other developers. &lt;/p&gt;

&lt;p&gt;As a final note, I'm thrilled to share that my contributions have already been merged into the CrispyWaffle project. You can check out my &lt;a href="https://github.com/guibranco/CrispyWaffle/pull/212"&gt;Pull Request&lt;/a&gt; and the final &lt;a href="https://github.com/guibranco/CrispyWaffle/commit/8065aaf2b7a8192c21af36df3a5bd54e5a57460e"&gt;merge commit&lt;/a&gt;. The CrispyWaffle team immediately approved and merged my proposed changes without any further change requests, underlining the collaborative spirit of the open-source community. As Hacktoberfest comes to an end, I look forward to more open-source contributions in the future.&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>refactorit</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Hacking Away in Week 3 of Hacktoberfest</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Fri, 20 Oct 2023 12:28:22 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/hacking-away-in-week-3-of-hacktoberfest-o2m</link>
      <guid>https://dev.to/yousefmajidi/hacking-away-in-week-3-of-hacktoberfest-o2m</guid>
      <description>&lt;p&gt;Week 3 of this annual event brought a unique opportunity to contribute to &lt;a href="https://github.com/SmartBear-DevRel/explore-cli"&gt;&lt;strong&gt;explore-cli&lt;/strong&gt;&lt;/a&gt;, a nifty utility CLI designed to facilitate data import and export in SwaggerHub Explore, an integral tool for API professionals. If you're not yet familiar with SwaggerHub Explore, it's a powerful component of the SwaggerHub platform, that streamlines data management for API designers and developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issue: Elevating the &lt;code&gt;ExportedAt&lt;/code&gt; Attribute
&lt;/h2&gt;

&lt;p&gt;My contribution for this week was centred around a specific issue in the explore-cli repository. The issue, identified as &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/issues/8"&gt;Issue #8&lt;/a&gt;, revolved around enhancing the &lt;code&gt;ExportedAt&lt;/code&gt; attribute found in the &lt;code&gt;Program.cs&lt;/code&gt; file. Initially, this attribute contained only a timestamp representing time, neglecting to include the date.&lt;/p&gt;

&lt;p&gt;Here's a glimpse of the original code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// construct the export object&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ExportSpaces&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Info&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ExportedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToLongTimeString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;ExploreSpaces&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spacesToExport&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my quest to enhance this utility, I proposed a modification that incorporated both the date and time into the &lt;code&gt;ExportedAt&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ExportSpaces&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Info&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ExportedAt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"yyyy-MM-ddTHH:mm:ss.fffZ"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;ExploreSpaces&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spacesToExport&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adjustment introduced a standardized timestamp format, including both date and time, making it more informative and user-friendly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pull Request Journey
&lt;/h2&gt;

&lt;p&gt;Following the code modification, I promptly created a &lt;a href="https://github.com/SmartBear-DevRel/explore-cli/pull/12"&gt;pull request&lt;/a&gt; to merge these changes into the &lt;strong&gt;explore-cli&lt;/strong&gt; repository. An interesting twist occurred during this process. The maintainers decided to create their own &lt;a href="https://github.com/Yousef-Majidi/explore-cli/pull/1"&gt;pull request&lt;/a&gt; to my topic branch on the repository forked to &lt;a href="https://github.com/Yousef-Majidi/explore-cli"&gt;my GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This action essentially meant that they crafted the code to align with their precise requirements. Once I approved their pull request, their contributions seamlessly integrated into my initial pull request, a curious instance of a project's maintainers collaborating on their own project through an external contributor's repository. This raised an intriguing question: Why enlist external contributions when the project's maintainers are actively involved in the development process?&lt;/p&gt;

&lt;p&gt;This question often arises in open-source projects, and the answer lies in the diversity of perspectives and ideas that external contributors bring to the table. Even when maintainers are deeply involved, fresh insights from the community can lead to innovative solutions and foster a sense of community and collaboration. It's a testament to the inclusive nature of open-source, where different viewpoints can lead to enhanced project quality and efficiency. This collaborative spirit is what makes open-source development a dynamic and ever-evolving ecosystem.&lt;/p&gt;

&lt;p&gt;Nevertheless, this experience turned out to be highly educational for me. I took the opportunity to refine their code, aligning it with industry standards in terms of spacing, indentation, and overall formatting. It underscored the significance of code quality and consistency within the realm of open-source contributions.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Valuable Learning Experience
&lt;/h2&gt;

&lt;p&gt;My involvement in Hacktoberfest Week 3 wasn't just about code changes; it was also a valuable learning experience. While my solution effectively achieved the desired outcome, the approach suggested by the project's author in their &lt;a href="https://github.com/Yousef-Majidi/explore-cli/pull/1"&gt;pull request&lt;/a&gt; proved to be more efficient and concise.&lt;/p&gt;

&lt;p&gt;In conclusion, my journey in Hacktoberfest Week 3 was an enriching experience. It highlighted the collaborative nature of open-source development and emphasized the significance of maintaining code quality. Despite the occasional twist, it showcased the value of collective efforts, both in terms of code enhancement and learning opportunities. Open source truly offers a fascinating journey where each contribution, no matter how small or significant, adds value to the larger landscape of technology and innovation.&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>csharp</category>
      <category>cli</category>
    </item>
    <item>
      <title>Git Rebase: Learn2Blog Refactor</title>
      <dc:creator>Yousef</dc:creator>
      <pubDate>Sat, 14 Oct 2023 22:34:59 +0000</pubDate>
      <link>https://dev.to/yousefmajidi/git-rebase-learn2blog-refactor-i06</link>
      <guid>https://dev.to/yousefmajidi/git-rebase-learn2blog-refactor-i06</guid>
      <description>&lt;p&gt;This week, I embarked on a journey to enhance my ongoing open-source project, &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog"&gt;Learn2Blog&lt;/a&gt;. This is a command-line tool I developed to convert plain text and markdown files into HTML, making it a handy utility for bloggers and content creators. In this article, we'll explore the recent refactoring efforts undertaken to improve the codebase's maintainability, extensibility, and overall code quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Need for Refactoring
&lt;/h2&gt;

&lt;p&gt;Refactoring is a crucial practice in software development that involves restructuring and optimizing code without changing its external behaviour. The primary motivations behind the refactoring of Learn2Blog were as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modularity for Future Development&lt;/strong&gt;: The original code was functional but lacked the modularity required for future feature additions and maintenance. By refactoring, we aimed to make the codebase more extensible and easier to work with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code Quality&lt;/strong&gt;: Improving code quality not only makes the project more maintainable but also enhances its overall performance. This is crucial for an open-source project meant for public use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better Readability&lt;/strong&gt;: Code readability is essential for collaboration. By making the code more readable and organized, it becomes more accessible to potential contributors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bug Fixing&lt;/strong&gt;: Addressing longstanding bugs and issues to ensure a smoother user experience was another vital goal.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Refactoring: Step by Step
&lt;/h2&gt;

&lt;p&gt;Let's dive into the step-by-step process of refactoring Learn2Blog. We'll discuss the improvements made to the project's structure, as well as changes to the &lt;code&gt;FileProcessor&lt;/code&gt; class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improved Project Structure
&lt;/h3&gt;

&lt;p&gt;In the refactored code, we introduced a cleaner project structure to enhance organization and code separation. We created a &lt;code&gt;Learn2Blog.cs&lt;/code&gt; file, which serves as the entry point for the application. This centralization simplifies the entry point and makes it more cohesive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Learn2Blog&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;CommandLineOptions&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CommandLineParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseCommandLineArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CommandLineOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;InputPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowVersion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;CommandLineUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ShowVersion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowHelp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;CommandLineUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ShowHelp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;FileProcessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProcessFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This new structure facilitates ease of understanding and navigation, which is crucial when working on a collaborative, open-source project. Now, the &lt;code&gt;Main&lt;/code&gt; function in &lt;code&gt;Program.cs&lt;/code&gt; contains the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Learn2Blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  FileProcessor - Breaking Down the Complexity
&lt;/h3&gt;

&lt;p&gt;The most significant improvement during this refactoring process happened in the &lt;code&gt;FileProcessor&lt;/code&gt; class. This class is responsible for processing input files. In the original code, file processing logic was coupled with command-line argument parsing, creating a challenging codebase to manage.&lt;/p&gt;

&lt;p&gt;In the old code, the &lt;code&gt;FileProcessor&lt;/code&gt; class did not exist, and the file processing logic was scattered throughout the application. In the refactored code, the &lt;code&gt;FileProcessor&lt;/code&gt; class now separates file-processing logic and command-line argument parsing. This separation enhances the code's modularity and makes it easier to maintain and extend.&lt;/p&gt;

&lt;h4&gt;
  
  
  Handling Single File Processing
&lt;/h4&gt;

&lt;p&gt;One of the key changes in the refactored code is the introduction of the &lt;code&gt;ProcessFile&lt;/code&gt; method. This method is responsible for processing a single file. Here's how it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;".txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ProcessText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ProcessMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HtmlGenerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GenerateHtmlFromText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileNameWithoutExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;CommandLineUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Error processing file &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputFileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetUniqueOutputFileName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;SaveHtmlFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputFileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;CommandLineUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"File converted: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;outputFileName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ProcessFile&lt;/code&gt; method efficiently handles the conversion of individual input files. It identifies the file type, processes the content, generates HTML, and saves it with a unique filename to avoid overwriting existing files.&lt;/p&gt;

&lt;h4&gt;
  
  
  Processing Files in a Directory
&lt;/h4&gt;

&lt;p&gt;In the refactored code, we introduced the &lt;code&gt;ProcessFilesInDirectory&lt;/code&gt; method. This function is responsible for processing all files in a specified directory. Here's how it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessFilesInDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;inputDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputDirectory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*.txt"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*.md"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;CommandLineUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"No .txt or .md files found in directory &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inputDirectory&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;CommandLineUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateOutputDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputDirectory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;ProcessFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outputDirectory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ProcessFilesInDirectory&lt;/code&gt; method scans the specified directory for &lt;code&gt;.txt&lt;/code&gt; and &lt;code&gt;.md&lt;/code&gt; files, and then, for each file found, it calls the &lt;code&gt;ProcessFile&lt;/code&gt; method for individual file processing. This separation of responsibilities enhances code modularity and maintainability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ensuring Unique Output Filenames
&lt;/h4&gt;

&lt;p&gt;Another noteworthy addition in the refactored code is the &lt;code&gt;GetUniqueOutputFileName&lt;/code&gt; method. This method is responsible for generating a unique output filename when saving converted HTML files. This approach ensures that no files are inadvertently overwritten.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetUniqueOutputFileName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileNameWithoutExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputFileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;".html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fileNumber&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputFileName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;outputFileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fileNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;fileNumber&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;outputFileName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Improved HTML Generation
&lt;/h3&gt;

&lt;p&gt;In the refactored code, the HTML generation logic has been moved to a separate class called &lt;code&gt;HtmlGenerator&lt;/code&gt;. This separation enhances code modularity. Instead of calling &lt;code&gt;AppendLine&lt;/code&gt; repetitively, the &lt;code&gt;HtmlGenerator&lt;/code&gt; class generates the HTML content as a single string, which embeds both the title and body.&lt;/p&gt;

&lt;p&gt;Here's how the &lt;code&gt;HtmlGenerator&lt;/code&gt; class works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlGenerator&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GenerateHtmlFromText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$@"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach simplifies HTML generation, making the code more readable and maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Rebase for a Cleaner History
&lt;/h2&gt;

&lt;p&gt;Maintaining a clean and organized Git history is essential for open-source projects. During this refactoring process, I used Git's interactive rebase feature to squash and clean up my commit history. This approach ensures that the project's history is coherent and easier to review for potential contributors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git rebase main &lt;span class="nt"&gt;-i&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also recommend using the &lt;a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens"&gt;GitLens&lt;/a&gt; extension for Visual Studio Code, which provides a convenient GUI for Git rebase operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rigorous Testing
&lt;/h2&gt;

&lt;p&gt;Throughout the refactoring process, I performed rigorous testing to ensure that all existing functionalities were preserved as intended. This included manual testing only, as I have not developed a unit tester for this application yet. But that will be coming in the next few weeks, so stay tuned! By running tests at each refactoring step, I could quickly identify and rectify any issues and bugs before moving on to the next phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Few Bumps in the Road
&lt;/h2&gt;

&lt;p&gt;As with any significant code refactoring, some issues surfaced along the way. But in this case, nothing major. There was a minor hiccup with my &lt;code&gt;.gitconfig&lt;/code&gt; file, which was not correctly linked to my external editor. After resolving this issue and correctly linking Visual Studio Code as my external editor, the rebase process proceeded smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Final Commit
&lt;/h2&gt;

&lt;p&gt;After completing the refactor, I squashed all 14 commits into a single one to create a clean and cohesive history. Using &lt;code&gt;git commit --amend&lt;/code&gt;, I updated the commit message for this final commit, and then I merged it into the main branch and pushed the changes to GitHub. The final commit can be reviewed &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/commit/40d6904516ceece10e0b343c37104e9a95c05c97"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also pushed all the changes made during the refactor to a dedicated branch called &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/tree/refactor"&gt;refactor&lt;/a&gt;. This branch contains the entire &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog/compare/main...refactor"&gt;commit history&lt;/a&gt; related to this refactoring effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Code refactoring is a vital part of maintaining a healthy open-source project. It improves code quality, enhances modularity, and makes the project more inviting to contributors. By following best practices and rigorous testing, we can ensure that existing functionalities remain intact while improving the codebase.&lt;/p&gt;

&lt;p&gt;In the case of Learn2Blog, this refactoring effort has laid the groundwork for future enhancements and a more user-friendly experience. If you're interested in contributing to this project or exploring the changes in detail, please check out the &lt;a href="https://github.com/Yousef-Majidi/Learn2Blog"&gt;Learn2Blog repository on GitHub&lt;/a&gt;. Your contributions are always welcome!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>csharp</category>
      <category>git</category>
      <category>refactorit</category>
    </item>
  </channel>
</rss>
