@fatsolutions/ganchos 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,22 @@
1
+ import { existsSync } from 'fs';
2
+ import { join } from 'path';
1
3
  export const dependencies = {
2
4
  "eslint": "9.39.2",
3
5
  "@eslint/js": "9.39.2",
4
- "eslint-config-prettier": "10.1.8", // includes prettier
6
+ // includes prettier
7
+ "eslint-config-prettier": "10.1.8",
5
8
  "typescript-eslint": "8.51.0",
6
9
  };
7
10
  export const configFiles = [
8
11
  "eslint.config.js",
9
12
  ".prettierrc"
10
13
  ];
11
- export function getInstallCommand(deps) {
14
+ export function getInstallCommand(deps, projectRoot) {
12
15
  const packages = Object.entries(deps)
13
16
  .map(([name, version]) => `${name}@${version}`)
14
17
  .join(' ');
15
- return `pnpm add -D -w --ignore-scripts ${packages}`;
18
+ // Check if in a pnpm workspace
19
+ const isWorkspace = existsSync(join(projectRoot, 'pnpm-workspace.yaml'));
20
+ const workspaceFlag = isWorkspace ? '-w ' : '';
21
+ return `pnpm add -D ${workspaceFlag}--ignore-scripts ${packages}`;
16
22
  }
@@ -1,7 +1,11 @@
1
+ import { existsSync } from 'fs';
2
+ import { join } from 'path';
3
+
1
4
  export const dependencies: Record<string, string> = {
2
5
  "eslint": "9.39.2",
3
6
  "@eslint/js": "9.39.2",
4
- "eslint-config-prettier": "10.1.8", // includes prettier
7
+ // includes prettier
8
+ "eslint-config-prettier": "10.1.8",
5
9
  "typescript-eslint": "8.51.0",
6
10
  };
7
11
 
@@ -10,9 +14,14 @@ export const configFiles: string[] = [
10
14
  ".prettierrc"
11
15
  ];
12
16
 
13
- export function getInstallCommand(deps: Record<string, string>): string {
17
+ export function getInstallCommand(deps: Record<string, string>, projectRoot: string): string {
14
18
  const packages = Object.entries(deps)
15
19
  .map(([name, version]) => `${name}@${version}`)
16
20
  .join(' ');
17
- return `pnpm add -D -w --ignore-scripts ${packages}`;
21
+
22
+ // Check if in a pnpm workspace
23
+ const isWorkspace = existsSync(join(projectRoot, 'pnpm-workspace.yaml'));
24
+ const workspaceFlag = isWorkspace ? '-w ' : '';
25
+
26
+ return `pnpm add -D ${workspaceFlag}--ignore-scripts ${packages}`;
18
27
  }
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs/promises";
3
+ import path from "path";
4
+ import { enableLanguages } from "./lib/config.js";
5
+ import { installHook, installHookTools } from "./lib/hooks.js";
6
+ import { getConfigPath } from "./lib/paths.js";
7
+ async function appendToExclude(projectRoot, entries) {
8
+ const excludePath = path.join(projectRoot, ".git", "info", "exclude");
9
+ try {
10
+ const existing = await fs.readFile(excludePath, "utf-8");
11
+ const linesToAdd = entries.filter((entry) => !existing.includes(entry));
12
+ if (linesToAdd.length > 0) {
13
+ await fs.appendFile(excludePath, "\n" + linesToAdd.join("\n") + "\n");
14
+ }
15
+ } catch {
16
+ }
17
+ }
18
+ async function bootstrap() {
19
+ const projectRoot = process.env.INIT_CWD || process.cwd();
20
+ const selfPkgPath = path.join(projectRoot, "package.json");
21
+ try {
22
+ const selfPkg = JSON.parse(await fs.readFile(selfPkgPath, "utf-8"));
23
+ if (selfPkg.name === "@fatsolutions/ganchos") {
24
+ return;
25
+ }
26
+ } catch {
27
+ return;
28
+ }
29
+ const configPath = getConfigPath(projectRoot);
30
+ try {
31
+ await fs.access(configPath);
32
+ console.log("Ganchos: Already configured, skipping bootstrap.");
33
+ return;
34
+ } catch {
35
+ }
36
+ try {
37
+ await fs.access(path.join(projectRoot, ".git"));
38
+ } catch {
39
+ console.log("Ganchos: Not a git repository, skipping bootstrap.");
40
+ return;
41
+ }
42
+ const pkgPath = path.join(projectRoot, "package.json");
43
+ const pkgContent = await fs.readFile(pkgPath, "utf-8");
44
+ const pkg = JSON.parse(pkgContent);
45
+ const ganchosConfig = pkg.ganchos;
46
+ if (!ganchosConfig?.languages?.length) {
47
+ console.log('Ganchos: No languages configured in package.json "ganchos" field, skipping.');
48
+ console.log('Ganchos: Add { "ganchos": { "languages": ["typescript"] } } to enable.');
49
+ return;
50
+ }
51
+ console.log("Ganchos: Setting up git hooks...");
52
+ await enableLanguages(projectRoot, ganchosConfig.languages);
53
+ console.log(`Ganchos: Enabled languages: ${ganchosConfig.languages.join(", ")}`);
54
+ await installHookTools(projectRoot);
55
+ await installHook(projectRoot);
56
+ await appendToExclude(projectRoot, [".ganchos.json"]);
57
+ console.log("Ganchos: Setup complete!");
58
+ }
59
+ bootstrap().catch((err) => {
60
+ console.error("Ganchos: Bootstrap failed:", err);
61
+ process.exit(1);
62
+ });
@@ -1,7 +1,7 @@
1
1
  import { FatHooksConfig } from '../types/index.js';
2
2
 
3
3
  /**
4
- * Read configuration from "@fatsolutions/ganchos".json, creating default if missing.
4
+ * Read configuration from ".ganchos.json", creating default if missing.
5
5
  */
6
6
  declare function readConfig(projectRoot: string): Promise<FatHooksConfig>;
7
7
  /**
package/dist/lib/hooks.js CHANGED
@@ -61,7 +61,7 @@ async function installHookTools(projectRoot) {
61
61
  }
62
62
  const installModule = await import(installModulePath);
63
63
  if (installModule.dependencies && installModule.getInstallCommand) {
64
- const cmd = installModule.getInstallCommand(installModule.dependencies);
64
+ const cmd = installModule.getInstallCommand(installModule.dependencies, projectRoot);
65
65
  console.log(`Installing ${lang.name} tools: ${cmd}`);
66
66
  execSync(cmd, { cwd: projectRoot, stdio: "inherit" });
67
67
  }
@@ -5,7 +5,7 @@ interface LanguageConfig {
5
5
  interface LanguageInstallModule {
6
6
  dependencies: Record<string, string>;
7
7
  configFiles: string[];
8
- getInstallCommand: (deps: Record<string, string>) => string;
8
+ getInstallCommand: (deps: Record<string, string>, projectRoot: string) => string;
9
9
  }
10
10
  interface FatHooksConfig {
11
11
  version: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fatsolutions/ganchos",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Git Hook Manager for Polyglot Monorepos, developed in house by FatSolutions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,6 +38,7 @@
38
38
  "registry": "https://registry.npmjs.org"
39
39
  },
40
40
  "scripts": {
41
+ "postinstall": "node dist/bootstrap.js",
41
42
  "build": "tsup && tsc -p tsconfig.configs.json",
42
43
  "build:dev": "tsc -p tsconfig.build.json && tsc -p tsconfig.configs.json",
43
44
  "dev": "tsup --watch",