/ src / commands / issue.ts
issue.ts
 1  import { Command } from 'commander';
 2  import { get } from '../http.js';
 3  
 4  export function issueCommand(): Command {
 5    const issue = new Command('issue')
 6      .description('Work with AtomGit issues')
 7      .option('-R, --repo <repo>', 'Select repository (OWNER/REPO)')
 8      .addHelpText('after', `
 9  ARGUMENTS
10    An issue can be supplied as argument in any of the following formats:
11    - by number, e.g. "123"
12    - by URL, e.g. "https://atomgit.com/OWNER/REPO/issues/123"
13  
14  EXAMPLES
15    $ atomgit issue list -R owner/repo
16    $ atomgit issue view 123 -R owner/repo
17  
18  LEARN MORE
19    Use \`atomgit issue <subcommand> --help\` for more information about a command.
20  `);
21  
22    issue
23      .command('list')
24      .description('List issues in a repository')
25      .option('-R, --repo <repo>', 'Select repository (OWNER/REPO)')
26      .option('-s, --state <state>', 'Filter by state: open, closed, all', 'open')
27      .option('-L, --limit <number>', 'Maximum number of issues to list', '30')
28      .action(async (options: { repo?: string; state?: string; limit?: string }) => {
29        if (!options.repo) {
30          // eslint-disable-next-line no-console
31          console.error('Repository required. Use -R owner/repo');
32          process.exitCode = 1;
33          return;
34        }
35  
36        try {
37          const params = new URLSearchParams();
38          params.set('state', options.state ?? 'open');
39          params.set('limit', options.limit ?? '30');
40  
41          const issues = await get(`/repos/${options.repo}/issues?${params}`);
42          // eslint-disable-next-line no-console
43          console.log(JSON.stringify(issues, null, 2));
44        } catch (error) {
45          // eslint-disable-next-line no-console
46          console.error('Failed to list issues:', error instanceof Error ? error.message : error);
47          process.exitCode = 1;
48        }
49      });
50  
51    issue
52      .command('view')
53      .description('View issue details')
54      .argument('<number>', 'Issue number')
55      .option('-R, --repo <repo>', 'Select repository (OWNER/REPO)')
56      .action(async (number: string, options: { repo?: string }) => {
57        if (!options.repo) {
58          // eslint-disable-next-line no-console
59          console.error('Repository required. Use -R owner/repo');
60          process.exitCode = 1;
61          return;
62        }
63  
64        try {
65          const issue = await get(`/repos/${options.repo}/issues/${number}`);
66          // eslint-disable-next-line no-console
67          console.log(JSON.stringify(issue, null, 2));
68        } catch (error) {
69          // eslint-disable-next-line no-console
70          console.error('Failed to view issue:', error instanceof Error ? error.message : error);
71          process.exitCode = 1;
72        }
73      });
74  
75    return issue;
76  }