Git Product home page Git Product logo

companienv's Introduction

Companienv

Your companion for .env files. Everybody knows about 12 factor and environments variables now. A lot of frameworks such as Symfony are using a .env file to configure the application, but we don't have anything to help users to complete their local .env file.

Companienv will helps you manage the .env files, from a reference .env.dist version in your code repository. Companienv can:

Usage

  1. Require sroze/companienv as your project dependency:
composer req sroze/companienv
  1. Run your companion:
vendor/bin/companienv

Composer automation

You can run Companienv automatically after composer install or composer update commands by configuring the scripts in your composer.json file:

{
    "scripts": {
        "post-install-cmd": [
            "Companienv\\Composer\\ScriptHandler::run"
        ],
        "post-update-cmd": [
            "Companienv\\Composer\\ScriptHandler::run"
        ]
    }
}

By default, the file used as a template is .env.dist and the written file is .env. You can change these defaults within your composer.json file:

{
    "extra": {
        "companienv-parameters": [
            {
                "file": ".env.foo",
                "dist-file": ".env.foo.dist"
            }
        ]
    }
}

The .env.dist file

All your configuration is directly in your .env.dist file, as comments. The configuration is divided in blocks that will be displayed to the user for a greater understanding of the configuration. Here are the fondations for Companienv:

  • Blocks. They logically group variables together. They are defined by a title (line starting with a double-comment ##) and a description (every comment line directly bellow)
  • Attributes. Defined by a line starting with #+, an attribute is associated to one or multiple variables. These attributes are the entrypoint for extensions. In the example above, it says that the JWT_* variables are associated with an RSA key pair, so Companienv will automatically offer the user to generate one for them.
  • Comments. Lines starting by #~ will be ignored by Companienv.

Example of .env.dist. file

# .env.dist

## Welcome in the configuration of [my-project]
#
#~ Please run the `bin/start` command.
#~ These lines starting with `~` are not going to be displayed to the user

## GitHub
# In order to be able to login with GitHub, you need to create a GitHub application. To get access to the code
# repositories, you need to create a GitHub integration.
#
#+file-to-propagate(GITHUB_INTEGRATION_KEY_PATH)
#
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_INTEGRATION_ID=
GITHUB_INTEGRATION_KEY_PATH=
GITHUB_SECRET=

## Security
# We need sauce! Well, no, we need an SSL certificate.
#
#+rsa-pair(JWT_PRIVATE_KEY_PATH JWT_PUBLIC_KEY_PATH JWT_PRIVATE_KEY_PASS_PHRASE)
#
JWT_PRIVATE_KEY_PATH=/runtime/keys/jwt-private.pem
JWT_PUBLIC_KEY_PATH=/runtime/keys/jwt-public.pem
JWT_PRIVATE_KEY_PASS_PHRASE=

## Another block
# With its (optional) description
AND_OTHER_VARIABLES=

Built-in extensions

only-if extension

Some of the blocks of your .env file might not even be relevant if some other variable was disabling a given feature.

Example: This will only ask for the INTERCOM_APPLICATION_ID variable if INTERCOM_ENABLED has the value (current or entered by the user) true.

## Support & Feedback
# If you would like to allow your users to get some support from you, give you some feedback and this
# sort of things, select the integrations you'd like.
#
#+only-if(INTERCOM_APPLICATION_ID):(INTERCOM_ENABLED=true)
#
INTERCOM_ENABLED=false
INTERCOM_APPLICATION_ID=none

file-to-propagate extension

Will ask the path of an existing file and copy it to the destination mentioned in the reference.

Example: this will ask the user to give the path of an existing file. It will copy this file to the path /runtime/keys/firebase.json, relative to the root directory of the project.

#+file-to-propagate(FIREBASE_SERVICE_ACCOUNT_PATH)
FIREBASE_SERVICE_ACCOUNT_PATH=/runtime/keys/firebase.json

rsa-pair extension

If the public/private key pair does not exist, Companienv will offer to generate one for the user.

#+rsa-pair(JWT_PRIVATE_KEY_PATH JWT_PUBLIC_KEY_PATH JWT_PRIVATE_KEY_PASS_PHRASE)
JWT_PRIVATE_KEY_PATH=/runtime/keys/jwt-private.pem
JWT_PUBLIC_KEY_PATH=/runtime/keys/jwt-public.pem
JWT_PRIVATE_KEY_PASS_PHRASE=

ssl-certificate-extension

Similar to the RSA keys pair: Companienv will offer to generate a self-signed SSL certificate if it does not exist yet.

#+ssl-certificate(SSL_CERTIFICATE_PRIVATE_KEY_PATH SSL_CERTIFICATE_CERTIFICATE_PATH SSL_CERTIFICATE_DOMAIN_NAME)
SSL_CERTIFICATE_PRIVATE_KEY_PATH=/runtime/keys/server.key
SSL_CERTIFICATE_CERTIFICATE_PATH=/runtime/keys/server.crt
SSL_CERTIFICATE_DOMAIN_NAME=

Your own extensions

You can easily create and use your own extensions with Companienv. In order to do so, you'll have to start Companienv with your own PHP file and use the registerExtension method of the Application:

use Companienv\Application;
use Companienv\Extension;

$application = new Application($rootDirectory);
$application->registerExtension(new class() implements Extension {
    // Implements the interface...
});
$application->run();

companienv's People

Contributors

carusogabriel avatar elodieirdor avatar jontjs avatar peter17 avatar sroze avatar vsouz4 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

companienv's Issues

Suggestion: Allow RegEx Compare for "only-if"

Hi,

in our projects we have an environment variable for the system context, which can have values like: Production, Development OR Development/Staging or Development/Local/UserX

So, if I want to promote an ENV var only in every Development/Local/* scenario, it would be nice, if the only-if feature would allow regex compare.

Like:

#+only-if(SOME_ENV_VAR_FOR_LOCAL_CONTEXT_ONLY):(CONTEXT~'/^Development\/Local/')

What do you think?

Invalid line in .env.dist file

Hi,

In my .env.dist file, I have a line with a variable set with a base64 encoded value (finishing with an =).

Companienv writes the line is invalid. Is it a normal behavior or a bug?

Command must return with integer

> ./vendor/bin/companienv
PHP Fatal error:  Uncaught TypeError: Return value of "class@anonymous in /home/sabee/test/vendor/symfony/console/Command/Command.php:261
Stack trace:
#0 /home/sabee/test/vendor/symfony/console/Application.php(916): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#1 /home/sabee/test/vendor/symfony/console/Application.php(264): Symfony\Component\Console\Application->doRunCommand(Object(class@anonymous), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#2 /home/sabee/test/vendor/symfony/console/Application.php(140): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#3 /home/sabee/test/vendor/sroze/companienv/bin/companienv(26): Symfony\Component\Console\Applic in /home/sabee/test/vendor/symfony/console/Command/Command.php on line 261

Fatal error: Uncaught TypeError: Return value of "class@anonymous in /home/sabee/test/vendor/symfony/console/Command/Command.php on line 261

TypeError: Return value of "class@anonymous in /home/sabee/test/vendor/symfony/console/Command/Command.php on line 261

Call Stack:
    0.0003     394848   1. {main}() /home/sabee/test/vendor/sroze/companienv/bin/companienv:0
    0.0261    2206296   2. Companienv\Application->run() /home/sabee/test/vendor/sroze/companienv/bin/companienv:26
    0.0467    2542272   3. Companienv\Application->doRun() /home/sabee/test/vendor/symfony/console/Application.php:140
    0.0481    2553928   4. Companienv\Application->doRunCommand() /home/sabee/test/vendor/symfony/console/Application.php:264
    0.0481    2553928   5. class@anonymous->run() /home/sabee/test/vendor/symfony/console/Application.php:916

symfony/console version is 5.1

Since symfony/console:5.0.0 a command must return with integer, otherwise application will throw TypeError.

https://github.com/symfony/console/blob/5.0/CHANGELOG.md

Based on this, Companienv\Application::run must return 0 if everything went fine, but Companienv\Companion::fillGaps returns with void.

return $callable($input, $output);

Ignore warning/errors with composer --no-interaction

I think it could be a good things, with CircleCI for example, to ignore .env if it is not exist and create/copy/paste .env from the dist file or just ignore if .env.dist does not exist.

For example, currently we use Docker in CircleCI and we just copy our .env and not .env.dist.

I can do a P.R. but I would like to know your point of view of what you prefer.

File not found + only-if applying: discrepancy in requiring the value

Given the following example:

# .env.dist
#+file-to-propagate(GOOGLE_CLOUD_AUDIT_LOG_SERVICE_ACCOUNT_PATH)
#+only-if(GOOGLE_CLOUD_AUDIT_LOG_SERVICE_ACCOUNT_PATH):(GOOGLE_CLOUD_AUDIT_ENABLED=true)
GOOGLE_CLOUD_AUDIT_ENABLED=false
GOOGLE_CLOUD_AUDIT_LOG_SERVICE_ACCOUNT_PATH=/runtime/keys/google-cloud-audit-log.json

When the .env file contains the following:

GOOGLE_CLOUD_AUDIT_ENABLED=false
GOOGLE_CLOUD_AUDIT_LOG_SERVICE_ACCOUNT_PATH=/runtime/keys/google-cloud-audit-log.json

Then companienv will prompt the user because it is missing one variable (GOOGLE_CLOUD_AUDIT_LOG_SERVICE_ACCOUNT_PATH, because the file does not exist) but will not prompt for anything because the only-if is applied later. Therefore, only-if should rule out this variable from the "is requiring value" check.

Unable to set 0 as a value of env var

How can I set false as a value of environment variable? Before, I handled it with 0 value which was converted to false with %env(bool:BOOL_ENV_VAR)% Symfony feature. But now, when I set 0 during interactive mode of ./vendor/bin/companienv it just re-ask a new value.

Tag new release v0.0.11

Would it be possible to tag commit bff66f3 to allow use of the fix without having to use dev-master as a composer constraint?

Symfony 5: rsa key pair generation fails

Got an error in Symfony 5.1 app when running vendor/bin/companienv.

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Symfony\Component\Process\Process::__construct() must be of the type array, string given, called in /home/user/sf5/vendor/sroze/companienv/src/Companienv/Extension/RsaKeys.php on line 48 and defined in /home/user/sf5/vendor/symfony/process/Process.php:140
Stack trace:
#0 /home/user/sf5/vendor/sroze/companienv/src/Companienv/Extension/RsaKeys.php(48): Symfony\Component\Process\Process->__construct()
#1 /home/user/sf5/vendor/sroze/companienv/src/Companienv/Extension/Chained.php(31): Companienv\Extension\RsaKeys->getVariableValue()
#2 /home/user/sf5/vendor/sroze/companienv/src/Companienv/Companion.php(79): Companienv\Extension\Chained->getVariableValue()
#3 /home/user/sf5/vendor/sroze/companienv/src/Companienv/Companion.php(53): Companienv\Companion->fillBlockGaps()
#4 /home/user/sf5/vendor/sroze/companienv/src/Companienv/Application.php(66): Companienv\Companion->fillGaps()
#5 /home/user/sf5/ in /home/user/sf5/vendor/symfony/process/Process.php on line 140

composer.json

"symfony/process": "5.1.*",
"sroze/companienv": "^1.0",

I have the following in my dist file

###> lexik/jwt-authentication-bundle ###
#+rsa-pair(JWT_SECRET_KEY JWT_PUBLIC_KEY JWT_PASSPHRASE)
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=secret
###< lexik/jwt-authentication-bundle ###

This is because of the breaking change in the Symfony 5 Process component https://github.com/symfony/symfony/blob/master/UPGRADE-5.0.md#process

Commands must be defined as arrays when creating a Process instance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.