Autore: UMNW

  • Cleaning Inline Comments from .env Files Without Wasting Time and Patience

    Cleaning Inline Comments from .env Files Without Wasting Time and Patience

    .env files seem like the most harmless thing in the world.

    A variable, an equals sign, a value. Everything is nice and simple.

    Then comes the moment when someone — especially our beloved AIs — decides to do something that looks perfectly reasonable:

    DB_PORT=27017 # MongoDB port
    NODE_ENV=production # Production environment
    

    And so it begins…

    The problem is that not every .env file parser handles inline comments properly. Some understand perfectly well that everything after # is a comment. Others decide to grab the entire line and start fluttering around like a moth against a streetlight.

    So you think you have:

    DB_PORT=27017
    

    while your software may actually end up with something like:

    DB_PORT="27017 # MongoDB port"
    

    Wonderful.

    Personally, I ran into this with Go. Don’t ask me which parser it was because I don’t remember, but I’ve seen similar behaviour during builds and startups managed with Docker Compose as well.

    The funny part is that these problems often don’t blow up in your face immediately.

    If the variable represents something important and critical, the program might die straight away and at least give you a clue.

    But if it represents a non-essential application value, a secondary feature flag, an endpoint used only under certain conditions, or simply some damn token, completely nonsensical malfunctions can start showing up.

    And that’s when the time starts disappearing.

    Why? Because you may find yourself in a situation where:

    • everything works locally;
    • it doesn’t work on the server;
    • the code is identical;
    • the configuration looks identical;
    • you’ve already checked the variable seven times;
    • you start questioning your own sanity.

    Meanwhile, the local version of your software keeps running perfectly happily like a fairground ride.

    No More Comments Next to Variables

    The solution I adopted is very simple:

    I no longer want to see comments on the same line as variables in .env files.

    So this:

    DB_PORT=27017 # MongoDB port
    REDIS_HOST=10.0.0.14 # Redis Cluster
    

    must become this:

    # MongoDB port
    DB_PORT=27017
    
    # Redis Cluster
    REDIS_HOST=10.0.0.14
    

    The comment is still there, and the configuration remains readable.

    Automatically Cleaning a .env File

    Obviously, I had absolutely no intention of manually fixing dozens or hundreds of lines.

    So we can let Perl do the dirty work (thanks, fatChatGPT):

    perl -pe 'if (/^(\s*[^#\s][^=]*=.*?)[ \t]+#\s*(.+?)\s*$/) { $_ = "# $2\n$1\n"; }' .env > .env-treated
    

    The command takes:

    DB_HOST=10.0.0.15
    DB_PORT=27017           # MongoDB port
    DB_PASSWORD=test#123
    REDIS_HOST=10.0.0.14    # Redis Cluster
    NODE_ENV=production     # Environment
    

    and produces a new .env-treated file:

    DB_HOST=10.0.0.15
    # MongoDB port
    DB_PORT=27017
    DB_PASSWORD=test#123
    # Redis Cluster
    REDIS_HOST=10.0.0.14
    # Environment
    NODE_ENV=production
    

    No magic. The comment is simply moved above the variable.

    Watch Out for # Characters That Are Actually Part of the Value

    There is, however, one important detail here.

    A # character can legitimately be part of a password, a token, or any other value.

    For example:

    PASSWORD=test#123
    TOKEN=abc#xyz
    

    These lines must not be touched.

    That’s why the command treats a # as an inline comment only when it is preceded by at least one space or tab.

    So:

    PASSWORD=test#123
    

    remains:

    PASSWORD=test#123
    

    while:

    PASSWORD=test#123   # Service password
    

    becomes:

    # Service password
    PASSWORD=test#123
    

    Exactly what we want.

    A Convenient Bash Function

    If this happens to you often, you might as well create a function:

    envclean() {
        perl -pe 'if (/^(\s*[^#\s][^=]*=.*?)[ \t]+#\s*(.+?)\s*$/) { $_ = "# $2\n$1\n"; }' "$1" > "${1}-treated"
    }
    

    Then:

    envclean .env.production
    

    generates:

    .env.production-treated
    

    without modifying the original file.

    Which is always a good idea, because automating configuration cleanup is useful; automating the destruction of the original configuration, slightly less so.

    In Conclusion

    Inline comments in .env files are nice as long as they work.

    The problem is that we can’t know for certain which parser will read that file today, tomorrow, or inside some container assembled by someone six months from now.

    So the rule I prefer is:

    A comment goes above. A variable goes below. Never together on the same line.

    It’s slightly more verbose, but it also makes it much less likely that you’ll spend an afternoon debugging a token that accidentally contains " # production token" at the end.

    I hope that, like me, you have more creative ways to waste your time.

  • Ripulire i file .env dai commenti inline senza perdere tempo e pazienza

    Ripulire i file .env dai commenti inline senza perdere tempo e pazienza

    I file .env sembrano la cosa più innocua del mondo.

    Una variabile, un uguale, un valore. Tutto molto bello.

    Poi arriva il momento in cui qualcuno (specie le nostre amate IA) decide di fare una cosa apparentemente civilissima:

    DB_PORT=27017 # Porta MongoDB
    NODE_ENV=production # Ambiente di produzione
    

    Il problema è che non tutti i parser dei file .env sono resistenti ai commenti inline. Alcuni capiscono perfettamente che tutto quello che viene dopo # è un commento. Altri invece decidono di prelevare la riga intera e sfarfallare come una falena contro un lampione.

    Quindi voi pensate di avere:

    DB_PORT=27017
    

    e invece il vostro software magari si ritrova qualcosa del genere:

    DB_PORT="27017 # Porta MongoDB"
    

    Bellissimo.

    Personalmente mi è capitato con Go, non chiedetemi con quale parser, perché non ricordo, ma ho visto comportamenti simili anche durante build e avvii gestiti con Docker Compose.

    La parte divertente è che spesso questi problemi non ti esplodono in faccia immediatamente.

    Se la variabile rappresenta qualcosa di importante e preminente, magari il programma muore subito e almeno avete una pista.

    Ma se rappresenta un valore non fondamentale dell’applicazione, una feature flag secondaria, un endpoint usato soltanto in determinate condizioni o semplicemente un cavolo di token, possono iniziare malfunzionamenti completamente privi di senso.

    E lì il tempo se ne va.

    Perché? Siete in una situazione in cui magari:

    • in locale funziona tutto;
    • sul server no;
    • il codice è identico;
    • la configurazione sembra identica;
    • avete già ricontrollato la variabile sette volte;
    • iniziate a dubitare della vostra sanità mentale.

    E nel frattempo la versione locale del vostro software continua a girare bene come una calcinculo gitano.

    Basta commenti di fianco alle variabili

    La soluzione che ho adottato è molto semplice:

    nei file .env non voglio più vedere commenti sulla stessa riga della variabile.

    Quindi questo:

    DB_PORT=27017 # Porta MongoDB
    REDIS_HOST=10.0.0.14 # Redis Cluster
    

    deve diventare questo:

    # Porta MongoDB
    DB_PORT=27017
    
    # Redis Cluster
    REDIS_HOST=10.0.0.14
    

    Il commento c’è ancora e la configurazione rimane leggibile.

    Ripulire automaticamente un .env

    Ovviamente non avevo nessuna intenzione di mettermi a sistemare decine o centinaia di righe a mano.

    Quindi possiamo far fare il lavoro sporco a Perl (grazie ciattoneGPT):

    perl -pe 'if (/^(\s*[^#\s][^=]*=.*?)[ \t]+#\s*(.+?)\s*$/) { $_ = "# $2\n$1\n"; }' .env > .env-treated
    

    Il comando prende:

    DB_HOST=10.0.0.15
    DB_PORT=27017           # Porta MongoDB
    DB_PASSWORD=test#123
    REDIS_HOST=10.0.0.14    # Redis Cluster
    NODE_ENV=production     # Ambiente
    

    e produce un nuovo file .env-treated:

    DB_HOST=10.0.0.15
    # Porta MongoDB
    DB_PORT=27017
    DB_PASSWORD=test#123
    # Redis Cluster
    REDIS_HOST=10.0.0.14
    # Ambiente
    NODE_ENV=production
    

    Niente magia. Il commento viene semplicemente spostato sopra la variabile.

    Attenzione ai # che fanno realmente parte del valore

    Qui c’è però un dettaglio importante.

    Un carattere # può anche essere parte legittima di una password, di un token o di qualsiasi altro valore.

    Per esempio:

    PASSWORD=test#123
    TOKEN=abc#xyz
    

    Queste righe non devono essere toccate.

    Per questo il comando considera un commento inline solamente un # preceduto da almeno uno spazio o da una tabulazione.

    Quindi:

    PASSWORD=test#123
    

    rimane:

    PASSWORD=test#123
    

    mentre:

    PASSWORD=test#123   # Password del servizio
    

    diventa:

    # Password del servizio
    PASSWORD=test#123
    

    Esattamente quello che vogliamo.

    Versione comoda come funzione Bash

    Se la cosa vi capita spesso, tanto vale creare una funzione:

    envclean() {
        perl -pe 'if (/^(\s*[^#\s][^=]*=.*?)[ \t]+#\s*(.+?)\s*$/) { $_ = "# $2\n$1\n"; }' "$1" > "${1}-treated"
    }
    

    A quel punto:

    envclean .env.production
    

    genera:

    .env.production-treated
    

    senza modificare il file originale.

    Che è sempre una buona idea, perché automatizzare una pulizia della configurazione è utile; automatizzare la distruzione della configurazione originale un po’ meno.

    In fine

    I commenti inline nei file .env sono belli finché funzionano.

    Il problema è che non possiamo sapere con certezza quale parser leggerà quel file oggi, domani o dentro qualche container assemblato da qualcuno sei mesi dopo.

    Quindi la regola che preferisco è:

    un commento sta sopra. Una variabile sta sotto. Mai insieme sulla stessa riga.

    È leggermente più verboso, ma è anche parecchio meno probabile che passiate un pomeriggio a debuggare un token che contiene accidentalmente " # token produzione" alla fine.

    Spero che, come me, anche voi abbiate modi più creativi per buttare via il tempo.

  • WordPress Notice _load_textdomain_just_in_time for Oxygen builder plugin

    WordPress Notice _load_textdomain_just_in_time for Oxygen builder plugin

    Hai mai visto questo notice?

    Notice: Function _load_textdomain_just_in_time was called <strong>incorrectly</strong>. Translation loading for the <code>oxygen</code> domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the <code>init</code> action or later. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 6.7.0.) in /home/<my-user>/public_html/wp-includes/functions.php on line 6260

    Ebbene non sai quanto rallenta l’interfaccia amministrativa di WordPress (back-end).

    Puoi fixarlo aggiungendo un semplice must-use plugin che sopperisce al fato che il team di Oxygen Builder non si è ancora adoperato a riguardo.

    Nota bene: nel mio caso il problema era presente sulla versione 4.9.7 di Oxygen Builder.

    Non sto qui a mostrare dati vari, ma ho riscontrato che era uno dei colli di bottiglia significativi che erano dietro la lentezza riscontrata dal cliente nell’usare il back-end di WordPress.

    Per risolverlo bisogna intervenire sul tempo di caricamento all’init di WordPress, come? Con un must use plugin.

    Aggiungete un file chiamato “oxygen-woocommerce-i18n-fix.php”, o come vi pare e mettete dentro questa roba:

    <?php
    /**
     * Plugin Name: Oxygen WooCommerce i18n timing fix
     * Description: Delays Oxygen WooCommerce initialization until after_setup_theme.
     */
    
    add_action(
        'plugins_loaded',
        function () {
            $priority = has_action(
                'plugins_loaded',
                'oxygen_woocommerce_init'
            );
    
            if ( false !== $priority ) {
                remove_action(
                    'plugins_loaded',
                    'oxygen_woocommerce_init',
                    $priority
                );
    
                add_action(
                    'after_setup_theme',
                    'oxygen_woocommerce_init',
                    0
                );
            }
        },
        -9999
    );
    

    Il notice sparirà e il vostro WordPress andrà un pochino meglio, non sarà un game changer, ma come diceva la nonna il pennello si fa un pelo alla volta.

    🪰🕸️