Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[DotEnv] Add a new loadForEnv() method mimicking Ruby's dotenv behavior#28533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
fabpot merged 1 commit intosymfony:masterfromdunglas:loadForEnv
Oct 26, 2018

Conversation

@dunglas
Copy link
Member

@dunglasdunglas commentedSep 21, 2018
edited
Loading

QA
Branch?master
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed ticketshelps forsymfony/recipes#465,symfony/recipes#408
LicenseMIT
Doc PRtodo

This PR adds a newloadForEnv() method that mimics the behavior ofCreate React App,Rails' DotEnv and probably some other libs:

DotEnv::loadForEnv() will load the following files, starting from the bottom. The first value set (or those already defined in the environment) take precedence:

  • .env - The Original®
  • .env.dev,.env.test... - Environment-specific settings.
  • .env.local - Local overrides. This file is loaded for all environmentsexcepttest.
  • .env.dev.local,.env.test.local... - Local overrides of environment-specific settings.

The plan is to use this method in the default SF installation (symfony/recipes#466).

Note: this feature can also be used in prod if the app doesn’t follow the 12factor methodology (discouraged, but sometimes mandatory in constrained hosting environments not allowing to set environment variables).

cvergne, mateuszsip, eko, bpaz, ogizanagi, maxhelias, OskarStark, magi-web, jrjohnson, onEXHovia, and 9 more reacted with thumbs up emojiWirone, ro0NL, jaikdean, DanielBadura, ossinkine, and deantomasevic reacted with thumbs down emojiTaluu, DanielBadura, jaikdean, Koc, and andreybolonin reacted with confused emojitoofff and teohhanhui reacted with heart emoji
@dunglasdunglas changed the title[DotEnv] Add a new loadForEnv() method mimicing Ruby's dotenv behavior[DotEnv] Add a new loadForEnv() method mimicking Ruby's dotenv behaviorSep 21, 2018
@dunglasdunglasforce-pushed theloadForEnv branch 2 times, most recently from1000890 toe0fecddCompareSeptember 21, 2018 06:57
/**
* Loads one or several .env and the corresponding env.local, env.$env and env.$env.local files if they exist.
*
* The env.test.local is always ignored because tests should produce the same results for everyone.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't think we should put any restriction and hardcode this. If that's really what the users want, that's on them. I'd remove it.

jvasseur reacted with thumbs up emoji
Copy link
MemberAuthor

@dunglasdunglasSep 21, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I was hesitating, but Create React App, Rails and Sinatra behave like this. Consistency is the key, it helps switching from one project to another. It especially matters when using both React and SF in a project (more and more common).

And, it's a good idea!

I really don't want to introduce something Symfony-specific here!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Why is.env.test.local mentioned in the following sentence, then ? 😄

.env.dev.local, .env.test.local, .env.prod.local... - Local overrides of environment-specific settings.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@ogizanagi the comment was wrong 😁. Fixed!

/**
* Loads one or several .env and the corresponding env.local, env.$env and env.$env.local files if they exist.
*
* env.local is always ignored in test env because tests should produce the same results for everyone.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

- env.local+ .env.local// or+ $path.local

? 😄

dunglas reacted with laugh emoji
}

/**
* Loads one or several .env and the corresponding env.local, env.$env and env.$env.local files if they exist.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Environment variables in later files override earlier files, correct?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Almost, see PR description.

@Wirone
Copy link
Contributor

Wirone commentedSep 25, 2018
edited
Loading

I don't get what's the purpose of having.env.prod while at the same time discuraging or even blockingDotEnv usage on production 🤔 Also, development instances shouldn't use production configuration..env.prod should not be commited, nor included in built Docker image. So what is the use case for it?

I don't like the idea of this PR. It makes simple task (app configuration) much more complicated and IMO doesn't bring added value (the only one I see is configuring variables for different environments and use it only by changingAPP_ENV, without need to edit.env by commenting/uncommenting lines per environment). I thought that YAML files' split (packages inprod/dev subdirectories) and.env file were supposed to fulfill all the config scenarios. This is a step back for me.

But maybe I don't understand something..

jvasseur, ossinkine, davidarich, SebastienXD, sukei, deantomasevic, and helhum reacted with thumbs up emoji

@fbourigault
Copy link
Contributor

The first use case I have is to have on a local machine the dev and test environments running at the "same" time. I mainly have a differentDATABASE_URL env variable which is probably different per developer and I don't want to useDATABSE_URL=... vendor/bin/simple-phpunit!

@dunglas
Copy link
MemberAuthor

@Wirone .env.prod is totally optional (for people not able to set environment variables in prod). This file will not be generated by the default skeleton (only .env.test will).
However it will make easier to use Dotenv in prod in cases were there is no alternatives (shared servers usually, and even for jobs in dedicated servers without Docker/K8S).

However, having .env.test, .env.panther, .env.otherenv on the development machine will be very useful (and it’s my main goal, as I use Kubernetes in prod, without env files obviously).

/**
* @param bool $envMode Silently ignore not existing files in $paths (but not the one in $path)
*/
privatefunctiondoLoad(bool$overrideExistingVars,string$path,array$paths,bool$envMode =false):void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

$envMode variable name does not correspond with what it does. Should be named$silent (as it's used internally) or$ignorePathErrors or something like that.

PS. phpDoc is missing the other arguments

Copy link
MemberAuthor

@dunglasdunglasSep 26, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

$silent or$ignorePathErrors is less accurate: an error will be thrown of the main file (usually .env) doesn’t exist. Only files for specific environments are optional.

Regarding the PHPDoc, in Symfony we don’t add the useless lines.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

IMO$envMode is not meaningful. If you don't look at implementation, only on signature, would you know what$envMode does? Honestly, it doesn't even look likebool variable, rather string or bitwise flag.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@Wirone I agree, it's why I added a PHPDoc description :) If you have better name in mind, I'll be very happy to switch ($silent and$ignorePathErrors were my first thoughts, but they are more confusing than$envMode).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What about$safe (determines if call is safe and will not throw an exception) or$required (determines if all paths should exist - it would require changing to$silent = !$required).

Copy link
MemberAuthor

@dunglasdunglasSep 26, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

IMO they are not more explicit, and can be confusing.environment mode is exactly what it is, and$ignoreFilesThatNotExistExceptTheFirstOne is a bit long. Isn't the description in the PHPDoc enough? This method is private, it will never be used by the end user, only by Symfony contributors (we may expect that they read the PHPDoc :D).

ogizanagi, Wirone, chalasr, and fbourigault reacted with thumbs up emoji

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

doLoad(bool $overrideExistingVars, string $path, bool $ignoreMissingExtraPaths, string ...$extraPaths = array())?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Not sure that using the splat operator is a good idea in this private method (we may add extra parameters at some point), also it is already used without the splat operator in other functions.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

parameter renamed

Copy link
Member

@chalasrchalasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Finally! This will allow me to drop an extra class from all my enterprise projects.
👍 Thanks for raising

@teohhanhui
Copy link
Contributor

I think what's missing from this picture is where.dist files fit in. We should not follow blindly the Create React App / Rails way, because it conflicts with our conventions.

@dunglas
Copy link
MemberAuthor

@teohhanhui the whole point of this PR is to switch from “our” conventions to the ones other projects follow.
Basically, .env.dist is now .env, and .env is now .env.local.

teohhanhui and sukei reacted with thumbs down emojiteohhanhui and goetas reacted with confused emoji

@teohhanhui
Copy link
Contributor

That sounds like a really bad thing to me. We shouldn't just switch conventions like that. What's wrong with sticking with.dist? It makes it more explicit that it's a distribution file. Plus, this would not go well with Docker Compose (.env is special for Docker Compose).

What I'm trying to say is, we could stick with our conventions while having all the benefits of an extended .env support like in the other projects.

@dunglas
Copy link
MemberAuthor

This has already been discussed a lot insymfony/recipes#466 and related tickets. It actually makes it easier to deal with Docker Compose.

teohhanhui reacted with confused emoji

@fabpot
Copy link
Member

Thank you@dunglas.

teohhanhui reacted with hooray emojiteohhanhui, chalasr, and maxhelias reacted with heart emoji

@fabpotfabpot merged commit774a78c intosymfony:masterOct 26, 2018
fabpot added a commit that referenced this pull requestOct 26, 2018
…s dotenv behavior (dunglas)This PR was merged into the 4.2-dev branch.Discussion----------[DotEnv] Add a new loadForEnv() method mimicking Ruby's dotenv behavior| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | yes| BC breaks?    | no     <!-- seehttps://symfony.com/bc -->| Deprecations? |no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->| Fixed tickets | helps forsymfony/recipes#465,symfony/recipes#408| License       | MIT| Doc PR        | todoThis PR adds a new `loadForEnv()` method that mimics the behavior of [Create React App](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#what-other-env-files-can-be-used), [Rails' DotEnv](https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use) and probably some other libs:`DotEnv::loadForEnv()` will load the following files, starting from the bottom. The first value set (or those already defined in the environment) take precedence:- `.env` - The Original®- `.env.dev`, `.env.test`, `.env.prod`... - Environment-specific settings.- `.env.local` - Local overrides. This file is loaded for all environments _except_ `test`.- `.env.dev.local`, `.env.test.local`, `.env.prod.local`... - Local overrides of environment-specific settings.The plan is to use this method in the default SF installation (symfony/recipes#466).Commits-------774a78c [DotEnv] Add a new loadForEnv() method mimicking Ruby's dotenv behavior
}

/**
* Loads one or several .env and the corresponding env.$env, env.local and env.$env.local files if they exist.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

this seems to be missing the dots in front of the files like .env.$env

dunglas reacted with thumbs up emoji
@dunglasdunglas deleted the loadForEnv branchOctober 29, 2018 07:13
fabpot added a commit that referenced this pull requestOct 29, 2018
This PR was merged into the 4.2-dev branch.Discussion----------[DotEnv] Fix loadForEnv PHPDoc| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->| BC breaks?    | no     <!-- seehttps://symfony.com/bc -->| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->| Fixed tickets |#28533 (review)| License       | MIT| Doc PR        | n/a<!--Write a short README entry for your feature/bugfix here (replace this comment block.)This will help people understand your PR and can be used as a start of the Doc PR.Additionally: - Bug fixes must be submitted against the lowest branch where they apply   (lowest branches are regularly merged to upper ones so they get the fixes too). - Features and deprecations must be submitted against the master branch.-->Commits-------c10710c [DotEnv] Fix loadForEnv PHPDoc
@ro0NL
Copy link
Contributor

ro0NL commentedOct 30, 2018
edited
Loading

did we really need this?

Why .env.prod over config/packages/prod? if you cant define real env vars those locations are effectively the same already... and you can already import a git ignored local parameter file.

the behavior of Create React App, Rails' DotEnv and probably some other libs:

so yeah.. curious if the config/packages/ convention didnt already provide such behavior in SF.

jvasseur, yceruto, jaikdean, Koc, Kocal, and deantomasevic reacted with thumbs up emoji

@jaikdean
Copy link

Is there a well-defined use case for this to explain why it's useful? The only ones I can think up are already solved by using parameters and environment variables as they are in Symfony 4.1, but I could well be missing something.

In my projects we havephpunit.xml.dist and.php_cs.dist files committed and their non-dist versions ignored, so the convention adopted from Rails etc just brings another convention into play, rather than replacing one. It's understandable if a lot of others are already used to this convention, but it's the first time I've seen it.

Just my 2 pence!

@weaverryan
Copy link
Member

This feature has a lot of options in it, but the original motivation was to help solve exactly one problem. Currently, you need to add all of your environment variables inphpunit.xml.dist. So, your environment variables are completely duplicated, even if you only want to change a few environment variables. This + this WIP recipe (symfony/recipes#466) will help make that happen (as you can just have a.env.dist). I think that, mostly, this change will not mean much to people - other than you don't need to duplicate your env vars in the test environment anymore and can instead create a.env.test with only the overrides.

Cheers!

@ro0NL
Copy link
Contributor

still.. there's zero difference with doing

# config/packages/test/some.yamlenv(SOME): "default in test"

no?

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedOct 30, 2018
edited
Loading

The value can be changed without invalidating the container, that's the diff :)

@weaverryan
Copy link
Member

That's a VERY fair point@ro0NL :). But I think setting a default in that way is a bit less obvious than having a.env.test that's created for you when installing the simple-phpunit recipe.

@nicolas-grekas
Copy link
Member

@weaverryan right!, that's the 2nd difference: flex automation!

@ro0NL
Copy link
Contributor

understood. im just skeptical if the overhaul is worth it eventually, it's quite significant.

@ryanotella
Copy link

@weaverryan Thanks for this! We were starting to think we'd gone mad and had completely missed something.

This was referencedNov 3, 2018
nicolas-grekas added a commit that referenced this pull requestNov 9, 2018
…nv() (nicolas-grekas)This PR was merged into the 4.2-dev branch.Discussion----------[Dotenv] add loadEnv(), a smoother alternative to loadForEnv()| Q             | A| ------------- | ---| Branch?       | 4.2| Bug fix?      | yes| New feature?  | no| BC breaks?    | yes (4.2-only)| Deprecations? | no| Tests pass?   | yes| Fixed tickets | -| License       | MIT| Doc PR        | -This PR replaces the `loadForEnv()` method introduced in#28533 by a new `loadEnv()` method.- It accepts only one mandatory argument: `$path`, which is the path to the `.env` file.- The 2nd argument is optional and defines the name of the environment variable that defines the Symfony env. This plays better with the current practice of defining the env in `.env` (`loadForEnv()` requires knowing the env before being called, leading to a chicken-n-egg situation that `loadEnv()` avoids.)- the possibility to load several files at once is removed. We don't have a use case for it and those who do can call `loadEnv()` in a loop anyway.In addition to $path (.env), the following files are loaded, the latter taking precedence in this order:.env < env.local < .env.$env < .env.$env.localNote that `loadForEnv()` used to give higher precedence to .env.local vs .env.$env.The new behavior is aligned with [the order used by create-react-app](https://github.com/facebook/create-react-app/blob/master/docusaurus/docs/adding-custom-environment-variables.md#what-other-env-files-can-be-used). It also allows overriding the env in .env.local, which should be convenient for DX.Last but not least, the "test" env has this special behaviors:- `.env.local` file is skipped for the "test" env (same as before and as in create-react-app)- ~vars defined in .env files **override** real env vars (similar to what Rails' dotenv does: you don't want your tests to randomly fail because of some real env vars)~.Commits-------0cf9acb [Dotenv] add loadEnv(), a smoother alternative to loadForEnv()
@bouland
Copy link
Contributor

bouland commentedMar 21, 2019
edited
Loading

Hi,

This "Ruby's dotenv behavior" is BC for all tools using ".env traditional behaviour" which is to store a lot of command lines arguments value andstore secrets.

My main difficulty is with this last point. Cf.What Changed Exactly?

B) The .env file is now commited to your repository.

Check this illustration withdocker-compose to build the followingDockerfile :

FROM registry.access.redhat.com/rhel7/rhelARG PASSWORD

With the following tips Cf.docker compose args

You can omit the value when specifying a build argument, in which case its value at build time is the value in the environment where Compose is running.

services:web:build:context:docker/webargs:                -PASSWORD

And command line ".env traditional behaviour"explain Cf.docker compose env

Compose supports declaring default environment variables in an environment file named .env placed in the folder where the docker-compose command is executed (current working directory).

Will proposedocker-compose to adopt "Ruby's dotenv behavior"

extra thoughts

  • a dot file is hidden on Unix FS
  • .env is a conventional name shared across multiple tools
    best practice is to use command / service (.composer / .nvm /.java )
    why not.symfony ?
  • I used to createlocal environment on my desktop and keepdev for integration on shared dev server, so weird result.env.local.local

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@weaverryanweaverryanweaverryan left review comments

@ycerutoycerutoyceruto left review comments

@fabpotfabpotfabpot approved these changes

@nicolas-grekasnicolas-grekasnicolas-grekas approved these changes

@chalasrchalasrchalasr approved these changes

+6 more reviewers

@WironeWironeWirone left review comments

@TobionTobionTobion left review comments

@fbourigaultfbourigaultfbourigault left review comments

@andersonamullerandersonamullerandersonamuller left review comments

@ogizanagiogizanagiogizanagi approved these changes

@maxheliasmaxheliasmaxhelias approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

4.2

Development

Successfully merging this pull request may close these issues.

18 participants

@dunglas@Wirone@fbourigault@teohhanhui@fabpot@ro0NL@jaikdean@weaverryan@nicolas-grekas@ryanotella@bouland@Tobion@andersonamuller@yceruto@ogizanagi@chalasr@maxhelias@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp