@digigov/cli-lab 1.0.1 → 1.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digigov/cli-lab",
3
- "version": "1.0.1",
3
+ "version": "1.2.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -15,6 +15,7 @@
15
15
  "zx": "~1.15.2",
16
16
  "zx-extra": "~0.0.4",
17
17
  "inquirer": "~8.1.2",
18
- "glob": "7.1.6"
18
+ "glob": "7.1.6",
19
+ "fs-extra": "~10.0.0"
19
20
  }
20
21
  }
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env zx
2
+ import "zx-extra";
3
+ import "../lib/extra/index.mjs";
4
+
5
+ const dryRun = argv['dry']
6
+ console.log(argv)
7
+ const CI = process.env['CI']
8
+ console.log('CI', CI)
9
+ const configName = 'subtree.config.json'
10
+ const subtreeConfigFileExists = await find(configName)
11
+ console.log(subtreeConfigFileExists)
12
+
13
+ if (!subtreeConfigFileExists.length) {
14
+ console.log('Creating subtree.config file')
15
+ await writeJSON(configName, {})
16
+ }
17
+ const subtreeConfigFile = process.cwd() + '/' + configName
18
+ const subtreeConfig = await readJSON(subtreeConfigFile) || {}
19
+ const tempFolder = 'common/temp/repo'
20
+ await rm(tempFolder)
21
+ await mkdir(tempFolder)
22
+ cd(tempFolder)
23
+ await cli.git.clone('../../.. .')
24
+ await cli.git.checkout(`main`)
25
+ const rushLib = require('@microsoft/rush-lib');
26
+ const rushConfiguration = rushLib.RushConfiguration.loadFromDefaultLocation({
27
+ startingFolder: process.cwd()
28
+ });
29
+ const answers = subtreeConfig
30
+ const cwd = process.cwd()
31
+ const allPackages = rushConfiguration.projects.map(p => p.packageName)
32
+ if (!CI) {
33
+ answers.remote = await question(`Enter the repository url you want to push`,
34
+ subtreeConfig.remote)
35
+ answers.packages = await checkbox(
36
+ `Select package to be published to Github`,
37
+ allPackages, subtreeConfig.packages)
38
+ }
39
+ const branchName = answers.remote.replace('https://', '')
40
+
41
+ const notPublishedPackages = allPackages.filter((p) => !answers.packages.includes(p))
42
+ answers.lastCommitID = await cli.git.log(`-1 --pretty=format:"%h"`, {stdout: true})
43
+ await writeJSON(subtreeConfigFile, answers)
44
+ // delete old git history before X months, based on Date
45
+
46
+ const oneMonthSeconds = 1000 * 60 * 60 * 24 * 30;
47
+ const d = Date.now();
48
+ const beforeDateDate = new Date(d - oneMonthSeconds * 3);
49
+ const afterDateDate = new Date(d - oneMonthSeconds * 4);
50
+ const beforeDate = `${beforeDateDate.getFullYear()}-${beforeDateDate.getMonth()}-${beforeDateDate.getDay()}`;
51
+ const afterDate = `${afterDateDate.getFullYear()}-${afterDateDate.getMonth()}-${afterDateDate.getDay()}`;
52
+ const commitId = await cli.git.log(`-1 --before={${beforeDate}} --after={${afterDate}} --pretty=format:"%h"`, { stdout: true })
53
+ await cli.git.checkout(`--orphan ${branchName} ${commitId}`)
54
+ await cli.git.commit(`-m "chore: remove old commits from git history before ${afterDate}"`)
55
+ await cli.git.rebase(`--onto ${branchName} ${commitId} main`)
56
+ await cli.git.branch(`-D ${branchName}`)
57
+ await cli.git.checkout(`-b ${branchName}`)
58
+ const notPublishedProjects = notPublishedPackages.map(packageName =>
59
+ rushConfiguration
60
+ .findProjectByShorthandName(packageName)
61
+ .projectFolder
62
+ .replace(`${cwd}/`, '')
63
+ ).join(' ')
64
+ process.env['FILTER_BRANCH_SQUELCH_WARNING'] = 1
65
+ await cli.git['filter-branch'](`--force --index-filter \
66
+ "git rm -r --cached --ignore-unmatch ${notPublishedProjects}" \
67
+ --prune-empty --tag-name-filter cat -- --all`)
68
+ const rushJSON = await readJSON(rushConfiguration.rushJsonFile)
69
+ rushJSON.projects = rushJSON.projects.filter(project => !notPublishedPackages.includes(project.packageName))
70
+ await writeJSON('rush.json', rushJSON)
71
+ await cli.rush.update('--full --purge')
72
+ await cli.git.commit('-am "chore: remove unpublished projects from rush json"')
73
+ await cli.git.branch('-M main')
74
+ await cli.git.remote('add partial ' + answers.remote)
75
+ await cli.git.push('-f -u partial main')
76
+
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env zx
2
+
3
+ import '../lib/extra/index.mjs';
4
+
5
+ const components = require('../misc/react-core-components')
6
+ const htmlTypes = require('../misc/html-types')
7
+ // uppercase the first letter of a word
8
+ const ucFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);
9
+ function findRefInChildren(children){
10
+ for(const child of children){
11
+ if(child.props && child.props.ref){
12
+ return child.element
13
+ }
14
+ }
15
+ }
16
+ for(const componentName in components){
17
+ const component = components[componentName]
18
+ if(component.element){
19
+ let mainElement = component.element
20
+ if(component.children){
21
+ mainElement = findRefInChildren(component.children) || mainElement
22
+ }
23
+ const componentPath = `libs-ui/react-core/src/${componentName}/index.tsx`
24
+ const componentTestPath = `libs-ui/react-core/src/${componentName}/index.test.tsx`
25
+ const componentCode = `
26
+ import React from 'react';
27
+ import clsx from 'clsx';
28
+
29
+ type ${ucFirst(mainElement)}ElementAttributes = JSX.IntrinsicElements['${mainElement}']
30
+ export interface ${componentName}Props extends ${ucFirst(mainElement)}ElementAttributes {
31
+ ${
32
+ component.props && Object.keys(component.props).map(propName => {
33
+ const prop = component.props[propName]
34
+ return `
35
+ /**
36
+ * ${propName} is optional.
37
+ */
38
+ ${propName}?: ${prop.type ? prop.type:
39
+ prop.values? Object.keys(prop.values).map(value=>`'${value}'`).join('|'): 'string'}`
40
+ }).join(';\n')
41
+ }
42
+ }
43
+ /**
44
+ * Details for the ${componentName}.
45
+ */
46
+ export const ${componentName} = React.forwardRef<${htmlTypes[mainElement]}, ${componentName}Props>(
47
+ function ${componentName}({
48
+ ${
49
+ component.props && Object.keys(component.props).map(propName => {
50
+ const prop = component.props[propName]
51
+ return `${propName}${prop.default && (prop.type === 'boolean' || prop.type === 'number')? `=${prop.default},`:
52
+ prop.default? `='${prop.default}',`: ','}`
53
+ }).join('\n')
54
+ }
55
+ className,
56
+ children,
57
+ ...props
58
+ }, ref) {
59
+ return (
60
+ ${renderJsonToJsx(component, mainElement)}
61
+ );
62
+ });
63
+
64
+ export default ${componentName};
65
+ `
66
+ const componentTestCode = `
67
+ import React from 'react';
68
+ import { mount } from 'enzyme';
69
+
70
+ import ${componentName} from '@digigov/react-core/${componentName}';
71
+
72
+ it('renders the ${componentName} with no props', () => {
73
+ expect(mount(<${componentName}${component.nochildren?`/>`:`>hello</${componentName}>`})).toMatchSnapshot();
74
+ });
75
+ ${component.props && Object.keys(component.props).map(propName => {
76
+ const prop = component.props[propName]
77
+ if(prop.values && prop.type !== 'boolean'){
78
+ return Object.keys(prop.values).map(value=>{
79
+ return `
80
+ it('renders the ${componentName} with ${propName}=${value}', () => {
81
+ expect(mount(<${componentName} ${propName}={${prop.type === 'number'? value: `'${value}'`}}${component.nochildren?`/>`:`>hello</${componentName}>`})).toMatchSnapshot();
82
+ })`
83
+ }).join('\n')
84
+ }
85
+ if(prop.type === 'boolean'){
86
+ return `
87
+ it('renders the ${componentName} with ${propName}=true', () => {
88
+ expect(mount(<${componentName} ${propName}={true}${component.nochildren?`/>`:`>hello</${componentName}>`})).toMatchSnapshot();
89
+ })
90
+
91
+ it('renders the ${componentName} with ${propName}=false', () => {
92
+ expect(mount(<${componentName} ${propName}={false}${component.nochildren?`/>`:`>hello</${componentName}>`})).toMatchSnapshot();
93
+ })
94
+
95
+ `
96
+ }
97
+ return ''
98
+ }).join('\n')}
99
+
100
+ `
101
+ writeFile(componentPath, componentCode)
102
+ writeFile(componentTestPath, componentTestCode)
103
+ console.log(componentCode)
104
+ }
105
+ }
106
+
107
+
108
+
109
+ // render json to jsx
110
+ function renderJsonToJsx (json, mainElement) {
111
+ let topLevel = false
112
+ if(!Array.isArray(json)){
113
+ if(!json.children){
114
+ json.children = [{element: 'children'}]
115
+ }
116
+ json = [json]
117
+ topLevel = true
118
+
119
+ }
120
+ return json.map(component => {
121
+ if(mainElement === component.element){
122
+ component.props.ref = {
123
+ pass: true
124
+ }
125
+ }
126
+ if(component.element && component.element !== 'children'){
127
+ const elementCode = `<${component.element}
128
+ ${component.props ? Object.keys(component.props).map(propName => {
129
+ const prop = component.props[propName]
130
+ if(prop.pass){
131
+ return `${propName}={${propName}}`
132
+ }
133
+ return ''
134
+ }).filter(p=>p).join('\n'): ''}
135
+ className={clsx(${topLevel?'className,':''} {
136
+ ${component.classes ? component.classes.map(cl=>`'${cl}': true,`).filter(cl=>cl).join('\n'):''}
137
+ ${component.props ? Object.keys(component.props).map(propName => {
138
+ const prop = component.props[propName]
139
+ let classes = ''
140
+ if(prop.values && prop.type !== 'boolean' && prop.type!=='number'){
141
+ return Object.keys(prop.values).map(value=>{
142
+ const className = prop.values[value]
143
+ return `'${className}': ${propName} === '${value}',`
144
+ }).filter(t=>t).join('\n')
145
+ }
146
+ if(prop.values && prop.type === 'boolean'){
147
+ return Object.keys(prop.values).map(value=>{
148
+ const className = prop.values[value]
149
+ return `'${className}': ${propName} === ${value},`
150
+ }).filter(t=>t).join('\n')
151
+ }
152
+ if(prop.values && prop.type === 'number'){
153
+ return Object.keys(prop.values).map(value=>{
154
+ const className = prop.values[value]
155
+ return `'${className}': ${propName} === ${value},`
156
+ }).filter(t=>t).join('\n')
157
+ }
158
+ return ''
159
+ }).filter(t=>t).join(''): ''}
160
+ })}
161
+ ${mainElement === component.element? `{...props}`: ''}
162
+ >${
163
+ component.children? renderJsonToJsx(component.children, mainElement): ''
164
+ }</${component.element}>`
165
+ return elementCode
166
+ }else if(component.element === 'children'){
167
+ return `{children}`
168
+ }else if(component.text){
169
+ return `${component.text}`
170
+ }
171
+
172
+ }).join('').replace(
173
+ /className=\{clsx\( \{\s*\}\)\}/g,'')
174
+ }
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env zx
2
+ import "zx-extra";
3
+ import "../lib/extra/index.mjs";
4
+
5
+ // await cd('./common/temp/repo')
6
+ const subtree = await readJSON('./subtree.config.json');
7
+ const branchName = await question('Enter branch name: ')
8
+ await cli.git.remote(`rm partial`)
9
+ await cli.git.remote(`add partial ${subtree.remote}`)
10
+ await cli.git.pull('partial')
11
+ const commitIDs = (
12
+ await cli.git.log(
13
+ ` partial/main..partial/${branchName} --pretty=format:"%h"`,
14
+ {stdout: true})
15
+ )
16
+ .split('\n')
17
+ await cli.git.branch(`-D github/${branchName}`)
18
+ await cli.git.checkout(`-b github/${branchName} ${subtree.lastCommitID}`)
19
+ commitIDs.reverse()
20
+ for(const commitID of commitIDs) {
21
+ await cli.git['cherry-pick'](`${commitID}`)
22
+ }
@@ -2,18 +2,33 @@
2
2
  import "zx-extra";
3
3
  import "../lib/extra/index.mjs";
4
4
 
5
+ const rushJSON = await readJSON(await findUp('rush.json'));
6
+ const defaultBranch = rushJSON.repository.defaultBranch;
7
+ const currentBranch = await cli.git.branch('--show-current', { stdout: true });
8
+
5
9
  const shouldPublishAll = await confirm('Do you want to publish all packages?');
6
10
 
7
11
  const featureVersion = await confirm('Is it a feature version?');
8
12
  const featureVersionName = featureVersion && await question('What is the feature name? ');
13
+ let targetBranch = await select('Which target branch do you want to use?', [
14
+ defaultBranch,
15
+ currentBranch.trim(),
16
+ 'other (specify)'
17
+ ]);
18
+
19
+ if(targetBranch.indexOf('other (specify)') > -1) {
20
+ let branches = await cli.git.branch(`--format='%(refname:short)'`, {stdout: true});
21
+ branches = branches.split('\n').filter(i => i);
22
+ targetBranch = await select("Select the target branch where the changelogs will be commited", branches);
23
+ }
9
24
 
10
25
  await requireEnv('NPM_AUTH_TOKEN', true);
11
26
 
12
27
  if(shouldPublishAll && !featureVersion) {
13
28
  await cli.rush.change();
14
- await cli.rush.version('--bump');
29
+ await cli.rush.publish('-a');
15
30
  await cli.rush.build();
16
- await cli.rush.publish('-p --include-all --set-access-level public');
31
+ await cli.rush.publish(`-p --include-all --target-branch ${targetBranch} --set-access-level public`);
17
32
  } else if(shouldPublishAll && featureVersion) {
18
33
  await cli.rush.publish(`--prerelease-name ${featureVersionName} -a`);
19
34
  await cli.rush.build();
@@ -21,7 +36,7 @@ if(shouldPublishAll && !featureVersion) {
21
36
  } else if(!shouldPublishAll && !featureVersion) {
22
37
  console.log('Not supported')
23
38
  process.exit()
24
- const {projects} = await readJSON(await findUp('rush.json'));
39
+ const {projects} = rushJSON;
25
40
  const publishablePackages = projects.filter(project => project.shouldPublish);
26
41
  const publishPackages = await checkbox(
27
42
  'Select packages',
@@ -29,7 +44,6 @@ if(shouldPublishAll && !featureVersion) {
29
44
  );
30
45
  for(const packageName of publishPackages) {
31
46
  // cd(projects.find(({packageName}) => packageName===packageName).projectFolder))
32
-
33
47
  }
34
48
  console.log(publishPackages)
35
49
  }
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env zx
2
+ import "zx-extra";
3
+ import "../lib/extra/index.mjs";
4
+
5
+ const rushLib = require('@microsoft/rush-lib');
6
+ const rushConfiguration = rushLib.RushConfiguration.loadFromDefaultLocation({
7
+ startingFolder: process.cwd()
8
+ });
9
+
10
+ const localPackageVersions = rushConfiguration.projects.reduce((versions, project) => {
11
+ return { ...versions, [project.packageJson.name]: project.packageJson.version };
12
+ }, {});
13
+
14
+ console.log(localPackageVersions);
15
+ rushConfiguration.projects.forEach(project => {
16
+ for (const dependencyType of ['dependencies', 'devDependencies', 'peerDependencies']) {
17
+ const dependencies = project.packageJson[dependencyType];
18
+ if (dependencies) {
19
+ for (const dependencyName in dependencies) {
20
+ const dependencyVersion = dependencies[dependencyName];
21
+ if (localPackageVersions[dependencyName] && localPackageVersions[dependencyName] !== dependencyVersion) {
22
+ console.log(`${project.packageJson.name} ${dependencyType} ${dependencyName} ${dependencyVersion}`);
23
+ project.packageJsonEditor.addOrUpdateDependency(dependencyName, localPackageVersions[dependencyName], dependencyType);
24
+ }
25
+ }
26
+ }
27
+ }
28
+ project.packageJsonEditor.saveIfModified();
29
+ });