Skip to content

Commit

Permalink
Merge pull request #727 from simschla/feature/add-support-for-npmrc
Browse files Browse the repository at this point in the history
adding support for npmrc (detection & configuration)
  • Loading branch information
simschla authored Nov 2, 2020
2 parents dc0db92 + 4eb8ef1 commit b69a96a
Show file tree
Hide file tree
Showing 25 changed files with 614 additions and 116 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* Added support to npm-based steps for picking up `.npmrc` files ([#727](https://github.com/diffplug/spotless/pull/727))

## [2.9.0] - 2020-10-20
### Added
Expand Down
26 changes: 26 additions & 0 deletions gradle/spotless-freshmark.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@

import java.util.regex.Matcher
import java.util.regex.Pattern


def thisVm() {
String jre = System.getProperty("java.version")
if (jre.startsWith("1.8")) {
return 8
} else {
Matcher matcher = Pattern.compile("(\\d+)").matcher(jre)
if (!matcher.find()) {
throw new IllegalArgumentException("Expected " + jre + " to start with an integer")
}
int version = Integer.parseInt(matcher.group(1))
if (version <= 8) {
throw new IllegalArgumentException("Expected " + jre + " to start with an integer greater than 8")
}
return version
}
}

if (thisVm() >= 15) {
// freshmark doesn't run on JRE 15+
return
}

apply plugin: 'com.diffplug.spotless'

import com.diffplug.gradle.spotless.FreshMarkExtension
Expand Down
215 changes: 215 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/npm/FileFinder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
* Copyright 2020 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 static java.util.Objects.requireNonNull;

import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

class FileFinder {

private final List<Supplier<Optional<File>>> fileCandidateFinders;

private FileFinder(Builder builder) {
this.fileCandidateFinders = Collections.unmodifiableList(new ArrayList<>(builder.candidateFinders));
}

static Builder finderForFilename(String fileName) {
return new Builder(fileName, null);
}

static Builder finderForExecutableFilename(String fileName) {
return new Builder(fileName, true);
}

Optional<File> tryFind() {
return fileCandidateFinders
.stream()
.map(Supplier::get)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
}

static class Builder {

private final String fileName;

private final Boolean executable;

private final List<Supplier<Optional<File>>> candidateFinders = new ArrayList<>();

Builder(String fileName, Boolean executable) {
this.fileName = requireNonNull(fileName);
this.executable = executable;
}

public Builder candidateEnvironmentPath(String environmentVar) {
candidateFinders.add(new CandidateOnSinglePathEnvironmentVar(environmentVar, fileName, FileIsExecutableFilter.executable(this.executable)));
return this;
}

public Builder candidateEnvironmentPathList(String environmentVar, Function<File, File> fileTransformer) {
candidateFinders.add(new CandidateOnPathListEnvironmentVar(environmentVar, fileName, fileTransformer, FileIsExecutableFilter.executable(this.executable)));
return this;
}

public Builder candidateSystemProperty(String systemProperty) {
candidateFinders.add(new CandidateOnSystemPropertyVar(systemProperty, FileIsExecutableFilter.executable(this.executable)));
return this;
}

public Builder candidateFileInFolder(File folder) {
candidateFinders.add(new CandidateInFolder(folder, fileName, FileIsExecutableFilter.executable(this.executable)));
return this;
}

public FileFinder build() {
return new FileFinder(this);
}
}

private static class FileIsExecutableFilter implements Predicate<File> {
@Override
public boolean test(File file) {
return file.canExecute();
}

static Predicate<File> executable() {
return new FileIsExecutableFilter();
}

static Predicate<File> executable(Boolean executable) {
if (executable == null) {
return AnyFileFilter.any();
}
if (executable) {
return executable();
}
// !executable
return executable().negate();
}
}

private static class AnyFileFilter implements Predicate<File> {

@Override
public boolean test(File file) {
return true;
}

static AnyFileFilter any() {
return new AnyFileFilter();
}
}

private static class CandidateOnSinglePathEnvironmentVar implements Supplier<Optional<File>> {
private final String environmentVar;
private final String fileName;
private final Predicate<File> additionalFilters;

public CandidateOnSinglePathEnvironmentVar(String environmentVar, String fileName, Predicate<File> additionalFilter) {
this.environmentVar = environmentVar;
this.fileName = fileName;
this.additionalFilters = additionalFilter == null ? AnyFileFilter.any() : additionalFilter;
}

@Override
public Optional<File> get() {
return Optional.ofNullable(environmentVar)
.map(File::new)
.map(file -> new File(file, fileName))
.filter(File::exists)
.filter(additionalFilters);
}
}

private static class CandidateOnPathListEnvironmentVar implements Supplier<Optional<File>> {
private final String environmentVar;
private final String fileName;
private final Function<File, File> fileTransformer;
private final Predicate<File> additionalFilter;

public CandidateOnPathListEnvironmentVar(String environmentVar, String fileName, Function<File, File> fileTransformer, Predicate<File> additionalFilter) {
this.environmentVar = environmentVar;
this.fileName = fileName;
this.fileTransformer = fileTransformer;
this.additionalFilter = additionalFilter;
}

@Override
public Optional<File> get() {
String pathList = System.getenv(environmentVar);
if (pathList != null) {
return Arrays.stream(pathList.split(System.getProperty("path.separator", ":")))
.map(File::new)
.filter(File::exists)
.map(fileTransformer)
.map(dir -> new File(dir, fileName))
.filter(File::exists)
.filter(additionalFilter)
.findFirst();
}
return Optional.empty();
}
}

private static class CandidateOnSystemPropertyVar implements Supplier<Optional<File>> {
private final String systemProperty;
private final Predicate<File> additionalFilter;

public CandidateOnSystemPropertyVar(String systemProperty, Predicate<File> additionalFilter) {
this.systemProperty = systemProperty;
this.additionalFilter = additionalFilter == null ? AnyFileFilter.any() : additionalFilter;

}

@Override
public Optional<File> get() {
return Optional.ofNullable(System.getProperty(this.systemProperty))
.map(File::new)
.filter(File::exists)
.filter(additionalFilter);
}
}

private static class CandidateInFolder implements Supplier<Optional<File>> {

private final File folder;
private final String fileName;
private final Predicate<File> additionalFilter;

public CandidateInFolder(File folder, String fileName, Predicate<File> additionalFilter) {
this.folder = folder;
this.fileName = fileName;
this.additionalFilter = additionalFilter == null ? AnyFileFilter.any() : additionalFilter;
}

@Override
public Optional<File> get() {
return Optional.of(folder)
.filter(File::exists)
.filter(File::isDirectory)
.map(folder -> new File(folder, fileName))
.filter(File::exists)
.filter(additionalFilter);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ class NodeServerLayout {
private final File nodeModulesDir;
private final File packageJsonFile;
private final File serveJsFile;
private final File npmrcFile;

NodeServerLayout(File buildDir, String stepName) {
this.nodeModulesDir = new File(buildDir, "spotless-node-modules-" + stepName);
this.packageJsonFile = new File(nodeModulesDir, "package.json");
this.serveJsFile = new File(nodeModulesDir, "serve.js");
this.npmrcFile = new File(nodeModulesDir, ".npmrc");
}

File nodeModulesDir() {
Expand All @@ -40,4 +42,8 @@ File packageJsonFile() {
File serveJsFile() {
return serveJsFile;
}

public File npmrcFile() {
return npmrcFile;
}
}
11 changes: 9 additions & 2 deletions lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,21 @@

class NpmConfig implements Serializable {

private static final long serialVersionUID = -7660089232952131272L;
private static final long serialVersionUID = 684264546497914877L;

private final String packageJsonContent;

private final String npmModule;

private final String serveScriptContent;

public NpmConfig(String packageJsonContent, String npmModule, String serveScriptContent) {
private final String npmrcContent;

public NpmConfig(String packageJsonContent, String npmModule, String serveScriptContent, String npmrcContent) {
this.packageJsonContent = packageJsonContent;
this.npmModule = npmModule;
this.serveScriptContent = serveScriptContent;
this.npmrcContent = npmrcContent;
}

public String getPackageJsonContent() {
Expand All @@ -47,4 +50,8 @@ public String getNpmModule() {
public String getServeScriptContent() {
return serveScriptContent;
}

public String getNpmrcContent() {
return npmrcContent;
}
}
Loading

0 comments on commit b69a96a

Please sign in to comment.