Skip to content

Commit 2d96593

Browse files
committed
refactor: split up loader
1 parent c18f2b8 commit 2d96593

File tree

5 files changed

+187
-171
lines changed

5 files changed

+187
-171
lines changed

lib/loader/index.js

Lines changed: 6 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,182 +1,19 @@
11
'use strict';
22

3-
const Debug = require('debug');
4-
const Fs = require('fs');
5-
const GitUrlParse = require('git-url-parse');
6-
const Package = require('../../package.json');
7-
const Pacote = require('pacote');
8-
const Path = require('path');
9-
const Wreck = require('@hapi/wreck');
10-
11-
const Utils = require('../utils');
12-
13-
const internals = {
14-
cache: new Map(),
15-
log: Debug('detect-node-support:loader'),
16-
error: Debug('detect-node-support:error')
17-
};
18-
19-
20-
internals.parseRepository = (packument) => {
21-
22-
if (typeof packument.repository === 'string') {
23-
return packument.repository;
24-
}
25-
26-
if (!packument.repository || !packument.repository.url) {
27-
throw new Error(`Unable to determine the git repository for ${packument.name}`);
28-
}
29-
30-
return packument.repository.url;
31-
};
32-
33-
34-
internals.createPackageLoader = async (packageName) => {
35-
36-
try {
37-
const packument = await Pacote.packument(packageName + '@latest', {
38-
'fullMetadata': true,
39-
'user-agent': `${Package.name}@${Package.version}, see ${Package.homepage}`
40-
});
41-
42-
const repository = internals.parseRepository(packument);
43-
44-
const repositoryLoader = internals.createRepositoryLoader(repository);
45-
46-
return {
47-
...repositoryLoader,
48-
loadFile: async (filename, options) => {
49-
50-
const result = await repositoryLoader.loadFile(filename, options);
51-
52-
if (filename === 'package.json' && result.name !== packageName) {
53-
throw new Error(`${repository} does not contain ${packageName}. Monorepo not supported: https://github.com/pkgjs/detect-node-support/issues/6`);
54-
}
55-
56-
return result;
57-
}
58-
};
59-
}
60-
catch (err) {
61-
62-
if (err.statusCode === 404) {
63-
throw new Error(`Package ${packageName} does not exist`);
64-
}
65-
66-
throw err;
67-
68-
}
69-
};
70-
71-
72-
internals.createRepositoryLoader = (repository) => {
73-
74-
if (repository.split('/').length === 2) {
75-
repository = `https://github.com/${repository}`;
76-
}
77-
78-
const parsedRepository = GitUrlParse(repository);
79-
80-
return {
81-
getCommit: async () => {
82-
83-
const simpleGit = Utils.simpleGit();
84-
const httpRepository = GitUrlParse.stringify(parsedRepository, 'http');
85-
const result = await simpleGit.listRemote([httpRepository, 'HEAD']);
86-
const [head] = result.split(/\s+/);
87-
88-
return head;
89-
},
90-
loadFile: async (filename, options) => {
91-
92-
if (parsedRepository.source !== 'github.com') {
93-
throw new Error('Only github.com paths supported, feel free to PR at https://github.com/pkgjs/detect-node-support');
94-
}
95-
96-
const url = `https://raw.githubusercontent.com/${parsedRepository.full_name}/HEAD/${filename}`;
97-
internals.log('Loading: %s', url);
98-
99-
if (options === undefined && internals.cache.has(url)) {
100-
internals.log('From cache: %s', url);
101-
return internals.cache.get(url);
102-
}
103-
104-
try {
105-
const { payload } = await Wreck.get(url, options);
106-
107-
if (options === undefined) {
108-
internals.cache.set(url, payload);
109-
}
110-
111-
internals.log('Loaded: %s', url);
112-
return payload;
113-
}
114-
catch (err) {
115-
116-
if (err.data && err.data.res.statusCode === 404) {
117-
internals.log('Not found: %s', url);
118-
const error = new Error(`${repository} does not contain a ${filename}`);
119-
error.code = 'ENOENT';
120-
throw error;
121-
}
122-
123-
internals.error('Failed to load: %s', url);
124-
throw err;
125-
}
126-
}
127-
};
128-
};
129-
130-
131-
internals.createPathLoader = async (path) => {
132-
133-
const simpleGit = Utils.simpleGit(path);
134-
const isRepo = await simpleGit.checkIsRepo();
135-
136-
if (!isRepo) {
137-
throw new Error(`${path} is not a git repository`);
138-
}
139-
140-
if (!Fs.existsSync(Path.join(path, 'package.json'))) {
141-
throw new Error(`${path} does not contain a package.json`);
142-
}
143-
144-
return {
145-
getCommit: () => {
146-
147-
return simpleGit.revparse(['HEAD']);
148-
},
149-
loadFile: (filename, options = {}) => {
150-
151-
const fullPath = Path.join(path, filename);
152-
153-
const buffer = Fs.readFileSync(fullPath);
154-
155-
if (options.json) {
156-
return JSON.parse(buffer.toString());
157-
}
158-
159-
return buffer;
160-
}
161-
};
162-
};
3+
const NpmLoader = require('./npm');
4+
const PathLoader = require('./path');
5+
const RepositoryLoader = require('./repository');
1636

1647

1658
exports.create = ({ path, repository, packageName }) => {
1669

16710
if (repository) {
168-
return internals.createRepositoryLoader(repository);
11+
return RepositoryLoader.create(repository);
16912
}
17013

17114
if (packageName) {
172-
return internals.createPackageLoader(packageName);
15+
return NpmLoader.create(packageName);
17316
}
17417

175-
return internals.createPathLoader(path);
176-
};
177-
178-
179-
exports.clearCache = () => {
180-
181-
internals.cache = new Map();
18+
return PathLoader.create(path);
18219
};

lib/loader/npm.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
3+
const Package = require('../../package.json');
4+
const Pacote = require('pacote');
5+
6+
const RepositoryLoader = require('./repository');
7+
8+
const internals = {};
9+
10+
11+
internals.parseRepository = (packument) => {
12+
13+
if (typeof packument.repository === 'string') {
14+
return packument.repository;
15+
}
16+
17+
if (!packument.repository || !packument.repository.url) {
18+
throw new Error(`Unable to determine the git repository for ${packument.name}`);
19+
}
20+
21+
return packument.repository.url;
22+
};
23+
24+
25+
exports.create = async (packageName) => {
26+
27+
try {
28+
const packument = await Pacote.packument(packageName + '@latest', {
29+
'fullMetadata': true,
30+
'user-agent': `${Package.name}@${Package.version}, see ${Package.homepage}`
31+
});
32+
33+
const repository = internals.parseRepository(packument);
34+
35+
const repositoryLoader = RepositoryLoader.create(repository);
36+
37+
return {
38+
...repositoryLoader,
39+
loadFile: async (filename, options) => {
40+
41+
const result = await repositoryLoader.loadFile(filename, options);
42+
43+
if (filename === 'package.json' && result.name !== packageName) {
44+
throw new Error(`${repository} does not contain ${packageName}. Monorepo not supported: https://github.com/pkgjs/detect-node-support/issues/6`);
45+
}
46+
47+
return result;
48+
}
49+
};
50+
}
51+
catch (err) {
52+
53+
if (err.statusCode === 404) {
54+
throw new Error(`Package ${packageName} does not exist`);
55+
}
56+
57+
throw err;
58+
59+
}
60+
};

lib/loader/path.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
3+
const Fs = require('fs');
4+
const Path = require('path');
5+
6+
const Utils = require('../utils');
7+
8+
9+
exports.create = async (path) => {
10+
11+
const simpleGit = Utils.simpleGit(path);
12+
const isRepo = await simpleGit.checkIsRepo();
13+
14+
if (!isRepo) {
15+
throw new Error(`${path} is not a git repository`);
16+
}
17+
18+
if (!Fs.existsSync(Path.join(path, 'package.json'))) {
19+
throw new Error(`${path} does not contain a package.json`);
20+
}
21+
22+
return {
23+
getCommit: () => {
24+
25+
return simpleGit.revparse(['HEAD']);
26+
},
27+
loadFile: (filename, options = {}) => {
28+
29+
const fullPath = Path.join(path, filename);
30+
31+
const buffer = Fs.readFileSync(fullPath);
32+
33+
if (options.json) {
34+
return JSON.parse(buffer.toString());
35+
}
36+
37+
return buffer;
38+
}
39+
};
40+
};

lib/loader/repository.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
'use strict';
2+
3+
const Debug = require('debug');
4+
const GitUrlParse = require('git-url-parse');
5+
const Wreck = require('@hapi/wreck');
6+
7+
const Utils = require('../utils');
8+
9+
10+
const internals = {
11+
cache: new Map(),
12+
log: Debug('detect-node-support:loader'),
13+
error: Debug('detect-node-support:error')
14+
};
15+
16+
17+
exports.create = (repository) => {
18+
19+
if (repository.split('/').length === 2) {
20+
repository = `https://github.com/${repository}`;
21+
}
22+
23+
const parsedRepository = GitUrlParse(repository);
24+
25+
return {
26+
getCommit: async () => {
27+
28+
const simpleGit = Utils.simpleGit();
29+
const httpRepository = GitUrlParse.stringify(parsedRepository, 'http');
30+
const result = await simpleGit.listRemote([httpRepository, 'HEAD']);
31+
const [head] = result.split(/\s+/);
32+
33+
return head;
34+
},
35+
loadFile: async (filename, options) => {
36+
37+
if (parsedRepository.source !== 'github.com') {
38+
throw new Error('Only github.com paths supported, feel free to PR at https://github.com/pkgjs/detect-node-support');
39+
}
40+
41+
const url = `https://raw.githubusercontent.com/${parsedRepository.full_name}/HEAD/${filename}`;
42+
internals.log('Loading: %s', url);
43+
44+
if (options === undefined && internals.cache.has(url)) {
45+
internals.log('From cache: %s', url);
46+
return internals.cache.get(url);
47+
}
48+
49+
try {
50+
const { payload } = await Wreck.get(url, options);
51+
52+
if (options === undefined) {
53+
internals.cache.set(url, payload);
54+
}
55+
56+
internals.log('Loaded: %s', url);
57+
return payload;
58+
}
59+
catch (err) {
60+
61+
if (err.data && err.data.res.statusCode === 404) {
62+
internals.log('Not found: %s', url);
63+
const error = new Error(`${repository} does not contain a ${filename}`);
64+
error.code = 'ENOENT';
65+
throw error;
66+
}
67+
68+
internals.error('Failed to load: %s', url);
69+
throw err;
70+
}
71+
}
72+
};
73+
};
74+
75+
76+
exports.clearCache = () => {
77+
78+
internals.cache = new Map();
79+
};

test/fixtures/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const SimpleGit = require('simple-git/promise');
77
const Sinon = require('sinon');
88
const Tmp = require('tmp');
99

10-
const Loader = require('../../lib/loader');
10+
const RepositoryLoader = require('../../lib/loader/repository');
1111
const Utils = require('../../lib/utils');
1212

1313

@@ -29,7 +29,7 @@ module.exports = class TestContext {
2929

3030
cleanup() {
3131

32-
Loader.clearCache();
32+
RepositoryLoader.clearCache();
3333

3434
Sinon.restore();
3535

0 commit comments

Comments
 (0)