Skip to content

Commit

Permalink
Merge pull request #106 from snyk/feat/scalafix-and-project-layout-he…
Browse files Browse the repository at this point in the history
…uristics

feat: fix for scalafix and multi-project fodler layout heuristics
  • Loading branch information
muscar committed Mar 28, 2022
2 parents b2edcea + 2a307dd commit ebf261f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 16 deletions.
18 changes: 13 additions & 5 deletions lib/index.ts
Expand Up @@ -134,19 +134,27 @@ async function legacyInspect(root: string, targetFile: string, options: any) {

async function injectSbtScript(
sbtPluginPath: string,
targetFilePath: string,
targetFolderPath: string,
): Promise<InjectedScript> {
try {
// We could be running from a bundled CLI generated by `pkg`.
// The Node filesystem in that case is not real: https://github.com/zeit/pkg#snapshot-filesystem
// Copying the injectable script into a temp file.
let projectFolderPath = path.resolve(targetFolderPath, 'project/');
debug(`injectSbtScript: injecting snyk sbt plugin "${sbtPluginPath}" in "${projectFolderPath}"`);
if (!fs.existsSync(projectFolderPath)) {
debug(`injectSbtScript: "${projectFolderPath}" does not exist`);
projectFolderPath = path.resolve(targetFolderPath, '..', 'project/');
debug(`injectSbtScript: will try "${projectFolderPath}"`);
}
const tmpSbtPlugin = tmp.fileSync({
postfix: '-SnykSbtPlugin.scala',
dir: path.resolve(targetFilePath, 'project/'),
dir: projectFolderPath,
});
fs.createReadStream(sbtPluginPath).pipe(
fs.createWriteStream(tmpSbtPlugin.name),
);
debug(`successfully injected plugin at "${tmpSbtPlugin.name}"`);
return { path: tmpSbtPlugin.name, remove: tmpSbtPlugin.removeCallback };
} catch (error) {
error.message =
Expand Down Expand Up @@ -180,17 +188,17 @@ async function pluginInspect(
): Promise<types.PluginResult | null> {
let injectedScript: InjectedScript | undefined;
try {
const targetFilePath = path.dirname(path.resolve(root, targetFile));
const targetFolderPath = path.dirname(path.resolve(root, targetFile));
const sbtArgs = buildArgs(options.args, false, true);
const sbtVersion = await getSbtVersion(root, targetFile);
const sbtPluginPath = generateSbtPluginPath(sbtVersion);
const packageName = path.basename(root);
const packageVersion = '1.0.0';

injectedScript = await injectSbtScript(sbtPluginPath, targetFilePath);
injectedScript = await injectSbtScript(sbtPluginPath, targetFolderPath);
debug('injectedScript.path: ' + injectedScript.path);
const stdout = await subProcess.execute('sbt', sbtArgs, {
cwd: targetFilePath,
cwd: targetFolderPath,
});
return {
plugin: {
Expand Down
2 changes: 1 addition & 1 deletion lib/plugin-search.ts
Expand Up @@ -17,7 +17,7 @@ export async function isPluginInstalled(
function searchProjectFiles(root: string, targetFile: string, plugin: string): boolean {
const basePath = path.dirname(path.resolve(root, targetFile));
const sbtFileList = sbtFiles(path.join(basePath, 'project'))
.concat(sbtFiles(path.join(basePath, 'project', 'project')));
.concat(sbtFiles(path.join(basePath, 'project', 'project')));
const searchResults = sbtFileList.map ((file) => {
return searchWithFs(file, plugin);
});
Expand Down
28 changes: 20 additions & 8 deletions lib/version.ts
Expand Up @@ -12,22 +12,34 @@ export async function getSbtVersion(root: string, targetFile: string): Promise<s
path.dirname(targetFile),
'project/build.properties',
);
debug(`getSbtVersion: buildPropsPath=${buildPropsPath}`);
if (!fs.existsSync(buildPropsPath)) {
// NOTE(alexmu): We've seen this fail with the wrong path.
// If the path we derived above doesn't exist, we try to build a more sensible one.
// targetFile could be a path, so we need to call resolve()
const resolvedPath = path.resolve(root, targetFile);
const targetFilePath = path.dirname(resolvedPath);
buildPropsPath = path.resolve(targetFilePath, 'project/build.properties');
}
// NOTE(alexmu): We've seen this fail with the wrong path.
// If the path we derived above doesn't exist, we try to build a more sensible one.
// targetFile could be a path, so we need to call resolve()
debug(`getSbtVersion: "${buildPropsPath}" doesn't exist`);
const resolvedPath = path.resolve(root, targetFile);
const targetFilePath = path.dirname(resolvedPath);
buildPropsPath = path.resolve(targetFilePath, 'project/build.properties');
}
if (!fs.existsSync(buildPropsPath)) {
// NOTE(alexmu): Some projects don't have proper subproject structures,
// e.g. don't have a project/ subfolder. This breaks snyk's assumptions
// so we try to work around it here.
debug(`getSbtVersion: "${buildPropsPath}" does not exist`);
const resolvedPath = path.resolve(root, '..', targetFile);
const targetFilePath = path.dirname(resolvedPath);
buildPropsPath = path.resolve(targetFilePath, 'project/build.properties');
debug(`getSbtVersion: will try "${buildPropsPath}"`);
}
return fs
.readFileSync(buildPropsPath, 'utf-8')
.split('\n') // split into lines
.find((line) => !!line.match(/sbt\.version\s*=/))! // locate version line
.split(/=\s*/)[1]
.trim(); // return only the version
} catch (err) {
debug('Failed to get sbt version from project/build.properties' + err.message);
debug('Failed to get sbt version from project/build.properties: ' + err.message);
}

try {
Expand Down
2 changes: 1 addition & 1 deletion scala/SnykSbtPlugin-0.1x.scala
Expand Up @@ -10,7 +10,7 @@ import org.json4s._

object SnykSbtPlugin extends AutoPlugin {
val ConfigBlacklist: Set[String] =
Set("windows", "universal", "universal-docs", "debian", "rpm", "universal-src", "docker", "linux", "web-assets", "web-plugin", "web-assets-test")
Set("windows", "universal", "universal-docs", "debian", "rpm", "universal-src", "docker", "linux", "web-assets", "web-plugin", "web-assets-test", "scalafix")

case class SnykModuleInfo(version: String, configurations: Set[String])

Expand Down
2 changes: 1 addition & 1 deletion scala/SnykSbtPlugin-1.2x.scala
Expand Up @@ -8,7 +8,7 @@ import sjsonnew.support.scalajson.unsafe.PrettyPrinter

object SnykSbtPlugin extends AutoPlugin {
val ConfigBlacklist: Set[String] =
Set("windows", "universal", "universal-docs", "debian", "rpm", "universal-src", "docker", "linux", "web-assets", "web-plugin", "web-assets-test")
Set("windows", "universal", "universal-docs", "debian", "rpm", "universal-src", "docker", "linux", "web-assets", "web-plugin", "web-assets-test", "scalafix")

case class SnykModuleInfo(version: String, configurations: Set[String])
case class SnykProjectData(
Expand Down

0 comments on commit ebf261f

Please sign in to comment.