FLOSS Project Planets

Specbee: How to Write Your First Test Case Using PHPUnit & Kernel in Drupal

Planet Drupal - Tue, 2024-04-02 04:07
Are you able to imagine a world where your code functions flawlessly, your bugs are scared of your testing routine and your users can enjoy a seamless experience - free from crashes and errors? Well, this only means that you understand the importance of automated testing.  With automated testing, Drupal developers can elevate the code quality, streamline workflows, and fortify digital ecosystems against errors and bugs. Drupal offers 4 types of PHPUnit tests: Unit, Kernel, Functional, and Functional Javascript. In this blog post, we'll explore PHPUnit tests and Kernel tests. Setting Up PHPUnit in Drupal For setting up PHPUnit in Drupal, the recommended method by Drupal is composer-based: $ composer require --dev phpunit/phpunit --with-dependencies $ composer require behat/mink && composer require --dev phpspec/prophecy(Note  -  PHPUnit version 11 requires PHP 8.2, This blog is written for Drupal 10 and PHP 8.1)Once PHPUnit and its dependencies are installed, the next step involves creating and configuring the phpunit.xml file. Locate the phpunit.xml.dist file in the core folder of Drupal installation. Copy and paste this file into the docroot directory and rename it to phpunit.xml (it is recommended to keep the file in docroot directory instead of core so that it won't get affected by core updates). Create simpletest and browser_output directories. In order to run tests like Kernel and Functional we need to create these two directories and set the permissions to writable $ mkdir -p docroot/sites/simpletest/browser_output && chmod -R 777 docroot/sites/simpletestTo run the test locally, we need to configure some values in phpunit.xml e.g, Change 1 - <env name="SIMPLETEST_BASE_URL" value="" /> to <env name="SIMPLETEST_BASE_URL" value="https://yoursiteurl.com" /> 2 - <env name="SIMPLETEST_DB" value="" /> to <env name="SIMPLETEST_DB" value="mysql://username:password@yourdbhost/databasename" /> 3 - <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="" /> to <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="fullpath/docroot/sites/simpletest/browser_output" /> (Note - To check the full path of your app run from project root) $ pwdSetting Up PHPUnit with Lando If you want to run your test from lando you’ll need to configure .lando.yml file. We’ll leave the defaults for most of the values in the phpunit.xml file except for where to find the bootstrap.php file. This should be changed to the path in the Lando container, which will be /app/web/core/tests/bootstrap.php. This can be done with sed: $ sed -i 's|tests\/bootstrap\.php|/app/web/core/tests/bootstrap.php|g' phpunit.xml Next, edit the .lando.yml file and add the following: services:  appserver:    overrides:      environment:        SIMPLETEST_BASE_URL: "http://mysite.lndo.site"        SIMPLETEST_DB: "mysql://database:database@database/database"        MINK_DRIVER_ARGS_WEBDRIVER: '["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu","--headless"]}}, "http://chrome:9515"]'  chrome:    type: compose    services:      image: drupalci/webdriver-chromedriver:production      command: chromedriver --log-path=/tmp/chromedriver.log --verbose --whitelisted-ips= tooling:  test:    service: appserver    cmd: "php /app/vendor/bin/phpunit -c /app/phpunit.xml"Modify SIMPLETEST_BASE_URL and SIMPLETEST_DB to point to your lando site and database credentials as needed.This does three things: Adds environment variables to the appserver container (the one we’ll run the tests in). Adds a new container for the chromedriver image which is used for running headless javascript tests (more on that later). A tooling section that adds a test command to Lando to run our tests. Important!After updating the .lando.yml file we need to rebuild the containers with the following:$ lando rebuild -yLets run a single test with lando $ lando test core/modules/datetime/tests/src/Unit/Plugin/migrate/field/DateFiedTest.phpWithout Lando — Verify the tests are working by running core test.(Note — I keep my phpunit.xml file in docroot folder and will be running test from docroot directory.)$ ../vendor/bin/phpunit -c core core/modules/datetime/tests/src/Unit/Plugin/migrate/field/DateFiedTest.php What is a PHPUnit Test PHPUnit tests are utilized to test small blocks of code and functionalities that do not necessitate a complete Drupal installation. These tests allow us to evaluate the functionality of a class within the Drupal environment, encompassing aspects like Database, Settings, etc. Moreover, they do not require a web browser, as the Drupal environment can be substituted by a "mock" object. Before writing unit tests, we should remember the following things: Base Class — \Drupal\Tests\UnitTestCaseTo implement a unit test case we need to extend our test class with the base classNamespace — \Drupal\Tests\mymodule\Unit (or subdirectory)We need to specify a namespace for our testDirectory location — mymodule/tests/src/Unit (or subdirectory)To run the test, the test class must reside in the above-mentioned directory. Write Your First PHPUnit Test Step 1: Create a custom module Step 2: Create the event_example.info.yml file for the custom module name: Events Exampletype: moduledescription: Provides an example of subscribing to and dispatching events.package: Customcore_version_requirement: ^9.4 || ^10 Step 3: Create event_example.services.yml file services: # Give your service a unique name, convention is to prefix service names with # the name of the module that implements them. events_example_subscriber:  # Point to the class that will contain your implementation of  # \Symfony\Component\EventDispatcher\EventSubscriberInterface  class: Drupal\events_example\EventSubscriber\EventsExampleSubscriber  tags:  - {name: event_subscriber}Step 4: Create events_example/src/EventSubscriber/EvensExampleSubscriber.php file for our class. <?php namespace Drupal\events_example\EventSubscriber; use Drupal\events_example\Event\IncidentEvents; use Drupal\events_example\Event\IncidentReportEvent; use Drupal\Core\Messenger\MessengerTrait; use Drupal\Core\StringTranslation\StringTranslationTrait; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Subscribe to IncidentEvents::NEW_REPORT events and react to new reports. * * In this example we subscribe to all IncidentEvents::NEW_REPORT events and * point to two different methods to execute when the event is triggered. In * each method we have some custom logic that determines if we want to react to * the event by examining the event object, and the displaying a message to the * user indicating whether or not that method reacted to the event. * * By convention, classes subscribing to an event live in the * Drupal/{module_name}/EventSubscriber namespace. * * @ingroup events_example */ class EventsExampleSubscriber implements EventSubscriberInterface {  use StringTranslationTrait;  use MessengerTrait;  /**   * {@inheritdoc}   */  public static function getSubscribedEvents() {    // Return an array of events that you want to subscribe to mapped to the    // method on this class that you would like called whenever the event is    // triggered. A single class can subscribe to any number of events. For    // organization purposes it's a good idea to create a new class for each    // unique task/concept rather than just creating a catch-all class for all    // event subscriptions.    //    // See EventSubscriberInterface::getSubscribedEvents() for an explanation    // of the array's format.    //    // The array key is the name of the event your want to subscribe to. Best    // practice is to use the constant that represents the event as defined by    // the code responsible for dispatching the event. This way, if, for    // example, the string name of an event changes your code will continue to    // work. You can get a list of event constants for all events triggered by    // core here:    // https://api.drupal.org/api/drupal/core%21core.api.php/group/events/8.2.x.    //    // Since any module can define and trigger new events there may be    // additional events available in your application. Look for classes with    // the special @Event docblock indicator to discover other events.    //    // For each event key define an array of arrays composed of the method names    // to call and optional priorities. The method name here refers to a method    // on this class to call whenever the event is triggered.    $events[IncidentEvents::NEW_REPORT][] = ['notifyMario'];    // Subscribers can optionally set a priority. If more than one subscriber is    // listening to an event when it is triggered they will be executed in order    // of priority. If no priority is set the default is 0.    $events[IncidentEvents::NEW_REPORT][] = ['notifyBatman', -100];    // We'll set an event listener with a very low priority to catch incident    // types not yet defined. In practice, this will be the 'cat' incident.    $events[IncidentEvents::NEW_REPORT][] = ['notifyDefault', -255];    return $events;  }  /**   * If this incident is about a missing princess, notify Mario.   *   * Per our configuration above, this method is called whenever the   * IncidentEvents::NEW_REPORT event is dispatched. This method is where you   * place any custom logic that you want to perform when the specific event is   * triggered.   *   * These responder methods receive an event object as their argument. The   * event object is usually, but not always, specific to the event being   * triggered and contains data about application state and configuration   * relative to what was happening when the event was triggered.   *   * For example, when responding to an event triggered by saving a   * configuration change you'll get an event object that contains the relevant   * configuration object.   *   * @param \Drupal\events_example\Event\IncidentReportEvent $event   *   The event object containing the incident report.   */  public function notifyMario(IncidentReportEvent $event) {    // You can use the event object to access information about the event passed    // along by the event dispatcher.    if ($event->getType() == 'stolen_princess') {      $this->messenger()->addStatus($this->t('Mario has been alerted. Thank you. This message was set by an event subscriber. See @method()', ['@method' => __METHOD__]));      // Optionally use the event object to stop propagation.      // If there are other subscribers that have not been called yet this will      // cause them to be skipped.      $event->stopPropagation();    }  }  /**   * Let Batman know about any events involving the Joker.   *   * @param \Drupal\events_example\Event\IncidentReportEvent $event   *   The event object containing the incident report.   */  public function notifyBatman(IncidentReportEvent $event) {    if ($event->getType() == 'joker') {      $this->messenger()->addStatus($this->t('Batman has been alerted. Thank you. This message was set by an event subscriber. See @method()', ['@method' => __METHOD__]));      $event->stopPropagation();    }  }  /**   * Handle incidents not handled by the other handlers.   *   * @param \Drupal\events_example\Event\IncidentReportEvent $event   *   The event object containing the incident report.   */  public function notifyDefault(IncidentReportEvent $event) {    $this->messenger()->addStatus($this->t('Thank you for reporting this incident. This message was set by an event subscriber. See @method()', ['@method' => __METHOD__]));    $event->stopPropagation();  }  /**   * @param $string String   *   Simple function to check string.   */  public function checkString($string) {    return $string ? TRUE : FALSE;  } }Step 5: Create tests/src/Unit/EventsExampleUnitTest.php file for our UnitTest <?php namespace Drupal\Tests\events_example\Unit; use Drupal\Tests\UnitTestCase; use Drupal\events_example\EventSubscriber\EventsExampleSubscriber; /** * Test events_example EventsExampleSubscriber functionality * * @group events_example * * @ingroup events_example */ class EventsExampleUnitTest extends UnitTestCase {    /**     * event_example EventsExampleSubscriber object.     *     * @var-object     */    protected $eventExampleSubscriber;    /**     * {@inheritdoc}     */     protected function setUp(): void {        $this->eventExampleSubscriber = new EventsExampleSubscriber();        parent::setUp();     }    /**     * Test simple function that returns true if string is present.     */    public function testHasString() {      $this->assertEqual(TRUE, $this->eventExampleSubscriber->checkString('Some String'));    }  }Important Notes: Test class name should start or end with “Test”. For example, EventsExampleUnitTest and it should extend with the base class UnitTestCase. Test function should start with “test”. For example, testHasString otherwise it will not be included in test run. Step 6: Let’s run our test! $ lando test modules/custom/events_example/tests/src/Unit/EventsExampleUnitTest.phpor$ ../vender/bin/phpunit -c core modules/custom/events_example/tests/src/Unit/EventsExampleUnitTest.php PHPUnit 9.6.17 by Sebastian Bergmann and contributors. Testing Drupal\Tests\events_example\Unit\EventsExampleUnitTest.                                                                   1 / 1 (100%) Time: 00:00.054, Memory: 10.00 MB OK (1 test, 1 assertion) Hooray! Our test has passed! Write Your First Kernel Test These tests necessitate specific Drupal environment dependencies, with no requirement for web browsers. They allow us to assess class functionality without the full Drupal setup or web browsers. However, certain Drupal environment dependencies are indispensable and cannot be easily mocked. Kernel tests are capable of accessing services, databases, and minimal file systems.Below are the essential prerequisites to consider when running kernel tests. Base Class — \Drupal\KernelTests\KernelTestBaseTo implement the Kernel test we need to extend our test class with the base classNamespace — \Drupal\Tests\mymodule\Kernel (or subdirectory)We need to specify a namespace for our testDirectory location — mymodule/tests/src/Kernel (or subdirectory)To run the test, the test class must reside in the above-mentioned directory.Create tests/src/Kernel/EventsExampleServiceTest.php file for our Kernel Test <?php namespace Drupal\Tests\events_example\Kernel; use Drupal\KernelTests\KernelTestBase; use Drupal\events_example\EventSubscriber\EventsExampleSubscriber; /** * Test to ensure 'events_example_subscriber' service is reachable. * * @group events_example * * @ingroup events_example */ class EventsExampleServiceTest extends KernelTestBase {  /**   * {@inheritdoc}   */  protected static $modules = ['events_example'];  /**   * Test for existence of 'events_example_subscriber' service.   */  public function testEventsExampleService() {    $subscriber = $this->container->get('events_example_subscriber');    $this->assertInstanceOf(EventsExampleSubscriber::class, $subscriber);  } }Important Notes: The test class name should start or end with “Test”, for example, EventsExampleServiceTest and it should extend with base class KernelTestBase.  The kernel test should include modules that have dependencies. For example , “$modules = [‘events_example’]” we can include other dependent modules here like “$modules = [‘events_example’, ‘user’, ‘field’]” . It acts like dependency injection. The test function should start with “test”, for example, testEventsExampleService otherwise it will not be included in the test run.Let's run our Kernel Test.$ lando test modules/custom/events_example/tests/src/Kernel/EventsExampleServiceTest.phpor$ ../vender/bin/phpunit -c core modules/custom/events_example/tests/src/Kernel/EventsExampleServiceTest.php PHPUnit 9.6.17 by Sebastian Bergmann and contributors. Testing Drupal\Tests\events_example\Kernel\EventsExampleServiceTest.                                                                   1 / 1 (100%) Time: 01:24.129, Memory: 10.00 MB OK (1 test, 1 assertion) Woohoo! Another successful test in the books! Final Thoughts What next after writing your first test case using PHPUnit and Kernel testing? Well, you can proceed to write more test cases to cover other functionalities or edge cases in your Drupal project. Additionally, you may want to consider integrating your test suite into a continuous integration(CI) pipeline to automate testing and ensure code quality throughout your development process.
Categories: FLOSS Project Planets

Python Bytes: #377 A Dramatic Episode

Planet Python - Tue, 2024-04-02 04:00
<strong>Topics covered in this episode:</strong><br> <ul> <li><a href="https://github.com/epogrebnyak/justpath"><strong>justpath</strong></a></li> <li><strong>xz back door</strong></li> <li><a href="https://lpython.org">LPython</a></li> <li><a href="https://github.com/treyhunner/dramatic"><strong>dramatic</strong></a></li> <li><strong>Extras</strong></li> <li><strong>Joke</strong></li> </ul><a href='https://www.youtube.com/watch?v=eWnYlxOREu4' style='font-weight: bold;'data-umami-event="Livestream-Past" data-umami-event-episode="377">Watch on YouTube</a><br> <p><strong>About the show</strong></p> <p>Sponsored by ScoutAPM: <a href="https://pythonbytes.fm/scout"><strong>pythonbytes.fm/scout</strong></a></p> <p><strong>Connect with the hosts</strong></p> <ul> <li>Michael: <a href="https://fosstodon.org/@mkennedy"><strong>@mkennedy@fosstodon.org</strong></a></li> <li>Brian: <a href="https://fosstodon.org/@brianokken"><strong>@brianokken@fosstodon.org</strong></a></li> <li>Show: <a href="https://fosstodon.org/@pythonbytes"><strong>@pythonbytes@fosstodon.org</strong></a></li> </ul> <p>Join us on YouTube at <a href="https://pythonbytes.fm/stream/live"><strong>pythonbytes.fm/live</strong></a> to be part of the audience. Usually Tuesdays at 11am PT. Older video versions available there too.</p> <p>Finally, if you want an artisanal, hand-crafted digest of every week of </p> <p>the show notes in email form? Add your name and email to <a href="https://pythonbytes.fm/friends-of-the-show">our friends of the show list</a>, we'll never share it.</p> <p><strong>Michael #1:</strong> <a href="https://github.com/epogrebnyak/justpath"><strong>justpath</strong></a></p> <ul> <li>Inspect and refine PATH environment variable on both Windows and Linux.</li> <li>Raw, count, duplicates, invalids, corrections, excellent stuff.</li> <li>Check out <a href="https://asciinema.org/a/642726">the video</a></li> </ul> <p><strong>Brian #2:</strong> <strong>xz back door</strong></p> <ul> <li>In case you kinda heard about this, but not really.</li> <li>Very short version: <ul> <li>A Microsoft engineer noticed a performance problem with ssh and tracked it to a particular version update of xz.</li> <li>Further investigations found a multi-year installation of a fairly complex back door into the xz by a new-ish contributor. But still contributing over several years. First commit in early 2022.</li> <li>The problem is caught. But if it had succeeded, it would have been bad.</li> <li>Part of the issue of how this happened is due to having one primary maintainer on a very widely used tool included in tons-o-Linux distributions.</li> </ul></li> <li>Some useful articles <ul> <li><a href="https://boehs.org/node/everything-i-know-about-the-xz-backdoor"><strong>Everything I Know About the XZ Backdoor</strong></a> - Evan Boehs - recommended read</li> </ul></li> <li>Don’t think your affected? Think again if you use homebrew, for example: <ul> <li><a href="https://micro.webology.dev/2024/03/29/update-and-upgrade.html"><strong>Update and upgrade Homebrew and</strong></a><a href="https://micro.webology.dev/2024/03/29/update-and-upgrade.html"> </a><a href="https://micro.webology.dev/2024/03/29/update-and-upgrade.html"><strong><code>xz</code></strong></a><a href="https://micro.webology.dev/2024/03/29/update-and-upgrade.html"> <strong>versions</strong></a></li> </ul></li> <li>Notes <ul> <li>Open source maintenance burnout is real</li> <li>Lots of open source projects are maintained by unpaid individuals for long periods of time.</li> <li>Multi-year sneakiness and social bullying is pretty hard to defend against.</li> <li>Handing off projects to another primary maintainer has to be doable. <ul> <li>But now I think we need better tools to vet contributors. </li> <li>Maybe? Or would that just suppress contributions?</li> </ul></li> </ul></li> <li>One option to help with burnout: <ul> <li>JGMM, Just Give Maintainers Money: <a href="https://blog.glyph.im/2024/03/software-needs-to-be-more-expensive.html"><strong>Software Needs To Be More Expensive</strong></a> - Glyph</li> </ul></li> </ul> <p><strong>Michael #3:</strong> <a href="https://lpython.org">LPython</a></p> <ul> <li>LPython aggressively optimizes type-annotated Python code. It has several backends, including LLVM, C, C++, and WASM. </li> <li>LPython’s primary tenet is speed.</li> <li>Play with the wasm version here: <a href="https://dev.lpython.org">dev.lpython.org</a></li> <li>Still in alpha, so keep that in mind.</li> </ul> <p><strong>Brian #4:</strong> <a href="https://github.com/treyhunner/dramatic"><strong>dramatic</strong></a></p> <ul> <li>Trey Hunner</li> <li>More drama in the software world. This time in the Python. </li> <li>Actually, this is just a fun utility to make your Python output more dramatic.</li> <li>More fun output with <a href="https://github.com/ChrisBuilds/terminaltexteffects">terminaltexteffects</a> <ul> <li>suggested by Allan</li> </ul></li> </ul> <p><strong>Extras</strong> </p> <p>Brian:</p> <ul> <li><a href="https://github.com/Textualize/textual/releases/tag/v0.55.0">Textual how has a new inline feature in the new release.</a></li> </ul> <p>Michael:</p> <ul> <li>My keynote talk is out: <a href="https://www.youtube.com/watch?v=coz1CGRxjQ0">The State of Python in 2024</a></li> <li>Have you browsed your <a href="https://github.com">github feed</a> lately?</li> <li><a href="https://pythoninsider.blogspot.com/2024/03/python-31014-3919-and-3819-is-now.html">3.10, 3.9, 3.8 security updates</a></li> </ul> <p><strong>Joke:</strong> <a href="https://python-bytes-static.nyc3.digitaloceanspaces.com/definition-of-methodolgy-terms.jpg">Definition of terms</a></p>
Categories: FLOSS Project Planets

Python Software Foundation: New Open Initiative for Cybersecurity Standards

Planet Python - Mon, 2024-04-01 23:00

The Python Software Foundation is pleased to announce our participation in co-starting a new Open Initiative for Cybersecurity Standards collaboration with the Apache Software Foundation, the Eclipse Foundation, other code-hosting open source foundations, SMEs, industry players, and researchers. This collaboration is focused on meeting the real challenges of cybersecurity in the open source ecosystem, and demonstrating full cooperation with and supporting the implementation of the European Union’s Cyber Resilience Act (CRA). With our combined efforts, we are optimistic that we will reach our goal of establishing common specifications for secure open source development based on existing open source best practices. 

New regulations, such as those in the CRA, highlight the need for secure by design and strong supply chain security standards. The CRA will lead to standard requests from the Commission to the European Standards Organisations and we foresee requirements from the United States and other regions in the future. As open source foundations, we want to respond to these requests proactively by establishing common specifications for secure software development and meet the expectations of the newly defined term Open Source Steward. 

Open source communities and foundations, including the Python community, have long been practicing and documenting secure software development processes. The starting points for creating common specifications around security are already there, thanks to millions of contributions to hundreds of open source projects. In the true spirit of open source, we plan to learn from, adapt, and build upon what already exists for the collective betterment of our greater software ecosystem. 

The PSF’s Executive Director Deb Nicholson will attend and participate in the initial Open Initiative for Cybersecurity Standards meetings. Later on, various PSF staff members will join in relevant parts of the conversation to help guide the initiative alongside their peers. The PSF looks forward to more investment in cybersecurity best practices by Python and the industry overall. 

This community-driven initiative will have a lasting impact on the future of cybersecurity and our shared open source communities. We welcome you to join this collaborative effort to develop secure open source development specifications. Participate by sharing your knowledge, input, and raising up existing community contributions. Sign up for the Open Initiative for Process Specifications mailing list to get involved and stay updated on this initiative. Check out the press release's from the Eclipse Foundation’s and the Apache Software Foundation for more information.

Categories: FLOSS Project Planets

SoK 2024 - Implementing package management features from RKWard into Cantor via a GUI First Blog

Planet KDE - Mon, 2024-04-01 20:00
Introduction

Hi! I’m Krish, an undergraduate student at the University of Rochester studying Computer Science and this KDE Season of Code I’m working on implementing package management features from RKWard into Cantor via a GUI. I’m being mentored by Alexander Semke.

In an effort to improve usability and functionality, this project seeks to strengthen Cantor's capabilities as a scientific computing platform by incorporating package management tools modeled after those found in RKWard and RStudio. The goal is to create an intuitive graphical interface within Cantor for managing packages in R, Octave, Julia, and other languages.

Set up development environment for Cantor
  • Used virt-manager to setup an “Kubuntu” virtual machine
  • Installed dependencies for Cantor
  • Open a terminal emulator and in your favorite shell:
cd cantor mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/cantor/usr/local -DCMAKE_BUILD_TYPE=RELEASE make make install Digging into RKWard's package management system

RKWard, an open-source, cross-platform integrated development environment for the R programming language, implements package management using R's built-in package management system and provides a GUI to simplify package installation, updating, and removal. This writeup will discuss the technical aspects of package management in RKWard.

Broadly, RKWard leverages R's built-in package management functions, such as install.packages(), update.packages(), and remove.packages(), to handle package management tasks. These functions interact with R's package repository (CRAN by default) and local package libraries to perform package-related operations.

RKWard's package management GUI is built on top of these R functions, allowing users to perform package management tasks without directly interacting with the command-line interface. The GUI provides a more user-friendly experience and enables users to manage packages with just a few clicks.

When a user requests to install or update a package, RKWard performs the following technical steps:

  • Dependency resolution: RKWard checks for dependencies required by the package and resolves them using R's available.packages() and installed.packages() functions. If dependencies are not satisfied, RKWard prompts the user to install them automatically.
  • CMake Configuration: The FindR.cmake script is used during the compilation of RKWard to locate the R installation and its components, including the R library directory. This information is necessary for RKWard to interface with R and manage packages.
  • Package download and installation: RKWard downloads package source code or binary files from CRAN or other repositories using R's download.file() function. The packages are then installed using install.packages() with appropriate options, such as specifying the library directory and installing dependencies.
  • Package library management: RKWard installs packages in the R library directory, which is typically located in the user's home folder. The library directory can be configured in RKWard's settings. RKWard ensures that packages are installed in the correct library directory, depending on the user's R version and operating system.
  • Integration with R Console: RKWard includes an embedded R console, which allows users to see the output of package management commands and interact with them directly if needed. Error Handling: RKWard provides error messages and troubleshooting advice if package installation or loading fails. This can include issues like missing dependencies, compilation errors, or permissions problems.
  • Package loading: After installation, RKWard loads the package into the current R session using R's library() or require() functions, making its functions and datasets available for use.
  • RKWard supports package management on various platforms, including Windows, macOS, and Linux. On Windows and macOS, RKWard typically installs packages as pre-compiled binaries for improved performance and ease of installation. On Linux, RKWard installs packages from source, which may require additional development libraries or tools to be installed on the user's system.

RKWard also supports installing packages from local files, Git repositories, and other sources by providing options to specify custom package repositories or URLs. This flexibility allows users to manage their R packages according to their specific needs.

In summary, RKWard implements package management using R's built-in package management functions and provides a user-friendly GUI to simplify package installation, updating, and removal. By leveraging R's package management system, RKWard enables users to manage their R packages efficiently and effectively, regardless of their operating system or R version.

Next Steps
  • Begin implementing package management features in Cantor.
  • Focus on creating a consistent and user-friendly interface for package management.
Categories: FLOSS Project Planets

Hynek Schlawack: Python Project-Local Virtualenv Management Redux

Planet Python - Mon, 2024-04-01 20:00

One of my first TIL entries was about how you can imitate Node’s node_modules semantics in Python on UNIX-like operating systems. A lot has happened since then (to the better!) and it’s time for an update. direnv still rocks, though.

Categories: FLOSS Project Planets

The Drop Times: Drupal Page Builders—Part 3: Other Alternative Solutions

Planet Drupal - Mon, 2024-04-01 16:04
Venture into the realm of alternatives to Paragraphs and Layout Builder with the third installment of the Drupal Page Builder series by André Angelantoni, Senior Drupal Architect at HeroDevs, showcased on The DropTimes. This segment navigates through a variety of server-side rendered page generation solutions, offering a closer look at innovative modules that provide a broader range of page-building capabilities beyond Drupal's native tools. From the adaptability of Component Builder and the intuitive DXPR Page Builder to the cutting-edge HAX module utilizing W3C-standard web components, this article illuminates a path for developers seeking polished, ready-made components for their site builds. Before exploring advanced Drupal solutions, ensure you're caught up by reading the first two parts of the series, laying the groundwork for a comprehensive understanding of Drupal's extensive page-building ecosystem.
Categories: FLOSS Project Planets

The Drop Times: DrupalCamp Ouagadougou Concludes Successfully

Planet Drupal - Mon, 2024-04-01 16:04
Experience the highlights of DrupalCamp Ouagadougou! Dive into captivating pictures and relive the vibrant atmosphere of this successful event.
Categories: FLOSS Project Planets

Talking Drupal: Talking Drupal #444 - Design to Development Workflow Optimization

Planet Drupal - Mon, 2024-04-01 14:00

Today we are talking about design to development hand off, common complications, and ways to optimize your process with guest Crispin Bailey. We’ll also cover Office Hours as our module of the week.

For show notes visit: www.talkingDrupal.com/444

Topics
  • Primary activities of the team
  • Where does handoff start
  • Handoff artifact
  • Tools for collaboration
  • Figma
  • Evaluating new tools
  • Challenges of developers and designers working together
  • How can we optimize handoff
  • What steps can the dev team take to facilitate smooth handoff
  • Framework recommendation
  • Final quality
  • AI
Guests

Crispin Bailey - kalamuna.com crispinbailey

Hosts

Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Anna Mykhailova - kalamuna.com amykhailova

MOTW Correspondent

Martin Anderson-Clutz - mandclu

  • Brief description:
    • Have you ever wanted to manage and display the hours of operation for a business on your Drupal site? There’s a module for that
  • Module name/project name:
  • Brief history
    • How old: created in Jan 2008 by Ozeuss, though recent releases are by John Voskuilen of the Netherlands
    • Versions available: 7.x-1.11 and 8.x-1.17
  • Maintainership
    • Actively maintained, latest release was 3 weeks ago
    • Security coverage
    • Test coverage
    • Documentation: no user guide, but a pretty extensive README
    • Number of open issues: 15 open issues, only 1 of which are bugs against the current branch, though it’s postponed for more info
  • Usage stats:
    • Almost 20,000 sites
  • Module features and usage
    • Previously covered in episode 113, more than 8 years ago, in the “Drupal 6 end of life” episode
    • The module provides a specialized widget to set the hours for each weekday, with the option to have more than one time slot per day
    • You can define exceptions, for example on stat holidays
    • You can also define seasons, with a start and end date, during which the hours are different
    • The module also offers a variety of options for formatting the output:
    • You can show days as ranges, for example Monday to Friday, 9am to 5pm, 12-hour or 24-hour clocks, and so on
    • Obviously it will show any exceptions or upcoming seasonal hours too
    • It can also show an “open now” or “closed now” indicator
    • It can create schema.org-compliant markup for openingHours, and has integration with the Schema.org Metatag module
    • Office Hours does all this with a new field type, so you could add it to Stores in a Drupal Commerce site, a Locations content type in a site for a bricks-and-mortar chain, or if you just need a single set of hours for the site, you should be able to use it with something like the Config Pages module
    • The README file also includes some suggestions on how to use Office Hours with Views, which can give you a lot of flexibility on where and how to show the information
   
Categories: FLOSS Project Planets

The Drop Times: The Power of Embracing New Challenges and Technologies

Planet Drupal - Mon, 2024-04-01 13:04

“The greater the obstacle, the more glory in overcoming it.” – Molière


Dear Readers,

Stepping out of our comfort zones is undoubtedly a daunting task. Yet, it's precisely this leap into the unknown that often leads to remarkable growth and self-discovery. Embracing new challenges and learning from scratch can feel overwhelming at first, but through these experiences, we truly push our limits and uncover our hidden capabilities.

In our journey of embracing the unfamiliar, we expand our skill sets and gain a deeper understanding of ourselves and the paths we never thought possible. Each new challenge becomes an opportunity to stretch beyond what we thought we were capable of, illuminating uncharted territories of potential and opportunity.

Embrace the technological diversity surrounding us, as it serves as a rich tapestry of tools and methodologies that can enhance our creativity, efficiency, and impact in ways we've only begun to explore. Like the inspiring journey of Tanay Sai, a seasoned builder, engineering leader, and AI/ML practitioner who recently embarked on a transformative adventure beyond the familiar horizons of Drupal. Tanay's story is a testament to the idea that stepping out of one's comfort zone can lead to groundbreaking achievements and a deeper understanding of the multifaceted digital ecosystem.

The importance of continuous learning and the willingness to embrace new challenges is profound. It encourages us to look beyond the familiar, to experiment with emerging technologies, and to remain adaptable in our pursuit of delivering exceptional digital experiences.

Now, Let's take a moment to revisit the highlights from last week's coverage at The Drop Times.

Last month, we celebrated the Women in Drupal community and released the second part of "Inspiring Inclusion: Celebrating the Women in Drupal | #2" penned by Alka Elizabeth. Part 3 of this series will be coming soon.

Explore the dynamic evolution of Drupal's page-building features in Part 2 of André Angelantoni's latest series on The Drop Times. Each module discussed extends Layout Builder and can be integrated individually. Part 3 might already be released by the time this newsletter comes your way. Access the second part here.

DrupalCon Portland 2024, scheduled from May 6 to 9, will feature an empowering Women in Drupal Lunch event. This gathering aims to uplift female attendees and inspire and support women within the Drupal community. Learn more here.

Save the dates for DrupalCamp Spain 2024 in Benidorm! The event is scheduled for October 25 and 26, with the venue to be announced soon. Additionally, mark your calendars for October 24, designated as Business Day.

DrupalCamp Belgium has unveiled the keynote speakers for its highly anticipated 2024 edition in Ghent. For more information and to discover the lineup of keynote speakers, be sure to check out the details here. A complete list of events for the week is available here. Additionally, Gander Documentation is now available on Drupal.org, as announced by Janez Urevc, Tag1 Consulting's Strategic Growth and Innovation Manager, on March 25, 2024.

Also, read about Tanay Sai, an accomplished builder, engineering leader, and AI/ML practitioner who shares insights into his transformative journey beyond Drupal. After a decade immersed in the Drupal realm, Tanay candidly expresses his pivotal decision to venture beyond its confines. Learn more here.

Monika Branicka of Droptica conducts a comprehensive analysis of content management systems (CMS) employed by 314 higher education institutions in Poland. This study aims to unveil the prevalent CMS preferences among both public and non-public universities, providing insights into the educational sector's technological landscape. The report comes amidst a growing call for resources to track Drupal usage across industry sectors, coinciding with similar studies conducted by The DropTimes and Grzegorz Pietrzak.

DevBranch has announced the launch of a Drupal BootCamp tailored for aspiring web developers. This initiative aims to equip individuals with the necessary skills and knowledge to excel in web development using Drupal. For further details, click here.

The development of Drupal 11 has reached a critical phase, marked by ongoing updates to its system requirements within the development branch. Gábor Hojtsy has provided valuable insights on preparing core developers and informing the community about these changes. Stay updated on the latest developments as Drupal 11 evolves to meet the needs of its users and developers.

We acknowledge that there are more stories to share. However, due to selection constraints, we must pause further exploration for now.

To get timely updates, follow us on LinkedIn, Twitter and Facebook. Also, join us on Drupal Slack at #thedroptimes.

Thank you,
Sincerely
Elma John
Sub-editor, TheDropTimes.

Categories: FLOSS Project Planets

Luke Plant: Enforcing conventions in Django projects with introspection

Planet Python - Mon, 2024-04-01 11:05

Naming conventions can make a big difference to the maintenance issues in software projects. This post is about how we can use the great introspection capabilities in Python to help enforce naming conventions in Django projects.

Contents

Let’s start with an example problem and the naming convention we’re going to use to solve it. There are many other applications of the techniques here, but it helps to have something concrete.

The problem: DateTime and DateTimeField confusion

Over several projects I’ve found that inconsistent or bad naming of DateField and DateTimeField fields can cause various problems.

First, poor naming means that you can confuse them for each other, and this can easily trip you up. In Python, datetime is a subclass of date, so if you use a field called created_date assuming it holds a date when it actually holds a datetime, it might be not obvious initially that you are mishandling the value, but you’ll often have subtle problems down the line.

Second, sometimes you have a field named like expired which is actually the timestamp of when the record expired, but it could easily be confused for a boolean field.

Third, not having a strong convention, or having multiple conventions, leads to unnecessary time wasted on decisions that could have been made once.

Finally, inconsistency in naming is just confusing and ugly for developers, and often for users further down the line, because names tend to leak.

Even if you do have an established convention, it’s possible for people not to know. It’s also very easy for people to change a field’s type between date and datetime without also changing the name. So merely having the convention is not enough, it needs to be enforced.

Note

If you want to change the name and type of a field (or any other atribute), and want the data to preserve data as much as possible, you usually need to do it in two stages or more depending on your needs, and always check the migrations created – otherwise Django’s migration framework will just see one field removed and a completely different one added, and generate migrations that will destroy your data.

For this specific example, the convention I quite like is:

  • field names should end with _at for timestamp fields that use DateTimeField, like expires_at or deleted_at.

  • field names should end with _on or _date for fields that use DateField, like issued_on or birth_date.

This is based on the English grammar rule that we use “on” for dates but “at” for times – “on the 25th March”, but “at 7:00 pm” – and conveniently it also needs very few letters and tends to read well in code. The _date suffix is also helpful in various contexts where _on seems very unnatural. You might want different conventions, of course.

To get our convention to be enforced with automated checks we need a few tools.

The tools Introspection

Introspection means the ability to use code to inspect code, and typically we’re talking about doing this when our code is already running, from within the same program and using the same programming language.

In Python, this starts from simple things like isintance() and type() to check the type of an object, to things like hasattr() to check for the presence of attributes and many other more advanced techniques, including the inspect module and many of the metaprogramming dunder methods.

Django app and model introspection

Django is just Python, so you can use all normal Python introspection techniques. In addition, there is a formally documented and supported set of functions and methods for introspecting Django apps and models, such as the apps module and the Model _meta API.

Django checks framework

The third main tool we’re going to use in this solution is Django’s system checks framework, which allows us to run certain kinds of checks, at both “warning” and “error” level. This is the least important tool, and we could in fact switch it out for something else like a unit test.

The solution

It’s easiest to present the code, and then discuss it:

from django.apps import apps from django.conf import settings from django.core.checks import Tags, Warning, register @register() def check_date_fields(app_configs, **kwargs): exceptions = [ # This field is provided by Django's AbstractBaseUser, we don't control it # and we’ll break things if we change it: "accounts.User.last_login", ] from django.db.models import DateField, DateTimeField errors = [] for field in get_first_party_fields(): field_name = field.name model = field.model if f"{model._meta.app_label}.{model.__name__}.{field_name}" in exceptions: continue # Order of checks here is important, because DateTimeField inherits from DateField if isinstance(field, DateTimeField): if not field_name.endswith("_at"): errors.append( Warning( f"{model.__name__}.{field_name} field expected to end with `_at`, " + "or be added to the exceptions in this check.", obj=field, id="conventions.E001", ) ) elif isinstance(field, DateField): if not (field_name.endswith("_date") or field_name.endswith("_on")): errors.append( Warning( f"{model.__name__}.{field_name} field expected to end with `_date` or `_on`, " + "or be added to the exceptions in this check.", obj=field, id="conventions.E002", ) ) return errors def get_first_party_fields(): for app_config in get_first_party_apps(): for model in app_config.get_models(): yield from model._meta.get_fields() def get_first_party_apps() -> list[AppConfig]: return [app_config for app_config in apps.get_app_configs() if is_first_party_app(app_config)] def is_first_party_app(app_config: AppConfig) -> bool: if app_config.module.__name__ in settings.FIRST_PARTY_APPS: return True app_config_class = app_config.__class__ if f"{app_config_class.__module__}.{app_config_class.__name__}" in settings.FIRST_PARTY_APPS: return True return False

We start here with some imports and registration, as documented in the “System checks” docs. You’ll need to place this code somewhere that will be loaded when your application is loaded.

Our checking function defines some allowed exceptions, because there are some things out of our control, or there might be other reasons. It also mentioned the exceptions mechanism in the warning message. You might want a different mechanism for exceptions here, but I think having some mechanism like this, and advertising its existence in the warnings, is often pretty important. Otherwise, you can end up with worse consequences when people just slavishly follow rules. Notice how in the exception list above I’ve given a comment detailing why the exception is there though – this helps to establish a precedent that exceptions should be justified, and the justification should be there in the code.

We then loop through all “first party” model fields, looking for DateTimeField and DateField instances. This is done using our get_first_party_fields() utility, which is defined in terms of get_first_party_apps(), which in turn depends on:

The id values passed to Warning here are examples – you should change according to your needs. You might also choose to use Error instead of Warning.

Output

When you run manage.py check, you’ll then get output like:

System check identified some issues: WARNINGS: myapp.MyModel.created: (conventions.E001) MyModel.created field expected to end with `_at`, or be added to the exceptions in this check. System check identified 1 issue (0 silenced).

As mentioned, you might instead want to run this kind of check as a unit test.

Conclusion

There are many variations on this technique that can be used to great effect in Django or other Python projects. Very often you will be able to play around with a REPL to do the introspection you need.

Where it is possible, I find doing this far more effective than attempting to document things and relying on people reading and remembering those docs. Every time I’m tripped up by bad names, or when good names or a strong convention could have helped me, I try to think about how I could push people towards a good convention automatically – while also giving a thought to unintended bad consequences of doing that prematurely or too forcefully.

Categories: FLOSS Project Planets

Marknote 1.1.0

Planet KDE - Mon, 2024-04-01 11:05

Marknote 1.1.0 is out! Marknote is the new WYSIWYG note-taking application from KDE. Despite the latest release being just a few days ago, we have been hard at work and added a few new features and, more importantly, fixed some bugs.

Marknote now boasts broader Markdown support, and can now display images and task lists in the editor. And once you are done editing your notes, you can export them to various formats, including PDF, HTML and ODT.

Export to PDF, HTML and ODT

Marknote’s interface now seamlessly integrates the colors assigned to your notebooks, enhancing its visual coherence and making it easier to distinguish one notebook from another. Additionally, your notebooks remember the last opened note, automatically reopening it upon selection.

Accent color in list delegate

We’ve also introduced a convenient command bar similar to the one in Merkuro. This provides quick access to essential actions within Marknote. Currently it only creates a new notebook and note, but we plan to make more actions available in the future. Finally we have reworked all the dialogs in Markdown to use the newly introduced FormCardDialog from KirigamiAddons.

Command bar

We have created a small feature roadmap with features we would like to add in the future. Contributions are welcome!

Packager section

You can find the package on download.kde.org and it has been signed with my GPG key.

Note that this release introduce a new recommanded dependencies: md4c and require the latest Kirigami Addons release (published a few hours ago).

Categories: FLOSS Project Planets

Kirigami Addons 1.1.0

Planet KDE - Mon, 2024-04-01 11:00

It’s again time for a new Kirigami Addons release. Kirigami Addons is a collection of helpful components for your QML and Kirigami applications.

FormCard

I added a new FormCard delegate: FormColorDelegate which allow to select a color and a new delegate container: FormCardDialog which is a new type of dialog.

FormCardDialog containing a FormColorDelegate in Marknote

Aside from these new components, Joshua fixed a newline bug in the AboutKDE component and I updated the code examples in the API documentation.

TableView

This new component is intended to provide a powerful table view on top of the barebone one provided by QtQuick and similar to the one we have in our QtWidgets application.

This was contributed by Evgeny Chesnokov. Thanks!

TableView with resizable and sortable columns

Other components

The default size of MessageDialog was decreased and is now more appropriate.

MessageDialog new default size

James Graham fixed the autoplay of the video delegate for the maximized album component.

Packager section

You can find the package on download.kde.org and it has been signed with my GPG key.

Categories: FLOSS Project Planets

The interpersonal side of the xz-utils compromise

Planet KDE - Mon, 2024-04-01 10:54

While everyone is busy analyzing the highly complex technical details of the recently discovered xz-utils compromise that is currently rocking the internet, it is worth looking at the underlying non-technical problems that make such a compromise possible. A very good write-up can be found on the blog of Rob Mensching...

"A Microcosm of the interactions in Open Source projects"

Categories: FLOSS Project Planets

Ben Hutchings: FOSS activity in March 2024

Planet Debian - Mon, 2024-04-01 10:51
Categories: FLOSS Project Planets

Ben Hutchings: FOSS activity in March 2024

Planet Debian - Mon, 2024-04-01 10:51
Categories: FLOSS Project Planets

Drupal Association blog: Unveiling the Power of Drupal: Your Ultimate Choice for Web Development

Planet Drupal - Mon, 2024-04-01 09:54

Welcome to DrupalCon Portland 2024, where innovation, collaboration, and excellence converge! As the premier event for Drupal enthusiasts, developers, and businesses, it's the perfect occasion to explore why Drupal stands tall as the preferred choice for web development. In this article, we'll delve into the compelling reasons that make Drupal the ultimate solution for your web development needs.

Open Source Excellence

Drupal is renowned for being an open-source content management system (CMS), fostering a vibrant community of developers and contributors. The power of collaboration within the Drupal community results in continuous improvements, security updates, and a wealth of modules that cater to a wide range of functionalities. Choosing Drupal means embracing a platform that is constantly evolving and adapting to the ever-changing landscape of the digital world.

Flexibility and Scalability

Drupal's flexibility is one of its key strengths. Whether you're building a personal blog, a corporate website, or a complex e-commerce platform, Drupal adapts to your needs. Its modular architecture allows developers to create custom functionalities and integrate third-party tools seamlessly. As your business grows, Drupal scales with you, ensuring that your website remains robust, high-performing, and capable of handling increased traffic and data.

Exceptional Content Management

Content is at the heart of any successful website, and Drupal excels in providing an intuitive and powerful content management experience. The platform offers a sophisticated taxonomy system, making it easy to organize and categorize content. With a user-friendly interface, content creators can effortlessly publish, edit, and manage content, empowering organizations to maintain a dynamic and engaging online presence.

Security First

In the digital age, security is non-negotiable. Drupal takes a proactive approach to security, with a dedicated security team that monitors, identifies, and addresses vulnerabilities promptly. The platform's robust security features, frequent updates, and a vigilant community ensure that your website is well-protected against potential threats. By choosing Drupal, you're investing in a platform that prioritizes the security of your digital assets.

Mobile Responsiveness

With the increasing prevalence of mobile devices, it's crucial for websites to be responsive and accessible across various screen sizes. Drupal is designed with mobile responsiveness in mind, offering a seamless experience for users on smartphones, tablets, and other devices. This ensures that your website not only looks great but also performs optimally, regardless of the device your audience is using.

Community Support and Knowledge Sharing

Drupal's strength lies not only in its codebase but also in its vast and supportive community. DrupalCon is a testament to the spirit of collaboration and knowledge sharing within the community. Whether you're a seasoned developer or a newcomer, Drupal's community is there to offer support, guidance, and a wealth of resources to help you succeed. By choosing Drupal, you're not just adopting a technology but becoming part of a global network of passionate individuals.

As we gather at DrupalCon Portland 2024, the choice is clear – Drupal is the unparalleled solution for web development. Its open-source nature, flexibility, security features, exceptional content management capabilities, mobile responsiveness, and thriving community make it the go-to platform for building robust and scalable websites. Join the Drupal revolution and unlock the full potential of your digital presence!

Register now for DrupalCon Portland 2024!

Categories: FLOSS Project Planets

KDE - Kiosco De Empanadas

Planet KDE - Mon, 2024-04-01 09:47

You like tasy! At KDE we got tasty!

Categories: FLOSS Project Planets

DrupalEasy: DrupalEasy Podcast - A very special episode

Planet Drupal - Mon, 2024-04-01 09:38

A very special episode of the DrupalEasy Podcast - an episode two years in the making.

Categories: FLOSS Project Planets

Pages