Skip to content

Commit f9d6714

Browse files
authored
Merge pull request #97 from wongjn/use-vscode-globalState
Refactor extension state persistence
2 parents b1638de + 3b55f8e commit f9d6714

7 files changed

+46
-90
lines changed

src/config.js

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class Config {
3939
this.supportsSVN = vscodeConfig.get('supportsSVN', false);
4040
this.displayProjectPath = vscodeConfig.get('displayProjectPath', false);
4141
}
42+
43+
get(param, defaultValue = undefined) {
44+
return this.hasOwnProperty(param) ? this[param] : defaultValue;
45+
}
4246
}
4347

4448
module.exports = Config;

src/extension.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ const vscode = require('vscode');
44
const ProjectManager = require('./gitProjectManager');
55
const Config = require('./config');
66
const cfg = new Config(vscode.workspace.getConfiguration('gitProjectManager'))
7-
const projectManager = new ProjectManager(cfg);
87

98
// this method is called when your extension is activated
109
// your extension is activated the very first time the command is executed
1110
function activate(context) {
11+
const projectManager = new ProjectManager(cfg, context.globalState);
1212

1313
let disposable = vscode.commands.registerCommand('gitProjectManager.openProject', function () {
1414
projectManager.showProjectList(false);

src/gitProjectManager.js

+16-39
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
const EXTENSION_NAME = 'gitProjectManager';
2-
31
const fs = require('fs');
42
const vscode = require('vscode');
53
const path = require('path');
@@ -18,32 +16,18 @@ class GitProjectManager {
1816
* Creates an instance of GitProjectManager.
1917
*
2018
* @param {object} config
19+
* @param {Memento} state
2120
*/
22-
constructor(config) {
21+
constructor(config, state) {
2322
this.config = config;
23+
this.state = state;
2424
this.loadedRepoListFromFile = false;
2525
this.repoList = [];
2626
this.storedLists = new Map();
27-
this.baseDir = this.getBaseDir();
28-
this.gpmRepoListFile = path.join(this.baseDir, this.getChannelPath(), "User/gpm_projects.json");
29-
this.recentList = new RecentItems(path.join(this.baseDir, this.getChannelPath(), "User/"));
30-
this.recentList.listSize = vscode.workspace.getConfiguration(EXTENSION_NAME).get('gitProjectManager.recentProjectsListSize', 5);
27+
this.recentList = new RecentItems(this.state, this.config.get('gitProjectManager.recentProjectsListSize', 5));
3128

3229
this.updateRepoList = this.updateRepoList.bind(this);
3330
this.addRepoInRepoList = this.addRepoInRepoList.bind(this);
34-
35-
}
36-
/**
37-
* Get the base user cfg directory
38-
*
39-
* @returns {string}
40-
*/
41-
getBaseDir() {
42-
if (process.platform == "linux") {
43-
return path.join(os.homedir(), '.config');
44-
} else {
45-
return process.env.APPDATA || (process.platform === 'darwin' ? process.env.HOME + '/Library/Application Support' : '/var/local');
46-
}
4731
}
4832
getQuickPickList() {
4933
this.repoList = this.repoList.sort((a, b) => {
@@ -77,47 +61,40 @@ class GitProjectManager {
7761
get storeDataBetweenSessions() {
7862
return this.config.storeRepositoriesBetweenSessions;
7963
}
80-
saveListToDisc() {
64+
saveList() {
8165
if (!this.storeDataBetweenSessions)
8266
return;
8367

84-
let lists = {};
85-
this.storedLists.forEach((value, key) => { lists[key] = value })
86-
fs.writeFileSync(this.gpmRepoListFile, JSON.stringify(lists), {
87-
encoding: 'utf8'
88-
});
68+
const lists = Array.from(this.storedLists.entries()).reduce(
69+
(storage, [hash, repos]) => ({ ...storage, [hash]: repos }),
70+
{},
71+
);
72+
this.state.update('lists', lists);
8973
}
90-
loadlListFromDisc() {
74+
loadList() {
9175
if (!this.storeDataBetweenSessions)
9276
return false;
9377

94-
if (!fs.existsSync(this.gpmRepoListFile))
95-
return false;
96-
97-
let list = JSON.parse(fs.readFileSync(this.gpmRepoListFile, 'utf8'));
98-
if (list instanceof Array) {
99-
fs.unlinkSync(this.gpmRepoListFile);
78+
const list = this.state.get('lists', false);
79+
if (!list)
10080
return false;
101-
}
10281

103-
this.storedLists = new Map();
104-
for (let key in list)
105-
this.storedLists.set(key, list[key]);
82+
this.storedLists = new Map(Array.from(Object.entries(list)));
10683

10784
this.loadedRepoListFromFile = true;
10885
return true;
10986
}
11087
saveRepositoryInfo(directories) {
11188
this.storedLists.set(this.getDirectoriesHash(directories), this.repoList);
112-
this.saveListToDisc();
89+
this.saveList();
11390
}
11491

11592
loadRepositoryInfo() {
11693
if (this.loadedRepoListFromFile) {
11794
return false;
11895
}
11996

120-
return this.loadlListFromDisc();
97+
return this.loadList();
12198
}
12299

123100
addRepoInRepoList(repoInfo) {

src/recentItems.js

+8-33
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,14 @@
1-
const path = require('path');
2-
const fs = require('fs');
3-
4-
5-
const RECENT_FILE_NAME = 'gpm-recentItems.json';
6-
71
class RecentItems {
82
/**
93
* Creates an instance of RecentItems.
10-
*
11-
* @param {string} pathToSave Path where the RecentItems file will be saved
12-
*/
13-
constructor(pathToSave) {
14-
this.pathToSave = pathToSave;
15-
this.listSize = 5;
16-
this.list = [];
17-
this.loadFromFile();
18-
}
19-
/**
20-
* Returns the full path to recent projects file
21-
*
22-
* @returns {string}
4+
*
5+
* @param {Memento} state Global extension state.
6+
* @param {number} [listSize=5] Recent items list size.
237
*/
24-
getPathToFile() {
25-
return path.join(this.pathToSave, RECENT_FILE_NAME);
26-
}
27-
loadFromFile() {
28-
const filePath = this.getPathToFile();
29-
if (fs.existsSync(filePath) && typeof filePath !== 'undefined') {
30-
this.list = JSON.parse(fs.readFileSync(filePath, 'utf8'));
31-
}
32-
}
33-
saveToFile() {
34-
fs.writeFileSync(this.getPathToFile(), JSON.stringify(this.list), {
35-
encoding: 'utf8'
36-
});
8+
constructor(state, listSize = 5) {
9+
this.state = state;
10+
this.listSize = listSize;
11+
this.list = this.state.get('recent', []);
3712
}
3813
addProject(projectPath, gitRepo) {
3914
const idx = this.list.findIndex(p => p.projectPath === projectPath);
@@ -48,7 +23,7 @@ class RecentItems {
4823
};
4924

5025
this.sortList();
51-
this.saveToFile();
26+
this.state.update('recent', this.list);
5227
}
5328
sortList() {
5429
this.list = this.list.sort((a, b) => b.lastUsed - a.lastUsed);

test/gitProjectManager.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const vscode = require('vscode');
66

77
const ProjectManager = require('../src/gitProjectManager');
88
const Config = require('../src/config');
9-
const config = new Config();
10-
const projectManager = new ProjectManager(config)
9+
const StateMock = require('./stateMock');
10+
const projectManager = new ProjectManager(new Config(), new StateMock());
1111

1212
describe("gitProjectManager", function () {
1313
var sandbox;

test/recentItems.test.js

+4-15
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
const RecentItems = require('../src/recentItems');
44
const expect = require('chai').expect;
5-
const path = require('path');
6-
const fs = require('fs');
75
const rmdir = require('rmdir');
86
const sinon = require('sinon');
97

10-
const TESTING_PATH = path.join(__dirname, 'recents');
8+
const StateMock = require('./stateMock');
119

1210
function addProjectsToList(recentList, size) {
1311
switch (size) {
@@ -27,19 +25,10 @@ function addProjectsToList(recentList, size) {
2725
}
2826

2927
describe('RecentItems', () => {
30-
let recentItems = new RecentItems(TESTING_PATH);
28+
let recentItems;
3129

3230
beforeEach(() => {
33-
if (fs.existsSync(TESTING_PATH)) {
34-
fs.rmdirSync(TESTING_PATH);
35-
}
36-
fs.mkdirSync(TESTING_PATH);
37-
recentItems = new RecentItems(TESTING_PATH);
38-
39-
});
40-
41-
afterEach((done) => {
42-
rmdir(TESTING_PATH, {}, () => done())
31+
recentItems = new RecentItems(new StateMock());
4332
});
4433

4534
it('should start with an empty list', () => {
@@ -53,7 +42,7 @@ describe('RecentItems', () => {
5342

5443
it('should load projects on create', () => {
5544
addProjectsToList(recentItems, 2);
56-
const secondInstance = new RecentItems(TESTING_PATH);
45+
const secondInstance = new RecentItems(recentItems.state);
5746
expect(secondInstance.list.length).to.be.equals(2);
5847
})
5948

test/stateMock.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = class {
2+
constructor() {
3+
this.data = {};
4+
}
5+
get(key, defaultValue = undefined) {
6+
return this.data.hasOwnProperty(key) ? this.data[key] : defaultValue;
7+
}
8+
async update(key, value) {
9+
this.data[key] = value;
10+
}
11+
}

0 commit comments

Comments
 (0)