-
Notifications
You must be signed in to change notification settings - Fork 458
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…and #1582)
- Loading branch information
Showing
40 changed files
with
1,966 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright 2023 DiffPlug | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.diffplug.spotless.npm; | ||
|
||
import java.util.Objects; | ||
|
||
import javax.annotation.Nonnull; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class NodeApp { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(NodeApp.class); | ||
|
||
private static final TimedLogger timedLogger = TimedLogger.forLogger(logger); | ||
|
||
@Nonnull | ||
protected final NodeServerLayout nodeServerLayout; | ||
|
||
@Nonnull | ||
protected final NpmConfig npmConfig; | ||
|
||
@Nonnull | ||
protected final NpmProcessFactory npmProcessFactory; | ||
|
||
@Nonnull | ||
protected final NpmFormatterStepLocations formatterStepLocations; | ||
|
||
public NodeApp(@Nonnull NodeServerLayout nodeServerLayout, @Nonnull NpmConfig npmConfig, @Nonnull NpmFormatterStepLocations formatterStepLocations) { | ||
this.nodeServerLayout = Objects.requireNonNull(nodeServerLayout); | ||
this.npmConfig = Objects.requireNonNull(npmConfig); | ||
this.npmProcessFactory = processFactory(formatterStepLocations); | ||
this.formatterStepLocations = Objects.requireNonNull(formatterStepLocations); | ||
} | ||
|
||
private static NpmProcessFactory processFactory(NpmFormatterStepLocations formatterStepLocations) { | ||
if (formatterStepLocations.cacheDir() != null) { | ||
logger.info("Caching npm install results in {}.", formatterStepLocations.cacheDir()); | ||
return NodeModulesCachingNpmProcessFactory.create(formatterStepLocations.cacheDir()); | ||
} | ||
logger.debug("Not caching npm install results."); | ||
return StandardNpmProcessFactory.INSTANCE; | ||
} | ||
|
||
boolean needsNpmInstall() { | ||
return !this.nodeServerLayout.isNodeModulesPrepared(); | ||
} | ||
|
||
boolean needsPrepareNodeAppLayout() { | ||
return !this.nodeServerLayout.isLayoutPrepared(); | ||
} | ||
|
||
void prepareNodeAppLayout() { | ||
timedLogger.withInfo("Preparing {} for npm step {}.", this.nodeServerLayout, getClass().getName()).run(() -> { | ||
NpmResourceHelper.assertDirectoryExists(nodeServerLayout.nodeModulesDir()); | ||
NpmResourceHelper.writeUtf8StringToFile(nodeServerLayout.packageJsonFile(), this.npmConfig.getPackageJsonContent()); | ||
if (this.npmConfig.getServeScriptContent() != null) { | ||
NpmResourceHelper.writeUtf8StringToFile(nodeServerLayout.serveJsFile(), this.npmConfig.getServeScriptContent()); | ||
} else { | ||
NpmResourceHelper.deleteFileIfExists(nodeServerLayout.serveJsFile()); | ||
} | ||
if (this.npmConfig.getNpmrcContent() != null) { | ||
NpmResourceHelper.writeUtf8StringToFile(nodeServerLayout.npmrcFile(), this.npmConfig.getNpmrcContent()); | ||
} else { | ||
NpmResourceHelper.deleteFileIfExists(nodeServerLayout.npmrcFile()); | ||
} | ||
}); | ||
} | ||
|
||
void npmInstall() { | ||
timedLogger.withInfo("Installing npm dependencies for {} with {}.", this.nodeServerLayout, this.npmProcessFactory.describe()) | ||
.run(() -> npmProcessFactory.createNpmInstallProcess(nodeServerLayout, formatterStepLocations).waitFor()); | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
lib/src/main/java/com/diffplug/spotless/npm/NodeModulesCachingNpmProcessFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* Copyright 2023 DiffPlug | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.diffplug.spotless.npm; | ||
|
||
import java.io.File; | ||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import javax.annotation.Nonnull; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.diffplug.spotless.ProcessRunner.Result; | ||
|
||
public class NodeModulesCachingNpmProcessFactory implements NpmProcessFactory { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(NodeModulesCachingNpmProcessFactory.class); | ||
|
||
private static final TimedLogger timedLogger = TimedLogger.forLogger(logger); | ||
|
||
private final File cacheDir; | ||
|
||
private final ShadowCopy shadowCopy; | ||
|
||
private NodeModulesCachingNpmProcessFactory(@Nonnull File cacheDir) { | ||
this.cacheDir = Objects.requireNonNull(cacheDir); | ||
assertDir(cacheDir); | ||
this.shadowCopy = new ShadowCopy(cacheDir); | ||
} | ||
|
||
private void assertDir(File cacheDir) { | ||
if (cacheDir.exists() && !cacheDir.isDirectory()) { | ||
throw new IllegalArgumentException("Cache dir must be a directory"); | ||
} | ||
if (!cacheDir.exists()) { | ||
if (!cacheDir.mkdirs()) { | ||
throw new IllegalArgumentException("Cache dir could not be created."); | ||
} | ||
} | ||
} | ||
|
||
public static NodeModulesCachingNpmProcessFactory create(@Nonnull File cacheDir) { | ||
return new NodeModulesCachingNpmProcessFactory(cacheDir); | ||
} | ||
|
||
@Override | ||
public NpmProcess createNpmInstallProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations) { | ||
NpmProcess actualNpmInstallProcess = StandardNpmProcessFactory.INSTANCE.createNpmInstallProcess(nodeServerLayout, formatterStepLocations); | ||
return new CachingNmpInstall(actualNpmInstallProcess, nodeServerLayout); | ||
} | ||
|
||
@Override | ||
public NpmLongRunningProcess createNpmServeProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations) { | ||
return StandardNpmProcessFactory.INSTANCE.createNpmServeProcess(nodeServerLayout, formatterStepLocations); | ||
} | ||
|
||
private class CachingNmpInstall implements NpmProcess { | ||
|
||
private final NpmProcess actualNpmInstallProcess; | ||
private final NodeServerLayout nodeServerLayout; | ||
|
||
public CachingNmpInstall(NpmProcess actualNpmInstallProcess, NodeServerLayout nodeServerLayout) { | ||
this.actualNpmInstallProcess = actualNpmInstallProcess; | ||
this.nodeServerLayout = nodeServerLayout; | ||
} | ||
|
||
@Override | ||
public Result waitFor() { | ||
String entryName = entryName(); | ||
if (shadowCopy.entryExists(entryName, NodeServerLayout.NODE_MODULES)) { | ||
timedLogger.withInfo("Using cached node_modules for {} from {}", entryName, cacheDir) | ||
.run(() -> shadowCopy.copyEntryInto(entryName(), NodeServerLayout.NODE_MODULES, nodeServerLayout.nodeModulesDir())); | ||
return new CachedResult(); | ||
} else { | ||
Result result = timedLogger.withInfo("calling actual npm install {}", actualNpmInstallProcess.describe()) | ||
.call(actualNpmInstallProcess::waitFor); | ||
assert result.exitCode() == 0; | ||
storeShadowCopy(entryName); | ||
return result; | ||
} | ||
} | ||
|
||
private void storeShadowCopy(String entryName) { | ||
timedLogger.withInfo("Caching node_modules for {} in {}", entryName, cacheDir) | ||
.run(() -> shadowCopy.addEntry(entryName(), new File(nodeServerLayout.nodeModulesDir(), NodeServerLayout.NODE_MODULES))); | ||
} | ||
|
||
private String entryName() { | ||
return nodeServerLayout.nodeModulesDir().getName(); | ||
} | ||
|
||
@Override | ||
public String describe() { | ||
return String.format("Wrapper around [%s] to cache node_modules in [%s]", actualNpmInstallProcess.describe(), cacheDir.getAbsolutePath()); | ||
} | ||
} | ||
|
||
private class CachedResult extends Result { | ||
|
||
public CachedResult() { | ||
super(List.of("(from cache dir " + cacheDir + ")"), 0, new byte[0], new byte[0]); | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
lib/src/main/java/com/diffplug/spotless/npm/NodeServeApp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright 2023 DiffPlug | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.diffplug.spotless.npm; | ||
|
||
import javax.annotation.Nonnull; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.diffplug.spotless.ProcessRunner; | ||
|
||
public class NodeServeApp extends NodeApp { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(NodeApp.class); | ||
|
||
private static final TimedLogger timedLogger = TimedLogger.forLogger(logger); | ||
|
||
public NodeServeApp(@Nonnull NodeServerLayout nodeServerLayout, @Nonnull NpmConfig npmConfig, @Nonnull NpmFormatterStepLocations formatterStepLocations) { | ||
super(nodeServerLayout, npmConfig, formatterStepLocations); | ||
} | ||
|
||
ProcessRunner.LongRunningProcess startNpmServeProcess() { | ||
return timedLogger.withInfo("Starting npm based server in {} with {}.", this.nodeServerLayout.nodeModulesDir(), this.npmProcessFactory.describe()) | ||
.call(() -> npmProcessFactory.createNpmServeProcess(nodeServerLayout, formatterStepLocations).start()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.