dub icon indicating copy to clipboard operation
dub copied to clipboard

WIP: refactor commands & environment variables

Open WebFreak001 opened this issue 3 years ago • 22 comments
trafficstars

Environment variables are now consistent with custom command variables and are properly substituted at command run time to match with the recipe variables.

Additionally this fixes issue #2229 where sourceLibrary variables would get expanded later with wrong package dir, etc.

Might resolve issue #276 as well.

cc @rikkimax @veelo

WebFreak001 avatar May 16 '22 14:05 WebFreak001

What I am looking for in either this PR or a follow up is moving the variable substitution stuff out into it's own module.

It is fairly self contained logic but it is spread out over a few different files in random locations.

Also differentiating between early and just in time substitution might be a good thing too.

I'll review properly once I wake up (I really shouldn't be reviewing in bed on mobile! Lol).

On Tue, May 17, 2022, 02:17 Jan Jurzitza @.***> wrote:

@.**** commented on this pull request.

In source/dub/generators/generator.d https://github.com/dlang/dub/pull/2251#discussion_r873783408:

	}
  • // propagate dependency environment variables to root
    
  • // foreach (pack; m_project.getTopologicalPackageList(false, null, configs)) {
    
  • // 	auto ti = pack.name in targets;
    
  • // 	auto parentEnvs = pack.name in envs;
    
  • // 	foreach (deppkgName, depInfo; pack.getDependencies(ti.config)) {
    
  • // 		if (auto childEnvs = deppkgName in envs) {
    
  • // 			childEnvs.update(ti.buildSettings);
    
  • // 			parentEnvs.update(childEnvs);
    
  • // 		}
    
  • // 	}
    
  • // }
    

note: there was still some issue here

— Reply to this email directly, view it on GitHub https://github.com/dlang/dub/pull/2251#pullrequestreview-974038662, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHSL47UF5WCJFTMHORASZ3VKJKGFANCNFSM5WBUOVBA . You are receiving this because you were mentioned.Message ID: @.***>

rikkimax avatar May 16 '22 14:05 rikkimax

I really appreciate the work on this!

veelo avatar May 16 '22 14:05 veelo

Apart from acknowledging CI is failing and there is a bunch of code commented out, looking like it's going in the right direction.

I stand by what I said earlier about splitting out the variable substitution stuff entirely into its own module. It's all far too spread out yet so simple (in theory at least).

rikkimax avatar May 16 '22 17:05 rikkimax

Do you have time to continue work on this, or do you want me to try and pick this up?

veelo avatar May 23 '22 11:05 veelo

right now this rework broke support for inheriting set environment variables from dependencies, so I think that's all that needs to be fixed here. I will fix that myself, not sure if other things are missing right now.

WebFreak001 avatar May 23 '22 12:05 WebFreak001

Alright thank you, let me know if I can help in any way.

veelo avatar May 23 '22 12:05 veelo

I will fix that myself

Friendly ping @WebFreak001 to let you know that we are still held back by #2229.

veelo avatar Jul 08 '22 14:07 veelo

WTF how do these changes break the sanitize function of std.encoding inside commandline.d?!

source/dub/commandline.d(440,51): Error: function `std.encoding.sanitize!char.sanitize` at /Users/runner/hostedtoolcache/dc/ldc2-1.30.0/x64/ldc2-1.30.0-osx-universal/bin/../import/std/encoding.d(1846,16) conflicts with function `std.encoding.sanitize!char.sanitize` at /Users/runner/hostedtoolcache/dc/ldc2-1.30.0/x64/ldc2-1.30.0-osx-universal/bin/../import/std/encoding.d(1846,16)

WebFreak001 avatar Jan 08 '23 19:01 WebFreak001

I actually just noticed there are libraries on DUB that already rely on the behavior that sourceLibrary environment variables would get inherited into the package. (well it's my own library, dorm, but I didn't think of this issue when I added the commands and it might be used elsewhere too) https://github.com/rorm-orm/dorm/blob/eeb575b36dc40778b3b509bdfeb9b1cf7924f141/build-models/dub.sdl

@Geod24 what do you think? Should we make sourceLibrary commands (preBuild/postBuild/preGenerate/postGenerate/preRun/postRun) expand variables from the context of the sourceLibrary package or in the context of the package that depends on the source lib?

Commands that are inherited only run inside the context of the package that depends on the source lib, because a source library does not have run or build stages.

WebFreak001 avatar Jan 08 '23 19:01 WebFreak001

@veelo how are you using the commands / why do you need the package path of the source library (and not change the source library to a regular library instead?)

We could also think about adding some $SOURCE_PACKAGE_PATH variable that's only valid in the context of source libraries, if we go with making the commands use the environment variables of the depender package.

Right now a workaround to add a dummy "library" package that's just there to run commands should work as well, if we decide to keep this behavior.

WebFreak001 avatar Jan 08 '23 19:01 WebFreak001

We shouldn't break people's packages where possible. But I do think it needs to be configurable via the map syntax that we talked about previously.

rikkimax avatar Jan 08 '23 19:01 rikkimax

how about we throw away this PR and do the different command running syntax instead, adding a property to specify where the commands should be run? (although I can see that that might make the code flow a bit confusing)

WebFreak001 avatar Jan 08 '23 19:01 WebFreak001

So something like?

{
    "command": [
        "shell",
        {
             "shell": ["shells"],
             "compileAndRun": ["file.d"],
             "workingDirectory": "$EXEorSO_DIR",
             "envSource": "this/exeOrSO",
             "trigger": "default/always/never"
        }
    ]
}

rikkimax avatar Jan 08 '23 19:01 rikkimax

Thank you very much for picking this up again.

@veelo how are you using the commands / why do you need the package path of the source library (and not change the source library to a regular library instead?)

I use these commands to generate various (re)sources, like

	"preGenerateCommands": [
		"rdmd pvmake.d $PACKAGE_DIR/import"
	],
	"preBuildCommands": [
		"cd $PACKAGE_DIR && rdmd tvmake.d $PACKAGE_DIR"
	],

The wish to use these from a sourceLibrary package as opposed to a library package is admittedly unorthodox. We have around twenty programs that all use various modules from a large collection of shared sources. In order to not maintain 20 different dub.json files explicitly stating the various modules that each program depends on, we let the compiler figure out the dependencies using the -i option. Since Dub doesn't really support that, I had to find a work around. The work around is to have a package without sources and only build options, flags, preBuildCommands and of course importPaths. Dub complains if you try to configure a library without sources, so I had to make it a sourceLibrary. It kind of makes sense, because there is no artifact either from this package.

We could also think about adding some $SOURCE_PACKAGE_PATH variable that's only valid in the context of source libraries, if we go with making the commands use the environment variables of the depender package.

I guess that would work for me.

Right now a workaround to add a dummy "library" package that's just there to run commands should work as well, if we decide to keep this behavior.

That would require a dummy source file as well, and produce an artifact to link in.

Another example where we use postBuildCommands is

{
	"name": "ctups",
	"description": "Binding to Existec ctups",
	"homepage": "https://existec.com/product/hazcheck-toolkits/",
	"authors": [
		"SARC"
	],
	"copyright": "Copyright © 2022, SARC B.V.",
	"license": "proprietary",
	"targetType": "sourceLibrary",
	"targetPath": "$PACKAGE_DIR/../../bin",
	"sourceFiles": [
		"source/ctups.lib"
	],
	"copyFiles": [
		"source/ctups.dll",
		"source/subs.ind",
		"source/libiomp5md.dll",
		"source/frglobe.msg"
	],
	"comment": "https://github.com/dlang/dub/issues/2234",
	"postBuildCommands-windows": [
		"attrib -R %DUB_TARGET_PATH%/ctups.dll",
		"attrib -R %DUB_TARGET_PATH%/subs.ind"
	]
}

to change file attributes on 3rd party DLLs. This is a sourceLibrary because the only D source in it contains the header to the library, the .lib is supplied and should not be overwritten by this package.

Third example is similar to the second: a 3rd party lib where preGenerateCommands are used to run dpp:

{
	"name": "wibu",
	"description": "Protection implementation using the Wibu CodeMeter API.",
	"authors": [
		"Bastiaan N. Veelo"
	],
	"copyright": "Copyright © 2018, SARC B.V.",
	"license": "proprietary",
	"targetType": "sourceLibrary",
	"libs": [
		"$PACKAGE_DIR/WibuCm32"
	],
	"excludedSourceFiles": [
		"source/make.d"
	],
	"preGenerateCommands": [
		"cd $PACKAGE_DIR/source && rdmd make"
	]
}

with make.d:

import std;

void main()
{
  make(["sentinel.dpp"], ["sentinel.d"], ["dub", "run", "dpp", "--", "--preprocess-only", "sentinel.dpp"]);
}

void make(string[] input, string[] output, string[] args)
{
  input ~= __FILE__;
  if ((){
      foreach (outp; output)
      {
        immutable outpTime = timeLastModified(outp, SysTime.min);
        foreach (inp; input)
          if (timeLastModified(inp) > outpTime)
            return true;
      }
      return false;
    }())
  {
    stderr.writeln(args.joiner(" "));
    auto dmd = execute(args);
    enforce(dmd.status == 0, "Compilation failed:\n" ~ dmd.output);
  }
}

veelo avatar Jan 08 '23 20:01 veelo

Is a different syntax going to solve anything? I still think there needs to be a variable for commands in a sourceLibrary to refer to its own package dir, irrespective of the syntax for the commands.

veelo avatar Jan 08 '23 20:01 veelo

I actually just noticed there are libraries on DUB that already rely on the behavior that sourceLibrary environment variables would get inherited into the package. (well it's my own library, dorm, but I didn't think of this issue when I added the commands and it might be used elsewhere too) https://github.com/rorm-orm/dorm/blob/eeb575b36dc40778b3b509bdfeb9b1cf7924f141/build-models/dub.sdl

Pasting this in:

name "build-models"

targetType "sourceLibrary"

configuration "application" {
	postBuildCommands ".\\$DUB_ROOT_PACKAGE_TARGET_PATH$DUB_ROOT_PACKAGE_TARGET_NAME --DORM-dump-models-json" platform="windows"
	postBuildCommands "./$DUB_ROOT_PACKAGE_TARGET_PATH$DUB_ROOT_PACKAGE_TARGET_NAME --DORM-dump-models-json" platform="posix"
	versions "DormBuildModels"
}

These all concern the root package, so I don't understand how these would expand differently. The root package would be the same irrespective of this package being a library or a sourceLibrary, no? Maybe I misunderstand what a root package is.

veelo avatar Jan 08 '23 20:01 veelo

Is a different syntax going to solve anything? I still think there needs to be a variable for commands in a sourceLibrary to refer to its own package dir, irrespective of the syntax for the commands.

Unfortunately, it would yes. Not all compilers support -run and rdmd is not always available. I personally am affected by commands triggering a rebuild and I want to disable that. Basically, the map would allow us to configure its behavior in more desirable ways and not be limited to using shell commands (which there might not be a shell!).

rikkimax avatar Jan 08 '23 20:01 rikkimax

@veelo the code in dorm runs the app that has just being built (the root package of the user) with special flags that are handled by that dependency in a module constructor.

WebFreak001 avatar Jan 08 '23 20:01 WebFreak001

@WebFreak001 OK, but the meaning of root package should be the same, be it a library or sourceLibrary, right?

veelo avatar Jan 08 '23 20:01 veelo

hmm unsure about root package, it's a quite random concept I think - what's the root package if your root package is sourceLibrary? I think in that case rootPackage should still refer to the package that is being built. (the depender)

WebFreak001 avatar Jan 08 '23 21:01 WebFreak001

If the introduction of $SOURCE_PACKAGE_PATH makes anything easier, I would be happy with that. At least it gives me a way out of #2229, so I can move on.

veelo avatar Jan 08 '23 21:01 veelo

Right now a workaround to add a dummy "library" package that's just there to run commands should work as well, if we decide to keep this behavior.

That would require a dummy source file as well, and produce an artifact to link in.

For lack of an alternative, this is what I have started to resolve to.

veelo avatar Jan 19 '23 09:01 veelo