Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…-machine

# Conflicts:
#	package.json
  • Loading branch information
pilotpirxie committed Sep 14, 2023
2 parents 3ae9659 + acd26a7 commit a88c8e9
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 59 deletions.
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,23 @@ Usage: dependency-time-machine [options]
Tool to automatically update dependencies one-by-one in the time order

Options:
-p, --packageFile <file> Path to package.json file (default: "package.json")
-u, --update Update package.json file with new versions
-is, --install-script <command> Install with script (default: "npm install")
-ts, --test-script <command> Test command (default: "npm test")
-i, --install Install with script
-t, --timeline Print timeline
-a, --auto Run in auto mode
-c, --cache Cache resolved dependencies
-cf, --cache-file <file> Cache file (default: "./.dependency-time-machine/cache.json")
-e, --exclude <dependency> Exclude dependency from update, separated by comma
-x, --exclude-file <file> Exclude dependencies from file, one per line (default: "")
-r, --registry-url <url> Registry url (default: "https://registry.npmjs.org")
-pi, --print-info Print info about the packages
-h, --help display help for command
-p, --packageFile <file> Path to package.json file (default: "package.json")
-u, --update Update package.json file with new versions
-is, --install-script <command> Install with script (default: "npm install")
-ts, --test-script <command> Test command (default: "npm test")
-i, --install Install with script
-t, --timeline Print timeline
-a, --auto Run in auto mode
-c, --cache Cache resolved dependencies
-ans, --allow-non-semver Allow non-semver versions (compare with dates then, experimental)
-cf, --cache-file <file> Cache file (default: "./.dependency-time-machine-cache.json")
-e, --exclude <dependency> Exclude dependency from update, separated by comma
-r, --registry-url <url> Registry url (default: "https://registry.npmjs.org")
-x, --exclude-file <file> Exclude dependencies from file, one per line (default: "")
-shmn, --stop-if-higher-major-number Stop if higher major number
-shmnv, --stop-if-higher-minor-number Stop if higher minor or major number
-pi, --print-info Print info about the packages
-h, --help display help for command
```
## License
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/exec/getRemoteDependencies.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe("getRemoteDependencies", () => {
cacheFilePath: "cache.json",
excludedDependencies: [],
registryUrl: "",
allowNonSemver: false,
});

expect(existsSync).toHaveBeenCalledWith("cache.json");
Expand All @@ -42,6 +43,7 @@ describe("getRemoteDependencies", () => {
cacheFilePath: "cache.json",
excludedDependencies: [],
registryUrl: "",
allowNonSemver: false,
});

expect(existsSync).toHaveBeenCalledWith("cache.json");
Expand All @@ -57,6 +59,7 @@ describe("getRemoteDependencies", () => {
cacheFilePath: "cache.json",
excludedDependencies: [],
registryUrl: "",
allowNonSemver: false,
});

expect(dependencies).toBeDefined();
Expand All @@ -73,6 +76,7 @@ describe("getRemoteDependencies", () => {
cacheFilePath: "cache.json",
excludedDependencies: [],
registryUrl: "https://registry.npmjs.org",
allowNonSemver: false,
});

expect(dependencies).toBeDefined();
Expand Down
6 changes: 4 additions & 2 deletions src/exec/getRemoteDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ export async function getRemoteDependencies({
cacheFilePath,
excludedDependencies,
registryUrl,
allowNonSemver,
}: {
localDependencies: LocalDependencies;
cache: boolean;
cacheFilePath: string;
excludedDependencies: string[];
registryUrl: string;
allowNonSemver: boolean;
}): Promise<Dependency[]> {
try {
const cacheExists = fs.existsSync(cacheFilePath);
Expand All @@ -41,8 +43,8 @@ export async function getRemoteDependencies({
remoteDependencies.push(...newDependency);
}

remoteDependencies = remoteDependencies.filter((dependency) =>
isValidVersion(dependency.version),
remoteDependencies = remoteDependencies.filter(
(dependency) => isValidVersion(dependency.version) || allowNonSemver,
);

const sortedRemoteDependencies = remoteDependencies
Expand Down
4 changes: 2 additions & 2 deletions src/exec/printDependenciesInfo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ describe("printDependenciesInfo", () => {
{
name: "react",
version: "17.0.2",
published: new Date("2021-03-18T16:10:00.000Z"),
published: new Date("2021-03-18T16:10:00.000Z").toISOString(),
},
{
name: "react-dom",
version: "17.0.2",
published: new Date("2021-03-18T16:00:00.000Z"),
published: new Date("2021-03-18T16:00:00.000Z").toISOString(),
},
],
});
Expand Down
2 changes: 1 addition & 1 deletion src/exec/updatePackageFile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe("updatePackageFile", () => {
dependencyToUpdate: {
name: "react",
version: "17.0.2",
published: new Date(),
published: new Date().toISOString(),
},
packageFilePath: "/",
});
Expand Down
24 changes: 15 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
#!/usr/bin/env node
import { program } from "commander";
import { run } from "./run";
import {program} from "commander";
import {run} from "./run";

program
.name("dependency-time-machine")
.description(
"Tool to automatically update dependencies one-by-one in the time order"
"Tool to automatically update dependencies one-by-one in the time order",
)
.option(
"-p, --packageFile <file>",
"Path to package.json file",
"package.json"
"package.json",
)
.option("-u, --update", "Update package.json file with new versions")
.option(
"-is, --install-script <command>",
"Install with script",
"npm install"
"npm install",
)
.option("-ts, --test-script <command>", "Test command", "npm test")
.option("-i, --install", "Install with script")
.option("-t, --timeline", "Print timeline")
.option("-a, --auto", "Run in auto mode")
.option("-c, --cache", "Cache resolved dependencies")
.option("-ans, --allow-non-semver", "Allow non-semver versions (compare with dates then, experimental)")
.option(
"-cf, --cache-file <file>",
"Cache file",
"./.dependency-time-machine-cache.json"
"./.dependency-time-machine-cache.json",
)
.option(
"-e, --exclude <dependency>",
"Exclude dependency from update, separated by comma"
"Exclude dependency from update, separated by comma",
)
.option(
"-r, --registry-url <url>",
"Registry url",
"https://registry.npmjs.org"
"https://registry.npmjs.org",
)
.option(
"-x, --exclude-file <file>",
"Exclude dependencies from file, one per line",
""
"",
)
.option("-shmn, --stop-if-higher-major-number", "Stop if higher major number")
.option(
"-shmnv, --stop-if-higher-minor-number",
"Stop if higher minor or major number",
)
.option("-pi, --print-info", "Print info about the packages")
.action(run)
Expand Down
87 changes: 66 additions & 21 deletions src/run.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import path from "path";
import { getExcludedDependencies } from "./exec/getExcludedDependencies";
import { getDependenciesFromPackageJson } from "./exec/getDependenciesFromPackageJson";
import { getRemoteDependencies } from "./exec/getRemoteDependencies";
import { Dependency } from "./types/Dependency";
import { compareVersions } from "./util/semver";
import { close } from "./exec/close";
import { updatePackageFile } from "./exec/updatePackageFile";
import { installDependency } from "./exec/installDependency";
import { runTest } from "./exec/runTest";
import { printDependenciesInfo } from "./exec/printDependenciesInfo";
import {getExcludedDependencies} from "./exec/getExcludedDependencies";
import {getDependenciesFromPackageJson} from "./exec/getDependenciesFromPackageJson";
import {getRemoteDependencies} from "./exec/getRemoteDependencies";
import {Dependency} from "./types/Dependency";
import {
compareDates,
compareVersions,
isHigherMajorVersion,
isHigherMinorVersion,
isValidVersion,
} from "./util/semver";
import {close} from "./exec/close";
import {updatePackageFile} from "./exec/updatePackageFile";
import {installDependency} from "./exec/installDependency";
import {runTest} from "./exec/runTest";
import {printDependenciesInfo} from "./exec/printDependenciesInfo";

export const run = async ({
packageFile,
Expand All @@ -24,6 +30,9 @@ export const run = async ({
timeline,
registryUrl,
printInfo,
allowNonSemver,
stopIfHigherMajorNumber,
stopIfHigherMinorNumber,
}: {
packageFile: string;
installScript: string;
Expand All @@ -38,6 +47,9 @@ export const run = async ({
timeline: boolean | undefined;
registryUrl: string;
printInfo: boolean | undefined;
allowNonSemver: boolean | undefined;
stopIfHigherMajorNumber: boolean | undefined;
stopIfHigherMinorNumber: boolean | undefined;
}) => {
const currentDir = process.cwd();
const packageFilePath = path.join(currentDir, packageFile);
Expand All @@ -56,36 +68,69 @@ export const run = async ({
cacheFilePath: path.join(currentDir, cacheFile),
excludedDependencies,
registryUrl,
allowNonSemver: !!allowNonSemver,
});

let previousDependency: Dependency | null = null;
let dependencyToUpdate = null;
const timelineToPrint: Dependency[] = [];

for (let i = 0; i < sortedRemoteDependencies.length; i++) {
const dependency = sortedRemoteDependencies[i];
if (
compareVersions(
dependency.version,
localDependencies[dependency.name],
) > 0
) {

const dependencyToCompare = sortedRemoteDependencies.find(
(d) => d.name === dependency.name,
);

if (!dependencyToCompare) {
continue;
}

const compareAgainstLocalDependency = !isValidVersion(
dependency.version,
localDependencies[dependency.name],
)
? compareDates(dependency.published, dependencyToCompare.published) > 0
: compareVersions(
dependency.version,
localDependencies[dependency.name],
) > 0;

if (compareAgainstLocalDependency) {
if (dependencyToUpdate === null) {
previousDependency = {
name: dependency.name,
version: localDependencies[dependency.name],
published: new Date(),
published: new Date().toISOString(),
};
dependencyToUpdate = dependency;
timelineToPrint.push(...sortedRemoteDependencies.slice(i));
}

if (dependencyToUpdate.name !== dependency.name) {
const versioningStop =
(stopIfHigherMajorNumber &&
isHigherMajorVersion(
dependency.version,
dependencyToUpdate.version,
)) ||
(stopIfHigherMinorNumber &&
isHigherMinorVersion(
dependency.version,
dependencyToUpdate.version,
));

if (dependencyToUpdate.name !== dependency.name || versioningStop) {
break;
}

if (
compareVersions(dependency.version, dependencyToUpdate.version) > 0
) {
const compareAgainstDependencyToUpdate = !isValidVersion(
dependency.version,
dependencyToUpdate.version,
)
? compareDates(dependency.published, dependencyToUpdate.published) > 0
: compareVersions(dependency.version, dependencyToUpdate.version) > 0;

if (compareAgainstDependencyToUpdate) {
dependencyToUpdate = dependency;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/types/Dependency.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type Dependency = {
name: string;
version: string;
published: Date;
published: string;
};
4 changes: 2 additions & 2 deletions src/util/httpDependencyResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function fetchJson<T>(url: string): Promise<T> {

export default async function httpDependencyResolver(
name: string,
registryUrl: string
registryUrl: string,
): Promise<Dependency[]> {
const url = `${registryUrl}/${name}`;
try {
Expand All @@ -39,7 +39,7 @@ export default async function httpDependencyResolver(
dependencyVersionsWithPublishedDate.push({
name,
version,
published: new Date(published),
published: new Date(published).toISOString(),
});
}

Expand Down
Loading

0 comments on commit a88c8e9

Please sign in to comment.