irongit

A simpler way to view django projects

test gets models

huncholanehuncholaneauthored
parent f7a8139commit 5eed920a870eac575f0ef91b4638a16385b105edBrowse files

3 files changed, +101 -18

+94-17src/project.ts
@@ -3,41 +3,106 @@ import { getDjangoProjectDir } from "./context";
33 import * as fs from "fs";
44 import { promisify } from "util";
55 import regex from "./regex";
6+import path from "path";
7+import * as vscode from "vscode";
8+
9+const readFile = promisify(fs.readFile);
610
711 type Field = {
812 name: string;
913 type: string;
10- required: boolean;
11- unique: boolean;
12- default: string;
13- max_length: number;
14- choices: [string];
14+ index: number;
1515 };
1616
1717 type Model = {
1818 name: string;
19- fields: [Field];
19+ index: number;
20+ fields: Field[];
2021 };
2122
22-type App = {
23+class App {
2324 name: string;
24- // path: string;
25- // urls: [string];
26- // models: [{string: Model}];
27-};
25+ module: string;
26+ path: string;
27+ models: Model[];
2828
29-type Project = {
30- name: string;
31-};
32-
33-const readFile = promisify(fs.readFile);
29+ constructor(module: string) {
30+ this.module = module;
31+ this.models = [];
32+ let name = module.split(".").pop();
33+ const pythonPath =
34+ vscode.workspace.getConfiguration("python").get("pythonPath") ||
35+ "python3";
36+ if (name) {
37+ this.name = name;
38+ } else {
39+ throw new Error("Invalid module name");
40+ }
41+ const pythonScript = `
42+import importlib.util
43+import os
44+module = '${this.module}'
45+spec = importlib.util.find_spec(module)
46+if spec is not None and spec.origin is not None:
47+ print(os.path.dirname(spec.origin))
48+ `;
49+ try {
50+ const result = childProcess
51+ .execSync(`${pythonPath} -c "${pythonScript}"`)
52+ .toString();
53+ this.path = result.trim();
54+ } catch (error) {
55+ console.error(error);
56+ throw new Error(`Error getting path for app ${this.name}`);
57+ }
58+ console.log(`Reading models.py for app ${this.name}`);
59+ try {
60+ const data = fs.readFileSync(`${this.path}/models.py`, "utf-8");
61+ const models = data.matchAll(regex.model);
62+ for (const modelMatch of models) {
63+ const model: Model = {
64+ name: modelMatch[1],
65+ index: modelMatch.index || 0,
66+ fields: [],
67+ };
68+ const fields = modelMatch[2].matchAll(regex.modelField);
69+ for (const fieldMatch of fields) {
70+ const field: Field = {
71+ name: fieldMatch[1],
72+ type: fieldMatch[2],
73+ index: fieldMatch.index || 0,
74+ };
75+ model.fields.push(field);
76+ }
77+ this.models.push(model);
78+ }
79+ console.log(models);
80+ } catch (err) {
81+ console.error(`Error reading models.py for app ${this.name}`);
82+ // throw new Error(`Error reading models.py for app ${this.name}`);
83+ }
84+ }
85+}
3486
3587 export default class DjangoProject {
36- projectDir?: string;
88+ projectDir: string;
3789 name?: string;
90+ apps: App[];
3891
3992 constructor(rootDir: string) {
4093 this.projectDir = rootDir;
94+ this.apps = [];
95+ }
96+
97+ async read() {
98+ const originalDir = process.cwd();
99+ process.chdir(this.projectDir);
100+ try {
101+ await this.parseManagePy();
102+ await this.parseSettings();
103+ } finally {
104+ process.chdir(originalDir);
105+ }
41106 }
42107
43108 async parseManagePy() {
@@ -46,6 +111,18 @@ export default class DjangoProject {
46111 const match = text.match(regex.projectName);
47112 this.name = match ? match[1] : undefined;
48113 }
114+
115+ async parseSettings() {
116+ const settingsPath = `${this.projectDir}/${this.name}/settings.py`;
117+ const text = await readFile(settingsPath, "utf-8");
118+ const appContainerMatch = text.match(regex.appContainer);
119+ const appContainer = appContainerMatch ? appContainerMatch[1] : "";
120+ const apps = appContainer.matchAll(regex.module);
121+ for (const app of apps ? apps : []) {
122+ this.apps.push(new App(app[1]));
123+ }
124+ console.log(apps);
125+ }
49126 }
50127
51128 export const getProject = async () => {};
+4-0src/regex.ts
@@ -1,3 +1,7 @@
11 export default {
22 projectName: /([^']+?)\.settings/,
3+ appContainer: /INSTALLED_APPS = \[([\s\S]*?)\]/,
4+ module: /'([\.\w]+)'/gm,
5+ model: /class (\w+).*models.Model.*:([\s\S]*?)\n\n/gm,
6+ modelField: /(\w+) = .*\.(\w+)Field/gm,
37 };
+3-1src/test/extension.test.ts
@@ -13,6 +13,8 @@ suite("Extension Test Suite", () => {
1313 console.log("HELLO");
1414 const project = new DjangoProject("sample");
1515 await project.parseManagePy();
16- console.log(project);
16+ await project.parseSettings();
17+ console.log("Project:");
18+ console.log(JSON.stringify(project, null, 2));
1719 });
1820 });