Repository navigation
Expand file tree
/
Copy pathDirectory.Build.targets
More file actions
98 lines (76 loc) · 4.44 KB
/
Copy pathDirectory.Build.targets
File metadata and controls
98 lines (76 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<Project>
<!--
Where the TypeScript compiler comes from.
WWCP_WebAPI, which builds HTTPRoot scripts, used to run a bare "tsc",
which means the one installed globally on whichever machine is building.
That is wrong twice over.
It is not there. A fresh Debian with Node.js but no "npm install -g
typescript" stops the build with
error MSB3073: The command "tsc" exited with code 127
which is the shell saying "no such command" dressed as an MSBuild error.
And where it is there, it is whatever version that machine happens to
have. The emitted .js files are checked in, so the version decides their
bytes: 6.0.3 reproduces defaults.js as committed here, and a 5.x compiler
drops the "use strict" line from it. Pinned to the same version as
WWCP_OCPP, which measured the same question from the other side.
A build that changed nothing must leave the working tree clean, and since
the build stamp that is doubly true: a tree git calls dirty is a build
stamped "-dirty", and a marker nobody believes is worse than no marker.
.gitattributes beside this file finishes that job - the compiler writes
exactly the bytes that are committed, and core.autocrlf must not rewrite
them on the way out.
-->
<!--
And the same for the stylesheets, which is the same fault twice.
HTTPRoot/css is generated from the .scss files beside it, gitignored, and
embedded as a resource - so a machine where nobody had run compileSASS.sh
could not build this project at all:
error CS1566: Fehler beim Lesen der Ressource
"...HTTPRoot.css.chargingSessions.chargingSessions.css"
which names the missing file and not the missing step. That script needed
"sass" and "jq" installed globally, the same arrangement that made "tsc"
fail, so it is now a wrapper around compileSASS.mjs and the compiler is
pinned in package.json like the other one.
NodeToolsRoot rather than TypeScriptRoot, which is what WWCP_OCPP calls
the same directory: there it holds one tool and the name is the truth,
here it holds two.
-->
<PropertyGroup>
<NodeToolsRoot>$([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)'))</NodeToolsRoot>
<TypeScriptCompiler>$(NodeToolsRoot)node_modules/typescript/bin/tsc</TypeScriptCompiler>
<StylesheetCompiler>$(NodeToolsRoot)compileSASS.mjs</StylesheetCompiler>
</PropertyGroup>
<!--
"npm ci" when what it installs has changed, and not otherwise.
The first attempt asked only whether node_modules existed, and that was
wrong in the one case that was certain to happen: a machine that had
already built with the TypeScript compiler had the directory, so when
package.json gained sass the install was skipped and the build died with
[ERR_MODULE_NOT_FOUND]: Cannot find package 'sass'
on a tree where package-lock.json plainly named it. Reported from a Linux
machine within the hour, and reproducible here by deleting one package out
of node_modules.
So the lock file is the input and a stamp inside node_modules is the
output, which is what MSBuild's own up-to-date check is for: touch the
lock, the install runs; leave it alone and it does not, whatever else is
in the directory.
And once, not once per project. This used to say that two projects
starting "npm ci" here at the same moment was a first-build-only window in
which the loser merely reinstalls. It was not: npm ci begins by deleting
node_modules, so the loser's install pulled the compiler out from under the
winner's tsc, which failed with "Cannot find name 'document'" against a
tsconfig that lists DOM - and on Windows the two installs fought over open
files and died with EPERM. The window is every build in which an install is
due, which is every CI runner. restoreNodeTools.mjs beside this does the
install under a lock and asks again once it holds it, so the first project
installs and the others wait and find nothing left to do.
Inputs and Outputs stay, as the cheap first question: a build with nothing
to install does not start Node for it at all.
-->
<Target Name="RestoreNodeTools"
Condition="'$(DesignTimeBuild)' != 'true'"
Inputs="$(NodeToolsRoot)package-lock.json"
Outputs="$(NodeToolsRoot)node_modules/.npm-ci-stamp">
<Exec Command="node "$(NodeToolsRoot)restoreNodeTools.mjs"" WorkingDirectory="$(NodeToolsRoot)" />
</Target>
</Project>