@rindrics/initrepo 0.3.0 → 0.3.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.3.1](https://github.com/Rindrics/initrepo/compare/v0.3.0...v0.3.1) - 2026-01-19
4
+ - feat: add renovate command by @Rindrics in https://github.com/Rindrics/initrepo/pull/38
5
+
3
6
  ## [v0.3.0](https://github.com/Rindrics/initrepo/compare/v0.2.1...v0.3.0) - 2026-01-19
4
7
  - ci: use renovate to use bun by @Rindrics in https://github.com/Rindrics/initrepo/pull/35
5
8
  - feat: generate tagpr config by @Rindrics in https://github.com/Rindrics/initrepo/pull/37
package/dist/cli.js CHANGED
@@ -4207,7 +4207,7 @@ var {
4207
4207
  // package.json
4208
4208
  var package_default = {
4209
4209
  name: "@rindrics/initrepo",
4210
- version: "0.3.0",
4210
+ version: "0.3.1",
4211
4211
  description: "setup GitHub repo with dev tools",
4212
4212
  type: "module",
4213
4213
  bin: {
@@ -4363,6 +4363,21 @@ bun run build
4363
4363
  exclude:
4364
4364
  labels:
4365
4365
  - tagpr
4366
+ `,
4367
+ "common/renovate.json5.ejs": `{
4368
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
4369
+ "extends": ["config:recommended"],
4370
+ "packageRules": [
4371
+ {
4372
+ "matchUpdateTypes": ["major", "minor", "patch"],
4373
+ "automerge": true
4374
+ }
4375
+ ],
4376
+ "lockFileMaintenance": {
4377
+ "enabled": true,
4378
+ "schedule": ["before 5am on monday"]
4379
+ }
4380
+ }
4366
4381
  `,
4367
4382
  "common/workflows/publish.yml.ejs": `name: Publish to npm
4368
4383
 
@@ -11641,7 +11656,7 @@ function registerSetupHuskyCommand(program2) {
11641
11656
  });
11642
11657
  }
11643
11658
 
11644
- // src/commands/setup-tagpr.ts
11659
+ // src/commands/setup-renovate.ts
11645
11660
  import * as fs4 from "node:fs/promises";
11646
11661
  import * as path4 from "node:path";
11647
11662
  async function fileExists2(filePath) {
@@ -11652,6 +11667,86 @@ async function fileExists2(filePath) {
11652
11667
  return false;
11653
11668
  }
11654
11669
  }
11670
+ function generateRenovateSetup() {
11671
+ return [
11672
+ {
11673
+ path: "renovate.json5",
11674
+ content: loadTemplate("common/renovate.json5.ejs", {})
11675
+ }
11676
+ ];
11677
+ }
11678
+ async function writeFiles2(targetDir, files, force) {
11679
+ const written = [];
11680
+ const skipped = [];
11681
+ for (const file of files) {
11682
+ const filePath = path4.join(targetDir, file.path);
11683
+ const fileDir = path4.dirname(filePath);
11684
+ if (!force && await fileExists2(filePath)) {
11685
+ skipped.push(file.path);
11686
+ continue;
11687
+ }
11688
+ await fs4.mkdir(fileDir, { recursive: true });
11689
+ await fs4.writeFile(filePath, file.content, "utf-8");
11690
+ written.push(file.path);
11691
+ }
11692
+ return { written, skipped };
11693
+ }
11694
+ async function setupRenovate(options) {
11695
+ const targetDir = options.targetDir ?? process.cwd();
11696
+ const force = options.force ?? false;
11697
+ const packageJsonPath = path4.join(targetDir, "package.json");
11698
+ if (!await fileExists2(packageJsonPath)) {
11699
+ throw new Error("package.json not found. Are you in a project directory?");
11700
+ }
11701
+ console.log(`\uD83D\uDD27 Setting up Renovate configuration...
11702
+ `);
11703
+ const files = generateRenovateSetup();
11704
+ const { written, skipped } = await writeFiles2(targetDir, files, force);
11705
+ if (written.length > 0) {
11706
+ console.log("✅ Created files:");
11707
+ for (const file of written) {
11708
+ console.log(` ${file}`);
11709
+ }
11710
+ }
11711
+ if (skipped.length > 0) {
11712
+ console.log(`
11713
+ ⏭️ Skipped (already exist, use --force to overwrite):`);
11714
+ for (const file of skipped) {
11715
+ console.log(` ${file}`);
11716
+ }
11717
+ }
11718
+ console.log(`
11719
+ \uD83C\uDF89 Renovate setup complete!`);
11720
+ console.log(`
11721
+ \uD83D\uDCCB Next steps:`);
11722
+ console.log(" 1. Install Renovate GitHub App: https://github.com/apps/renovate");
11723
+ console.log(" 2. Grant access to this repository");
11724
+ }
11725
+ function registerSetupRenovateCommand(program2) {
11726
+ program2.command("setup-renovate").description("Set up Renovate configuration in an existing project").option("-t, --target-dir <path>", "Target directory (defaults to current directory)").option("-f, --force", "Overwrite existing files").action(async (opts) => {
11727
+ try {
11728
+ await setupRenovate({
11729
+ targetDir: opts.targetDir,
11730
+ force: opts.force
11731
+ });
11732
+ } catch (error) {
11733
+ console.error(`❌ Failed to setup Renovate: ${error instanceof Error ? error.message : String(error)}`);
11734
+ process.exit(1);
11735
+ }
11736
+ });
11737
+ }
11738
+
11739
+ // src/commands/setup-tagpr.ts
11740
+ import * as fs5 from "node:fs/promises";
11741
+ import * as path5 from "node:path";
11742
+ async function fileExists3(filePath) {
11743
+ try {
11744
+ await fs5.access(filePath);
11745
+ return true;
11746
+ } catch {
11747
+ return false;
11748
+ }
11749
+ }
11655
11750
  async function generateTagprSetup() {
11656
11751
  const actionVersions = await getLatestActionVersions();
11657
11752
  return [
@@ -11668,18 +11763,18 @@ async function generateTagprSetup() {
11668
11763
  }
11669
11764
  ];
11670
11765
  }
11671
- async function writeFiles2(targetDir, files, force) {
11766
+ async function writeFiles3(targetDir, files, force) {
11672
11767
  const written = [];
11673
11768
  const skipped = [];
11674
11769
  for (const file of files) {
11675
- const filePath = path4.join(targetDir, file.path);
11676
- const fileDir = path4.dirname(filePath);
11677
- if (!force && await fileExists2(filePath)) {
11770
+ const filePath = path5.join(targetDir, file.path);
11771
+ const fileDir = path5.dirname(filePath);
11772
+ if (!force && await fileExists3(filePath)) {
11678
11773
  skipped.push(file.path);
11679
11774
  continue;
11680
11775
  }
11681
- await fs4.mkdir(fileDir, { recursive: true });
11682
- await fs4.writeFile(filePath, file.content, "utf-8");
11776
+ await fs5.mkdir(fileDir, { recursive: true });
11777
+ await fs5.writeFile(filePath, file.content, "utf-8");
11683
11778
  written.push(file.path);
11684
11779
  }
11685
11780
  return { written, skipped };
@@ -11687,14 +11782,14 @@ async function writeFiles2(targetDir, files, force) {
11687
11782
  async function setupTagpr(options) {
11688
11783
  const targetDir = options.targetDir ?? process.cwd();
11689
11784
  const force = options.force ?? false;
11690
- const packageJsonPath = path4.join(targetDir, "package.json");
11691
- if (!await fileExists2(packageJsonPath)) {
11785
+ const packageJsonPath = path5.join(targetDir, "package.json");
11786
+ if (!await fileExists3(packageJsonPath)) {
11692
11787
  throw new Error("package.json not found. Are you in a project directory?");
11693
11788
  }
11694
11789
  console.log(`\uD83D\uDD27 Setting up tagpr configuration...
11695
11790
  `);
11696
11791
  const files = await generateTagprSetup();
11697
- const { written, skipped } = await writeFiles2(targetDir, files, force);
11792
+ const { written, skipped } = await writeFiles3(targetDir, files, force);
11698
11793
  if (written.length > 0) {
11699
11794
  console.log("✅ Created files:");
11700
11795
  for (const file of written) {
@@ -11738,6 +11833,7 @@ function createProgram() {
11738
11833
  registerInitCommand(program2);
11739
11834
  registerPrepareReleaseCommand(program2);
11740
11835
  registerSetupHuskyCommand(program2);
11836
+ registerSetupRenovateCommand(program2);
11741
11837
  registerSetupTagprCommand(program2);
11742
11838
  return program2;
11743
11839
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rindrics/initrepo",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "setup GitHub repo with dev tools",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.ts CHANGED
@@ -4,6 +4,7 @@ import packageJson from '../package.json';
4
4
  import { registerInitCommand } from './commands/init';
5
5
  import { registerPrepareReleaseCommand } from './commands/prepare-release';
6
6
  import { registerSetupHuskyCommand } from './commands/setup-husky';
7
+ import { registerSetupRenovateCommand } from './commands/setup-renovate';
7
8
  import { registerSetupTagprCommand } from './commands/setup-tagpr';
8
9
 
9
10
  const { version: VERSION, name: NAME } = packageJson;
@@ -19,6 +20,7 @@ export function createProgram(): Command {
19
20
  registerInitCommand(program);
20
21
  registerPrepareReleaseCommand(program);
21
22
  registerSetupHuskyCommand(program);
23
+ registerSetupRenovateCommand(program);
22
24
  registerSetupTagprCommand(program);
23
25
 
24
26
  return program;
@@ -0,0 +1,138 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ import type { Command } from 'commander';
4
+ import type { GeneratedFile } from '../generators/project';
5
+ import { loadTemplate } from '../generators/project';
6
+
7
+ export interface SetupRenovateOptions {
8
+ /** Target directory (defaults to current directory) */
9
+ targetDir?: string;
10
+ /** Force overwrite existing files */
11
+ force?: boolean;
12
+ }
13
+
14
+ /**
15
+ * Check if file exists
16
+ */
17
+ async function fileExists(filePath: string): Promise<boolean> {
18
+ try {
19
+ await fs.access(filePath);
20
+ return true;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Generate renovate configuration
28
+ */
29
+ function generateRenovateSetup(): GeneratedFile[] {
30
+ return [
31
+ {
32
+ path: 'renovate.json5',
33
+ content: loadTemplate('common/renovate.json5.ejs', {}),
34
+ },
35
+ ];
36
+ }
37
+
38
+ /**
39
+ * Write generated files to target directory
40
+ */
41
+ async function writeFiles(
42
+ targetDir: string,
43
+ files: GeneratedFile[],
44
+ force: boolean,
45
+ ): Promise<{ written: string[]; skipped: string[] }> {
46
+ const written: string[] = [];
47
+ const skipped: string[] = [];
48
+
49
+ for (const file of files) {
50
+ const filePath = path.join(targetDir, file.path);
51
+ const fileDir = path.dirname(filePath);
52
+
53
+ // Check if file exists
54
+ if (!force && (await fileExists(filePath))) {
55
+ skipped.push(file.path);
56
+ continue;
57
+ }
58
+
59
+ // Create directory if needed
60
+ await fs.mkdir(fileDir, { recursive: true });
61
+
62
+ // Write file
63
+ await fs.writeFile(filePath, file.content, 'utf-8');
64
+ written.push(file.path);
65
+ }
66
+
67
+ return { written, skipped };
68
+ }
69
+
70
+ /**
71
+ * Main setup-renovate logic
72
+ */
73
+ export async function setupRenovate(
74
+ options: SetupRenovateOptions,
75
+ ): Promise<void> {
76
+ const targetDir = options.targetDir ?? process.cwd();
77
+ const force = options.force ?? false;
78
+
79
+ // Check if package.json exists
80
+ const packageJsonPath = path.join(targetDir, 'package.json');
81
+ if (!(await fileExists(packageJsonPath))) {
82
+ throw new Error('package.json not found. Are you in a project directory?');
83
+ }
84
+
85
+ console.log('🔧 Setting up Renovate configuration...\n');
86
+
87
+ // Generate renovate files
88
+ const files = generateRenovateSetup();
89
+
90
+ // Write files
91
+ const { written, skipped } = await writeFiles(targetDir, files, force);
92
+
93
+ // Report results
94
+ if (written.length > 0) {
95
+ console.log('✅ Created files:');
96
+ for (const file of written) {
97
+ console.log(` ${file}`);
98
+ }
99
+ }
100
+
101
+ if (skipped.length > 0) {
102
+ console.log('\n⏭️ Skipped (already exist, use --force to overwrite):');
103
+ for (const file of skipped) {
104
+ console.log(` ${file}`);
105
+ }
106
+ }
107
+
108
+ console.log('\n🎉 Renovate setup complete!');
109
+ console.log('\n📋 Next steps:');
110
+ console.log(
111
+ ' 1. Install Renovate GitHub App: https://github.com/apps/renovate',
112
+ );
113
+ console.log(' 2. Grant access to this repository');
114
+ }
115
+
116
+ export function registerSetupRenovateCommand(program: Command): void {
117
+ program
118
+ .command('setup-renovate')
119
+ .description('Set up Renovate configuration in an existing project')
120
+ .option(
121
+ '-t, --target-dir <path>',
122
+ 'Target directory (defaults to current directory)',
123
+ )
124
+ .option('-f, --force', 'Overwrite existing files')
125
+ .action(async (opts: { targetDir?: string; force?: boolean }) => {
126
+ try {
127
+ await setupRenovate({
128
+ targetDir: opts.targetDir,
129
+ force: opts.force,
130
+ });
131
+ } catch (error) {
132
+ console.error(
133
+ `❌ Failed to setup Renovate: ${error instanceof Error ? error.message : String(error)}`,
134
+ );
135
+ process.exit(1);
136
+ }
137
+ });
138
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": ["config:recommended"],
4
+ "packageRules": [
5
+ {
6
+ "matchUpdateTypes": ["major", "minor", "patch"],
7
+ "automerge": true
8
+ }
9
+ ],
10
+ "lockFileMaintenance": {
11
+ "enabled": true,
12
+ "schedule": ["before 5am on monday"]
13
+ }
14
+ }
File without changes