bdkjones / CodeKit

CodeKit 3 Issue Tracker
https://codekitapp.com
82 stars 5 forks source link

Environment Variables Are Not #669

Closed destructobeam closed 2 years ago

destructobeam commented 2 years ago

Quick, short summary:

A project's Environment doesn't have distinct Environment Variables outside of the auto NODE_ENV, making them not actually environment variables.

Expected results:

Should be distinct sets of keys/values

Actual results:

Not.

Exact steps to reproduce:

Set Environment for project, add Environment Variable, change Environment.

A link to download a simplified project or file that shows the issue:

N/A

Your configuration (any details about your system that you think might be relevant)

N/A


Thanks!

bdkjones commented 2 years ago

I don’t understand what you mean.

-Bryan

On Sep 22, 2021, at 03:39, destructobeam @.***> wrote:

 Quick, short summary:

A project's Environment doesn't have distinct Environment Variables outside of the auto NODE_ENV, making them not actually environment variables.

Expected results:

Should be distinct sets of keys/values

Actual results:

Not.

Exact steps to reproduce:

Set Environment for project, add Environment Variable, change Environment.

A link to download a simplified project or file that shows the issue:

N/A

Your configuration (any details about your system that you think might be relevant)

N/A

Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

bdkjones commented 2 years ago

I think what you're trying to say is you believe environment variables should change, automatically, based on whether Production or Development is selected.

That's not how they work. When you set an environment variable in Terminal ($PATH, for instance), that value does not change until you set it to something else. There is no concept of $PATH for "development" and $PATH for "production".

$NODE_ENV is just another variable; changing its value does not affect any other environment variables, such as $PATH.

When we say "environment variables", we do not refer to the environment specified by Node (production vs development). Instead, environment means "the context under which programs are run on this Mac." $NODE_ENV is just one setting in that context; it is not the context itself.

If you want different ENV variables for production and development, create two branches in your repo and configure the settings as you wish in each branch.

Pause CodeKit's file-watching when you switch branches, and the settings will change accordingly when you do.

destructobeam commented 2 years ago

Sorry, you misunderstand, I am saying that: there is a setting called Environment, and a section for Environment Variables, which should not change automatically, but should instead be two distinct sets of keys and values, the active "Environment" part of "Environment Variables" determined by the "Environment" setting.

Ignore $NODE_ENV for now (that was an example of something that sort of works but also shouldn't be "automatic"), that is just a Node convention, in every other build system you set your local environment for each target. The targets are arbitrary, in this case we have Development and Production. You are conflating exported environment variables for every sub-process, like $PATH, with the contextual environment variables for the current process (in this case the CodeKit build). In case you wanted to "override" $PATH locally for each target, variables have inheritance, e.g. PATH=$PATH:~/project/bin

Having to create a separate branch for what should be expected behaviour is a little unwieldy and not really what branches are for IMO.

Thanks!

bdkjones commented 2 years ago

The “Environment” popup button is a shortcut for NODE_ENV in the environment variables list. The two are always supposed to stay in sync.

All over environment variables in the list do not change.

-Bryan

On Sep 22, 2021, at 15:52, destructobeam @.***> wrote:

 Sorry, you misunderstand, I am saying that: there is a setting called Environment, and a section for Environment Variables, which should not change automatically, but should instead be two distinct sets of keys and values, the active "Environment" part of "Environment Variables" determined by the "Environment" setting.

Ignore $NODE_ENV for now (that was an example of something that sort of works but also shouldn't be "automatic"), that is just a Node convention, in every other build system you set your local environment for each target. The targets are arbitrary, in this case we have Development and Production. You are conflating exported environment variables for every sub-process, like $PATH, with the contextual environment variables for the current process (in this case the CodeKit build). In case you wanted to "override" $PATH locally for each target, variables have inheritance, e.g. PATH=$PATH:~/project/bin

Having to create a separate branch for what should be expected behaviour is a little unwieldy and not really what branches are for IMO.

Thanks!

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub, or unsubscribe.

destructobeam commented 2 years ago

That’s right, hence my opening this bug. All Environment variables should be target specific. For things like $PATH, if needed, should be an application setting, not a project setting.

destructobeam commented 2 years ago

Also, I know it’s not a terribly expensive app, but it would be nice to not just instantly close an issue without coming to some kind of resolution with the issue opener first. This should still be very much open IMO.

iocouto commented 2 years ago

@destructobeam you seem to be confusing "shell environment variables" with node "build environment values (=settings)". As a consequence, it seems you're wanting to set "shell environment variables" based on your selected node "build environment":

[...] All Environment variables should be target specific.

IMHO, definitely not.

The "build environment" setting - which you set in General -> General Project Settings -> Environment - is a setting commonly used by node-based tools (like Tailwind). These tools might load a different set of preferences, or perform custom build steps, depending on the 'environment' you've selected here. This is the purpose of this setting in CodeKit: to inform these node-based tools about your current node 'build environment'.

On the other hand, the 'environment variables' - which you set in General -> Environment Variables - are "shell environment variables": they are set by CodeKit just as if you had declared them directly in your Terminal app. They can be used, for example, in your own shell scripts, which you can use in CodeKit within custom hooks and build steps you define for your project.

For things like $PATH, if needed, should be an application setting, not a project setting.

Again, IMHO, definitely not: as different projects can have their own custom hooks and build systems, which require shell environment variables with different values, it is indeed a very handy feature to have CodeKit automagically set these variables for us on a project-by-project basis.

destructobeam commented 2 years ago

There is no distinction between shell environment variables and whatever you mean by “build” environment variables. There are contexts for running processes, like exports in bash/ZSH for sub-processes, locally set variables for a current process, but they all set the same type of variables.

I’m not confusing anything, I’m aware of the Node and Node based tooling using $NODE_ENV as a convention, and it is merely a convention. The fact that it is automatically set in CodeKit for the Environment setting indicates that they are at least partially aware of how process environments work. But I would be stunned if CodeKit itself was built the same environment for every target in XCode.

For other things like an API_PATH, ACCESS_TOKEN, etc, etc, these also need to be set per environment just like NODE_ENV is. Which I am unable to do.

iocouto commented 2 years ago

There is no distinction between shell environment variables and whatever you mean by “build” environment variables.[...]

From your answer, it seems you're used to dealing with certain tools - like Xcode - that use 'build targets' to load 'environment variables' that control your build process, and produce multiple output. Under this light, it's clear then why you don't understand what these different settings in CodeKit are supposed to do. You're bringing your compiler assumptions into CodeKit.

Frontend pre- & post-processing tools do NOT usually keep their build preferences in shell environment variables. Most standard node-based tools will read "build-time" variables from a config file - sometimes as an entry in your 'package.json', sometimes as a specific '.config' file. Some tools - like Parcel - do support compilation to multiple targets. In Parcel, for example, if you want to compile/bundle your javascript code for both browser and server/node environments, you can specify your separate targets (and their settings) as a single entry in your 'package.json' file. You don't need to set shell environment variables.

CodeKit, by default, only compiles to one single 'target' - one 'build' folder. However, if you do want to 'build' for multiple, different targets using CodeKit, you do have a couple of options. For starters, you can always do as @bdkjones suggested, and have your project setup in your VCS with multiple branches. Have each branch setup with different build settings. That would enable you, for example, to try out developing the same website using Tailwind with and without its JIT compiler, or targeting different browsers. Another option would be to use a custom build system - add custom steps to your build process in CodeKit, that might produce more than one target.

What you have been talking about, however, is to have CodeKit (re)set a whole bunch of shell environment variables - at application-level, no less, rather than at project-level. And to do it based on an arbitrary "environment" setting. That is not a usual requirement for a frontend or even node-based dev. It might be helpful if you can give a concrete example of a project where you're thinking of using this feature, and how it would work.

destructobeam commented 2 years ago

@iocouto No, I don't use Xcode often, and Environment variables apply to every process on a UNIX system, and most build tools in varying degrees, as well as compiled and interpreted languages, all of which I do use, not just things you run from the shell. You are being extremely presumptuous, and I don't mean to be rude, but maybe brush up on how your operating system works before stating I am assuming things: https://en.m.wikipedia.org/wiki/Environment_variable

Yeah, no front end tools use environment variables: https://vitejs.dev/guide/env-and-mode.html https://www.snowpack.dev/reference/environment-variables https://webpack.js.org/api/cli https://rollupjs.org/guide/en/#--environment-values

Just because you don't have a use for them, doesn't mean others don't. I use them for pure front-end, SSR front end, backend code, for compiled "apps", and interpreted scripts.

I gave examples of environment variables I use at the end of my previous comment.

iocouto commented 2 years ago

@destructobeam I have tried being as helpful as I can, but I'm afraid my attempts are being misunderstood.

I have not been able to see how the feature you seem to be asking for - namely, to switch sets of shell environment variables on-the-fly, for the entire application (not just the current project), based on an arbitrary 'environment' setting - would provide a solution that is not already covered by the current functionality, in a more 'standard' way. I suspect that @bdkjones might have closed this issue for the same reason.

I kindly suggest once again that you provide a concrete example of a project where you'd use these features - and how they would work better than the solutions we currently have already. Once again, I emphasise that this would be helpful in clarifying what your actual requirement is, and what it is that CodeKit is not addressing for you.

Could you do that?

destructobeam commented 2 years ago

@iocouto You are misunderstanding what I am suggesting:

I am suggesting the project Environment setting, should have a distinct list of environment variables/values. Not anything automatic.

So in the predefined Development target, your $API_PATH for your build scripts and rollup constants would equal something like http://localhost:5000/v1, and when you change that switch to create a build for the predefined Production target, that $API_PATH would equal https://api.production-website.example/v1

Does that make sense? Using version control for this is possible, just very cludgey when $NODE_ENV works the right way (except it is automatic).

iocouto commented 2 years ago

Thanks, @destructobeam - I think I'm starting to understand what you want better.

There are a couple of things about CodeKit - and its 'philosophy' - that we should keep in mind. The first, is that the whole 'raison d'être' of CodeKit is to make configuration of all these tools easy, quick and visual. So, in CodeKit, if the user wants to do something like changing the output path of their compiled JS file, they are expected to do it directly in the UI: we can do that in the 'Javascript' preferences. We should be able to tweak all the main settings - like minification, transpilation, etc. - directly in the Preferences for the language itself, or for the tool (like in the Babel, Terser or Rollup Preferences). CodeKit does not expect the user to set shell environment variables to control these settings, and doing so would probably not be as easy, or quick, or visual, as what we already have today.

The second thing is that CodeKit right now is really meant to produce only ONE 'build' - ie., it will (usually) compile to one 'build' folder. I say 'usually', because as I mentioned before, there are a couple of ways to get around that limitation - eg., with custom build steps, or even using repository branches. I agree with you, that this is not the most 'quick, easy and visual' way of doing this, so perhaps THIS is the use-case we should be focusing on: getting CodeKit to be able to produce multiple builds, with different settings.

Then, the question becomes: for whom is this actually needed? We have to remember that CodeKit is essentially a frontend tool, targeting web developers who use HTML/CSS/JS and related frontend frameworks. In this field, the people who usually need 'multiple builds' are high-end JS developers - usually people working on JS libraries and frameworks, which need to be bundled in various formats (eg., to be used on the browser as well as a node module on a node server). But to be honest, it's unlikely that these developers would be using a tool like CodeKit: they're more likely to be using something like Parcel (which has automatic targeting and configuration for multiple outputs), or other more 'manual' tools - like webpack - that are unfriendly, but configurable to the extreme, and not scary to them. So, I could be wrong, but I think that the number of developers that would be interested in this kind of functionality, from CodeKit, would be quite small - and probably not the niche that CodeKit targets. But I could be wrong, so I wouldn't discourage you from posting a separate issue, asking for that feature, specifically.

@bdkjones is super helpful, and really listens to his users, but he is a one-man band, and has to prioritise his time really well. If you post a concise and clear feature request, and it gathers enough interest from other users here, he'll certainly look at it.

destructobeam commented 2 years ago

@iocouto These wouldn’t be seperate builds, they would be the same build with different configurations for developing a site, and publishing a site (same sources, same build destinations).

It’s incongruous at the moment because the settings are called “Environment” and “Environment Variables”, in every other dev tool I’ve come across, and UNIX in general, these mean something specific (naming is hard and important).

This is all why it’s more of a bug report than a feature request. A possible fix being to simply rename the “Environment” setting in the project to “Build For”, or “Optimisations”.

Normally I would be using something like Vite and Svelte/SvelteKit, but for my current project that is outside of client requirements. So instead of charging them a decent chunk of change for the time needed to write a Vite (or any other front end build tool) plugin for integrating with their existing backend templates, CodeKit seemed like an interesting possible alternative.

I don’t know about all the users of the app, and I admit I probably have pretty complex requirements in the context of a GUI build tool, but that is all outside of how things are presented in the app, in this specific issue I’ve raised.