Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: alphabetical rule #221

Merged
merged 11 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"@typescript-eslint/prefer-function-type": "warn",
"@typescript-eslint/prefer-includes": "error",
"@typescript-eslint/prefer-string-starts-ends-with": "error",
"@typescript-eslint/require-array-sort-compare": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/no-explicit-any": "error",
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,7 @@ jobs:
tags
resolutions
keys
alphabetical
dependency-types: |
dependencies
devDependencies
67 changes: 67 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25643,6 +25643,7 @@ const ranges_1 = __nccwpck_require__(6507);
const tags_1 = __nccwpck_require__(130);
const resolutions_1 = __nccwpck_require__(8808);
const keys_1 = __nccwpck_require__(4315);
const alphabetical_1 = __nccwpck_require__(972);
const pathToPackageJson = './package.json';
exports.RULES_MAP = {
ranges: {
Expand All @@ -25659,6 +25660,9 @@ exports.RULES_MAP = {
keys: {
method: keys_1.validateKeys,
extraInput: pathToPackageJson
},
alphabetical: {
method: alphabetical_1.validateAlphabetical
}
};
const run = () => {
Expand All @@ -25678,6 +25682,69 @@ exports.run = run;
(0, exports.run)();


/***/ }),

/***/ 972:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {

"use strict";

/*
Copyright 2021 Expedia, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.validateAlphabetical = void 0;
const core = __importStar(__nccwpck_require__(2186));
const get_dependencies_1 = __nccwpck_require__(4715);
const validateAlphabetical = (packageJson) => {
const dependencyTypes = (0, get_dependencies_1.getDependencyTypes)();
dependencyTypes.forEach(dependencyType => {
const dependencies = packageJson[dependencyType];
if (!dependencies) {
throw new Error(`${dependencyType} specified in dependency-types but missing in package.json`);
}
const sortedDependencies = Object.keys(dependencies).sort();
const isSorted = JSON.stringify(Object.keys(dependencies)) === JSON.stringify(sortedDependencies);
if (!isSorted) {
core.setFailed(`${dependencyType} in package.json are not sorted alphabetically.`);
}
});
};
exports.validateAlphabetical = validateAlphabetical;


/***/ }),

/***/ 4315:
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { validateVersionRanges } from './rules/ranges';
import { validateVersionTags } from './rules/tags';
import { validateResolutions } from './rules/resolutions';
import { validateKeys } from './rules/keys';
import { validateAlphabetical } from './rules/alphabetical';

type GithubError = {
status: number;
Expand Down Expand Up @@ -46,6 +47,9 @@ export const RULES_MAP: {
keys: {
method: validateKeys,
extraInput: pathToPackageJson
},
alphabetical: {
method: validateAlphabetical
}
};

Expand Down
34 changes: 34 additions & 0 deletions src/rules/alphabetical.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright 2021 Expedia, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import * as core from '@actions/core';
import { PackageJson } from 'type-fest';
import { getDependencyTypes } from '../utils/get-dependencies';

export const validateAlphabetical = (packageJson: PackageJson) => {
const dependencyTypes = getDependencyTypes();
dependencyTypes.forEach(dependencyType => {
const dependencies = packageJson[dependencyType];
if (!dependencies) {
throw new Error(
`${dependencyType} specified in dependency-types but missing in package.json`
);
}
const sortedDependencies = Object.keys(dependencies).sort();
const isSorted =
JSON.stringify(Object.keys(dependencies)) === JSON.stringify(sortedDependencies);
if (!isSorted) {
core.setFailed(`${dependencyType} in package.json are not sorted alphabetically.`);
}
});
};
61 changes: 61 additions & 0 deletions test/rules/alphabetical.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {PackageJson} from 'type-fest';
import * as core from '@actions/core';
import { validateAlphabetical } from '../../src/rules/alphabetical';
import { getMultilineInput } from '@actions/core';

jest.mock('@actions/core');

(getMultilineInput as jest.Mock).mockReturnValue(['dependencies', 'devDependencies']);

describe('alphabetical', () => {
it('should fail when dependencies are not in alphabetical order', () => {
const packageJson: PackageJson = {
dependencies: {
'a-package': '1.2.3',
'c-package': '1.2.3',
'b-package': '1.2.3',
},
devDependencies: {
'c-package': '1.2.3',
'd-package': '1.2.3',
'e-package': '1.2.3',
}
};
validateAlphabetical(packageJson);
expect(core.setFailed).toHaveBeenCalled();
});

it('should fail when devDependencies are not in alphabetical order', () => {
const packageJson: PackageJson = {
dependencies: {
'a-package': '1.2.3',
'b-package': '1.2.3',
'c-package': '1.2.3',
},
devDependencies: {
'd-package': '1.2.3',
'c-package': '1.2.3',
'e-package': '1.2.3',
}
};
validateAlphabetical(packageJson);
expect(core.setFailed).toHaveBeenCalled();
});

it('should not fail when dependencies are in alphabetical order', () => {
const packageJson: PackageJson = {
dependencies: {
'a-package': '1.2.3',
'b-package': '1.2.3',
'c-package': '1.2.3',
},
devDependencies: {
'c-package': '1.2.3',
'd-package': '1.2.3',
'e-package': '1.2.3',
}
};
validateAlphabetical(packageJson);
expect(core.setFailed).not.toHaveBeenCalled();
});
});
4 changes: 2 additions & 2 deletions test/rules/resolutions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as core from '@actions/core';
jest.mock('@actions/core');

describe('resolutions', () => {
it('should fail when resolutions are present', function () {
it('should fail when resolutions are present', () => {
const packageJson: PackageJson = {
dependencies: {},
resolutions: {
Expand All @@ -16,7 +16,7 @@ describe('resolutions', () => {
expect(core.setFailed).toHaveBeenCalled();
});

it('should not fail when resolutions are not present', function () {
it('should not fail when resolutions are not present', () => {
const packageJson: PackageJson = {
dependencies: {}
};
Expand Down