pomanalyzer 1.0.0
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/.eslintrc.json +21 -0
- package/DOCUMENTATION.md +0 -0
- package/LICENSE +21 -0
- package/PUBLISH.md +28 -0
- package/README.md +152 -0
- package/TEST.md +43 -0
- package/babel.config.js +3 -0
- package/cli.js +56 -0
- package/jest.config.js +17 -0
- package/output/Maven_Dependencies_report.html +84 -0
- package/output/Maven_Dependencies_report.md +24 -0
- package/package.json +47 -0
- package/screenshots/CodeCoverage.png +0 -0
- package/screenshots/ConsoleOutput.png +0 -0
- package/screenshots/HtmlOutput.png +0 -0
- package/screenshots/MarkdownOutput.png +0 -0
- package/src/index.js +50 -0
- package/src/services/dependencyService.js +61 -0
- package/src/services/duplicateChecker.js +17 -0
- package/src/utils/dependencyResolver.js +28 -0
- package/src/utils/fileUtils.js +19 -0
- package/src/utils/outputFormatter.js +14 -0
- package/src/utils/printHTMLTable.js +88 -0
- package/src/utils/printMarkdownTable.js +50 -0
- package/src/utils/xmlParser.js +21 -0
- package/test/Test1.xml +56 -0
- package/test/dependencyResolver.test.js +58 -0
- package/test/dependencyService.test.js +310 -0
- package/test/duplicateChecker.test.js +67 -0
- package/test/fileUtils.test.js +43 -0
- package/test/outputFormatter.test.js +57 -0
- package/test/xmlParser.test.js +71 -0
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"es2021": true,
|
|
5
|
+
"node": true
|
|
6
|
+
},
|
|
7
|
+
"extends": "eslint:recommended",
|
|
8
|
+
"parserOptions": {
|
|
9
|
+
"ecmaVersion": 12,
|
|
10
|
+
"sourceType": "module"
|
|
11
|
+
},
|
|
12
|
+
"rules": {
|
|
13
|
+
"indent": ["error", 2],
|
|
14
|
+
"linebreak-style": ["error", "unix"],
|
|
15
|
+
"quotes": ["error", "single"],
|
|
16
|
+
"semi": ["error", "always"],
|
|
17
|
+
"no-console": "warn",
|
|
18
|
+
"eqeqeq": ["error", "always"],
|
|
19
|
+
"curly": "error"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/DOCUMENTATION.md
ADDED
|
File without changes
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Zack Dawood
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/PUBLISH.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
## Link your package locally for testing:
|
|
3
|
+
|
|
4
|
+
### Test Locally
|
|
5
|
+
`npm link`
|
|
6
|
+
|
|
7
|
+
`npm unlink -g`
|
|
8
|
+
|
|
9
|
+
`npm link pomanalyzer`
|
|
10
|
+
|
|
11
|
+
## Now you can run the script globally using:
|
|
12
|
+
|
|
13
|
+
```pomanalyzer <filePath>```
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Publish the Package
|
|
17
|
+
### Login to npm (if you haven't already):
|
|
18
|
+
`npm login`
|
|
19
|
+
|
|
20
|
+
### Publish the package:
|
|
21
|
+
`npm publish`
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Install the Package Globally
|
|
25
|
+
Once published, you (or anyone) can install the package globally using:
|
|
26
|
+
`npm install -g pomanalyzer`
|
|
27
|
+
|
|
28
|
+
### Check [Documentation](DOCUMENTATION.md) for more details
|
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# pomanalyzer
|
|
2
|
+
|
|
3
|
+
pomanalyzer is a utility to analyze Apache Maven POM XML files offline. It extracts and formats dependency information, detects duplicate dependencies, and generates reports in various formats.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/pomanalyzer)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- Analyze Maven POM XML files to extract dependency information.
|
|
11
|
+
- Detect duplicate dependencies and summarize them.
|
|
12
|
+
- Generate reports in:
|
|
13
|
+
- **HTML** format.
|
|
14
|
+
- **Markdown** format.
|
|
15
|
+
- Customizable output folder for generated reports.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Installation using NPM
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Install globally
|
|
22
|
+
npm install -g pomanalyzer
|
|
23
|
+
|
|
24
|
+
# To uninstall
|
|
25
|
+
npm uninstall -g pomanalyzer
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Installation in local
|
|
29
|
+
|
|
30
|
+
To install `pomanalyzer`, clone the repository and install the dependencies:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git clone https://github.com/zackria/pomanalyzer.git
|
|
34
|
+
cd pomanalyzer
|
|
35
|
+
npm install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
Run the `pomanalyzer` CLI tool with the following commands:
|
|
41
|
+
|
|
42
|
+
### Basic Analysis
|
|
43
|
+
|
|
44
|
+
Analyze a POM file and display the dependencies in the console:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pomanalyzer <pom.xmlfilepath>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Generate HTML Report
|
|
51
|
+
|
|
52
|
+
Generate an HTML report of the dependencies:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pomanalyzer --html <pom.xmlfilepath>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Generate Markdown Report
|
|
59
|
+
|
|
60
|
+
Generate a Markdown report of the dependencies:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pomanalyzer --markdown <pom.xmlfilepath>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Generate Both HTML and Markdown Reports
|
|
67
|
+
|
|
68
|
+
Generate both HTML and Markdown reports:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pomanalyzer --markdown --html <pom.xmlfilepath>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Specify Output Folder
|
|
75
|
+
|
|
76
|
+
Generate reports and save them to a specific output folder:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pomanalyzer --markdown --html --output-folder output <pom.xmlfilepath>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Example Output
|
|
83
|
+
|
|
84
|
+
### Console Output
|
|
85
|
+
|
|
86
|
+
```plaintext
|
|
87
|
+
Analyzing POM file: <pom.xmlfilepath>
|
|
88
|
+
Maven Dependencies:
|
|
89
|
+
| Group ID | Artifact ID | Version |
|
|
90
|
+
|----------------|----------------|----------|
|
|
91
|
+
| org.example | example-lib | 1.0.0 |
|
|
92
|
+
| org.example | another-lib | 2.1.0 |
|
|
93
|
+
|
|
94
|
+
Duplicate Dependencies:
|
|
95
|
+
| Dependency | Versions |
|
|
96
|
+
|--------------------|----------------|
|
|
97
|
+
| org.example:lib | 1.0.0, 1.1.0 |
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### HTML and Markdown Reports
|
|
101
|
+
|
|
102
|
+
Reports are saved in the specified output folder with filenames like:
|
|
103
|
+
|
|
104
|
+
- `Maven_Dependencies_report.html`
|
|
105
|
+
- `Maven_Dependencies_report.md`
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
110
|
+
|
|
111
|
+
## Contributing
|
|
112
|
+
|
|
113
|
+
Contributions are welcome! Feel free to open issues or submit pull requests to improve the tool.
|
|
114
|
+
|
|
115
|
+
## Support
|
|
116
|
+
|
|
117
|
+
For issues or feature requests, please visit the [GitHub Issues](https://github.com/zackria/pomanalyzer/issues) page.
|
|
118
|
+
|
|
119
|
+
### Example Commands
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pomanalyzer ./test/Test1.xml
|
|
123
|
+
pomanalyzer --html ./test/Test1.xml
|
|
124
|
+
pomanalyzer --markdown ./test/Test1.xml
|
|
125
|
+
pomanalyzer --markdown --html ./test/Test1.xml
|
|
126
|
+
pomanalyzer --markdown --html --output-folder output ./test/Test1.xml
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
## Report Examples
|
|
131
|
+
|
|
132
|
+
### Terminal View
|
|
133
|
+

|
|
134
|
+
|
|
135
|
+
### HTML View
|
|
136
|
+

|
|
137
|
+
|
|
138
|
+
### Markdown View
|
|
139
|
+

|
|
140
|
+
|
|
141
|
+
## Quality Assurance
|
|
142
|
+
|
|
143
|
+
This package is thoroughly tested with over 90% code coverage to ensure reliability.
|
|
144
|
+
|
|
145
|
+

|
|
146
|
+
|
|
147
|
+
## Compatibility
|
|
148
|
+
|
|
149
|
+
Developed and tested with:
|
|
150
|
+
- npm v11.1.0
|
|
151
|
+
- Node.js v22.13.0
|
|
152
|
+
|
package/TEST.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Automated testing with Jest
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Run Your Tests
|
|
5
|
+
`npm init -y # if you haven't created a package.json yet`
|
|
6
|
+
`npm install --save-dev jest`
|
|
7
|
+
|
|
8
|
+
`npm test`
|
|
9
|
+
or
|
|
10
|
+
`npx jest`
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Check jest.config.js for testing configuration
|
|
14
|
+
|
|
15
|
+
`npm test -- --coverage`
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
`node src/index.js ./test/Test1.xml`
|
|
19
|
+
|
|
20
|
+
`node cli.js ./test/Test1.xml`
|
|
21
|
+
|
|
22
|
+
`node cli.js --html ./test/Test1.xml`
|
|
23
|
+
|
|
24
|
+
`node cli.js --markdown ./test/Test1.xml`
|
|
25
|
+
|
|
26
|
+
`node cli.js --markdown --html ./test/Test1.xml`
|
|
27
|
+
|
|
28
|
+
`node cli.js --markdown --html --output-folder output ./test/Test1.xml`
|
|
29
|
+
|
|
30
|
+
### Test with NPM Link
|
|
31
|
+
|
|
32
|
+
`pomanalyzer ./test/Test1.xml`
|
|
33
|
+
|
|
34
|
+
`pomanalyzer ./test/Test1.xml`
|
|
35
|
+
|
|
36
|
+
`pomanalyzer --html ./test/Test1.xml`
|
|
37
|
+
|
|
38
|
+
`pomanalyzer --markdown ./test/Test1.xml`
|
|
39
|
+
|
|
40
|
+
`pomanalyzer --markdown --html ./test/Test1.xml`
|
|
41
|
+
|
|
42
|
+
`pomanalyzer --markdown --html --output-folder output ./test/Test1.xml`
|
|
43
|
+
|
package/babel.config.js
ADDED
package/cli.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import { analyzePom } from './src/index.js';
|
|
5
|
+
import { readFileSync } from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
// Get version from package.json
|
|
9
|
+
let version = '1.0.0';
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
const packageJson = JSON.parse(readFileSync('./package.json', 'utf8'));
|
|
13
|
+
version = packageJson.version;
|
|
14
|
+
} catch (err) {
|
|
15
|
+
// Use default version if package.json can't be read
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Check if no arguments were provided
|
|
19
|
+
if (process.argv.length <= 2) {
|
|
20
|
+
console.log(`pomanalyzer v${version}`);
|
|
21
|
+
console.log('Usage: pomanalyzer [options] <pomFile>');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
program
|
|
26
|
+
.version(version)
|
|
27
|
+
.description('Analyze Maven POM XML files')
|
|
28
|
+
.option('--html', 'Generate HTML report')
|
|
29
|
+
.option('--markdown', 'Generate Markdown report')
|
|
30
|
+
.option('--output-folder <path>', 'Output folder for results')
|
|
31
|
+
.option('-v, --verbose', 'Show verbose output')
|
|
32
|
+
.arguments('<pomFile>')
|
|
33
|
+
.usage('[options] <pomFile>')
|
|
34
|
+
.action(async (pomFile, options) => {
|
|
35
|
+
try {
|
|
36
|
+
// Resolve file path
|
|
37
|
+
const resolvedPath = path.resolve(pomFile);
|
|
38
|
+
|
|
39
|
+
// Prepare options for analysis
|
|
40
|
+
const analysisOptions = {
|
|
41
|
+
html: options.html,
|
|
42
|
+
markdown: options.markdown,
|
|
43
|
+
outputFolder: options.outputFolder,
|
|
44
|
+
verbose: options.verbose
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Use the centralized analyzePom function
|
|
48
|
+
await analyzePom(resolvedPath, analysisOptions);
|
|
49
|
+
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error('Error:', error.message);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
program.parse(process.argv);
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
testEnvironment: "node", // Use Node.js environment
|
|
3
|
+
transform: {
|
|
4
|
+
"^.+\\.js$": "babel-jest", // Transform ES modules with Babel
|
|
5
|
+
},
|
|
6
|
+
transformIgnorePatterns: [
|
|
7
|
+
"/node_modules/(?!(chalk|ansi-styles|supports-color|strip-ansi|ansi-regex)/)", // Allow specific ES module packages to be transformed
|
|
8
|
+
],
|
|
9
|
+
testMatch: [
|
|
10
|
+
"**/tests/**/*.test.js",
|
|
11
|
+
"**/?(*.)+(spec|test).js"
|
|
12
|
+
],
|
|
13
|
+
collectCoverage: true,
|
|
14
|
+
coverageDirectory: 'coverage',
|
|
15
|
+
coverageReporters: ['text', 'lcov'],
|
|
16
|
+
verbose: true,
|
|
17
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Maven Dependencies Report</title>
|
|
6
|
+
<style>
|
|
7
|
+
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
8
|
+
h2 { color: #333; }
|
|
9
|
+
table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }
|
|
10
|
+
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
11
|
+
th { background-color: #f2f2f2; }
|
|
12
|
+
.duplicate { background-color: #ffcccc; }
|
|
13
|
+
</style>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
|
|
17
|
+
<h2>Maven Dependencies</h2>
|
|
18
|
+
<table>
|
|
19
|
+
<thead>
|
|
20
|
+
<tr>
|
|
21
|
+
<th>groupId</th><th>artifactId</th><th>version</th>
|
|
22
|
+
</tr>
|
|
23
|
+
</thead>
|
|
24
|
+
<tbody>
|
|
25
|
+
|
|
26
|
+
<tr>
|
|
27
|
+
<td>org.springframework</td><td>spring-core</td><td>5.3.9</td>
|
|
28
|
+
</tr>
|
|
29
|
+
|
|
30
|
+
<tr>
|
|
31
|
+
<td>org.springframework</td><td>spring-core</td><td>5.3.9</td>
|
|
32
|
+
</tr>
|
|
33
|
+
|
|
34
|
+
<tr>
|
|
35
|
+
<td>org.apache.commons</td><td>commons-lang3</td><td>N/A</td>
|
|
36
|
+
</tr>
|
|
37
|
+
|
|
38
|
+
<tr>
|
|
39
|
+
<td>org.apache.commons</td><td>commons-lang3</td><td>N/A</td>
|
|
40
|
+
</tr>
|
|
41
|
+
|
|
42
|
+
<tr>
|
|
43
|
+
<td>junit</td><td>junit</td><td>4.13.2</td>
|
|
44
|
+
</tr>
|
|
45
|
+
|
|
46
|
+
<tr>
|
|
47
|
+
<td>com.google.guava</td><td>guava</td><td>N/A</td>
|
|
48
|
+
</tr>
|
|
49
|
+
|
|
50
|
+
<tr>
|
|
51
|
+
<td>com.google.guava</td><td>guava</td><td>N/A</td>
|
|
52
|
+
</tr>
|
|
53
|
+
|
|
54
|
+
</tbody>
|
|
55
|
+
</table>
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
<h2>Duplicate Dependencies</h2>
|
|
59
|
+
<table>
|
|
60
|
+
<thead>
|
|
61
|
+
<tr>
|
|
62
|
+
<th>dependency</th><th>versions</th>
|
|
63
|
+
</tr>
|
|
64
|
+
</thead>
|
|
65
|
+
<tbody>
|
|
66
|
+
|
|
67
|
+
<tr class="duplicate">
|
|
68
|
+
<td>org.springframework:spring-core</td><td>5.3.9, 5.3.9</td>
|
|
69
|
+
</tr>
|
|
70
|
+
|
|
71
|
+
<tr class="duplicate">
|
|
72
|
+
<td>org.apache.commons:commons-lang3</td><td>N/A, N/A</td>
|
|
73
|
+
</tr>
|
|
74
|
+
|
|
75
|
+
<tr class="duplicate">
|
|
76
|
+
<td>com.google.guava:guava</td><td>N/A, N/A</td>
|
|
77
|
+
</tr>
|
|
78
|
+
|
|
79
|
+
</tbody>
|
|
80
|
+
</table>
|
|
81
|
+
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
84
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Report
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Maven Dependencies
|
|
5
|
+
|
|
6
|
+
| groupId | artifactId | version |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| org.springframework | spring-core | 5.3.9 |
|
|
9
|
+
| org.springframework | spring-core | 5.3.9 |
|
|
10
|
+
| org.apache.commons | commons-lang3 | N/A |
|
|
11
|
+
| org.apache.commons | commons-lang3 | N/A |
|
|
12
|
+
| junit | junit | 4.13.2 |
|
|
13
|
+
| com.google.guava | guava | N/A |
|
|
14
|
+
| com.google.guava | guava | N/A |
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Duplicate Dependencies
|
|
19
|
+
|
|
20
|
+
| dependency | versions |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| org.springframework:spring-core | 5.3.9, 5.3.9 | <!-- duplicate row -->
|
|
23
|
+
| org.apache.commons:commons-lang3 | N/A, N/A | <!-- duplicate row -->
|
|
24
|
+
| com.google.guava:guava | N/A, N/A | <!-- duplicate row -->
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pomanalyzer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "pomanalyzer is a utility to analyze Apache Maven POM XML file",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pom",
|
|
7
|
+
"xml",
|
|
8
|
+
"analyze",
|
|
9
|
+
"maven",
|
|
10
|
+
"depedencies"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/zackria/pomanalyzer#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/zackria/pomanalyzer/issues"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/zackria/pomanalyzer.git"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Zack Dawood",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "index.js",
|
|
24
|
+
"bin": {
|
|
25
|
+
"pomanalyzer": "./cli.js"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "jest",
|
|
29
|
+
"run": "node ./src/index.js"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@babel/core": "^7.26.10",
|
|
33
|
+
"@babel/preset-env": "^7.26.9",
|
|
34
|
+
"babel-jest": "^29.7.0",
|
|
35
|
+
"jest": "^29.7.0",
|
|
36
|
+
"jest-environment-node": "^29.7.0"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"chalk": "^5.4.1",
|
|
40
|
+
"commander": "^13.1.0",
|
|
41
|
+
"js-yaml": "^4.1.0",
|
|
42
|
+
"xml2js": "^0.6.2"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=14.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readPomXml } from "./services/dependencyService.js";
|
|
2
|
+
import { checkForDuplicates } from "./services/duplicateChecker.js";
|
|
3
|
+
import { printTable } from "./utils/outputFormatter.js";
|
|
4
|
+
import { printHTMLTable } from "./utils/printHTMLTable.js";
|
|
5
|
+
import { printMarkdownTable } from "./utils/printMarkdownTable.js";
|
|
6
|
+
import chalk from "chalk"; // added Chalk import
|
|
7
|
+
|
|
8
|
+
export async function analyzePom(pomXmlPath, options = {}) {
|
|
9
|
+
try {
|
|
10
|
+
console.log(`Analyzing POM file: ${pomXmlPath}`);
|
|
11
|
+
const dependencies = await readPomXml(pomXmlPath, options);
|
|
12
|
+
|
|
13
|
+
if (dependencies && dependencies.length > 0) {
|
|
14
|
+
printTable(dependencies, "Maven Dependencies");
|
|
15
|
+
|
|
16
|
+
const duplicateDependencies = checkForDuplicates(dependencies);
|
|
17
|
+
let duplicateSummary = [];
|
|
18
|
+
if (duplicateDependencies.length > 0) {
|
|
19
|
+
duplicateSummary = duplicateDependencies.map(depList => ({
|
|
20
|
+
dependency: `${depList[0].groupId}:${depList[0].artifactId}`,
|
|
21
|
+
versions: depList.map(dep => dep.version).join(", "),
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Generate additional reports if flags are provided.
|
|
26
|
+
if (options.html) {
|
|
27
|
+
printHTMLTable(dependencies, duplicateSummary, "Maven Dependencies", options.outputFolder);
|
|
28
|
+
}
|
|
29
|
+
if (options.markdown) {
|
|
30
|
+
printMarkdownTable(dependencies, duplicateSummary, "Maven Dependencies", options.outputFolder);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if (duplicateSummary.length > 0) {
|
|
35
|
+
console.log(chalk.yellow("Duplicate dependencies found:"));
|
|
36
|
+
duplicateSummary.forEach(dup => {
|
|
37
|
+
console.log(chalk.red(`${dup.dependency} -> ${dup.versions}`));
|
|
38
|
+
});
|
|
39
|
+
} else {
|
|
40
|
+
console.log("No duplicate dependencies found.");
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
console.log("No dependencies found in the POM file.");
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error("Error analyzing POM file:", error);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/services/dependencyService.js
|
|
2
|
+
import { readFile } from '../utils/fileUtils.js';
|
|
3
|
+
import { parseXml } from '../utils/xmlParser.js';
|
|
4
|
+
import { resolveVersion } from '../utils/dependencyResolver.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reads and parses a Maven pom.xml file.
|
|
8
|
+
* @param {string} filePath - The path to the pom.xml file.
|
|
9
|
+
* @returns {Promise<Array>} - A promise that resolves to an array of dependencies.
|
|
10
|
+
*/
|
|
11
|
+
export async function readPomXml(filePath) {
|
|
12
|
+
try {
|
|
13
|
+
const xmlContent = await readFile(filePath);
|
|
14
|
+
const result = await parseXml(xmlContent); // Use await here
|
|
15
|
+
const dependencies = extractDependencies(result);
|
|
16
|
+
return dependencies;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw new Error(`Error reading pom.xml: ${error.message}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Extracts dependencies from the parsed XML result.
|
|
24
|
+
* @param {Object} result - The parsed XML result.
|
|
25
|
+
* @returns {Array} - An array of dependencies.
|
|
26
|
+
*/
|
|
27
|
+
function extractDependencies(result) {
|
|
28
|
+
const dependencies = [];
|
|
29
|
+
|
|
30
|
+
if (!result || !result.project) {
|
|
31
|
+
return dependencies;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const properties = result.project.properties ? result.project.properties[0] : {};
|
|
35
|
+
|
|
36
|
+
if (result.project.dependencies && result.project.dependencies[0] && result.project.dependencies[0].dependency) {
|
|
37
|
+
dependencies.push(
|
|
38
|
+
...result.project.dependencies[0].dependency.map((dep) => ({
|
|
39
|
+
groupId: dep.groupId ? dep.groupId[0] : 'unknown',
|
|
40
|
+
artifactId: dep.artifactId ? dep.artifactId[0] : 'unknown',
|
|
41
|
+
version: resolveVersion(dep.version && dep.version[0] ? dep.version[0] : 'N/A', properties),
|
|
42
|
+
}))
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (result.project.dependencyManagement &&
|
|
47
|
+
result.project.dependencyManagement[0] &&
|
|
48
|
+
result.project.dependencyManagement[0].dependencies &&
|
|
49
|
+
result.project.dependencyManagement[0].dependencies[0] &&
|
|
50
|
+
result.project.dependencyManagement[0].dependencies[0].dependency) {
|
|
51
|
+
dependencies.push(
|
|
52
|
+
...result.project.dependencyManagement[0].dependencies[0].dependency.map((dep) => ({
|
|
53
|
+
groupId: dep.groupId ? dep.groupId[0] : 'unknown',
|
|
54
|
+
artifactId: dep.artifactId ? dep.artifactId[0] : 'unknown',
|
|
55
|
+
version: resolveVersion(dep.version && dep.version[0] ? dep.version[0] : 'N/A', properties),
|
|
56
|
+
}))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return dependencies;
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identifies duplicate dependencies based on groupId and artifactId.
|
|
3
|
+
* @param {Array} dependencies - List of dependencies from the POM file.
|
|
4
|
+
* @returns {Array} - List of duplicate dependencies grouped by groupId:artifactId.
|
|
5
|
+
*/
|
|
6
|
+
export function checkForDuplicates(dependencies) {
|
|
7
|
+
const duplicates = dependencies.reduce((acc, dep) => {
|
|
8
|
+
const key = `${dep.groupId}:${dep.artifactId}`;
|
|
9
|
+
if (!acc[key]) {
|
|
10
|
+
acc[key] = [];
|
|
11
|
+
}
|
|
12
|
+
acc[key].push(dep);
|
|
13
|
+
return acc;
|
|
14
|
+
}, {});
|
|
15
|
+
|
|
16
|
+
return Object.values(duplicates).filter((depList) => depList.length > 1);
|
|
17
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/utils/dependencyResolver.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolves a Maven-style property placeholder in a version string.
|
|
5
|
+
*
|
|
6
|
+
* @param {string|null} version - The version string that may contain a property placeholder (e.g., "${project.version}")
|
|
7
|
+
* @param {Object} properties - An object containing property key-value pairs from the Maven POM file
|
|
8
|
+
* @returns {string} The resolved version string or "N/A" if the version couldn't be resolved
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // If properties = { "project.version": ["1.0.0"] }
|
|
12
|
+
* resolveVersion("${project.version}", properties) // returns "1.0.0"
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // If the property doesn't exist
|
|
16
|
+
* resolveVersion("${unknown.property}", properties) // returns "N/A"
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // If version is a regular string
|
|
20
|
+
* resolveVersion("2.1.0", properties) // returns "2.1.0"
|
|
21
|
+
*/
|
|
22
|
+
export const resolveVersion = (version, properties) => {
|
|
23
|
+
if (version && version.startsWith('${') && version.endsWith('}')) {
|
|
24
|
+
const propertyName = version.slice(2, -1);
|
|
25
|
+
return properties[propertyName] ? properties[propertyName][0] : 'N/A';
|
|
26
|
+
}
|
|
27
|
+
return version || 'N/A';
|
|
28
|
+
};
|