-
Notifications
You must be signed in to change notification settings - Fork 40
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
Export schemas #428
Export schemas #428
Conversation
*Enable/Disable when a realm browser window gains/loses focus *Export JS *Export swift
@kraenhansen @bmunkholm The branch has some TS errors related to the schema exporter library. Should I fix this? Or what are we going to do finally with this dependency? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of TS code in the exporter service that I would like to follow the codestyle of the project.
Also yes - I would like the tests to be passing before merging this in.
@@ -53,6 +54,9 @@ export class RealmBrowserContainer extends RealmLoadingComponent< | |||
progress: { done: false }, | |||
schemas: [], | |||
}; | |||
|
|||
ipcRenderer.on('exportSwiftSchema', this.onExportSwiftSchema); | |||
ipcRenderer.on('exportJSSchema', this.onExportJSSchema); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make this a single event name, and use "dash-case", fx: export-schema
and have that take a parameter determining to what language the schema should be exported. That would require way less changes to the code as new languages are added.
exp.exportSchema(this.realm); | ||
exp.writeFilesToDisk(selectedPaths); | ||
}); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally I would move this code into the service and call it by exporter.showSaveDialogAndSave
(or something similar).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it better to keep the exporter functionality without UI so it's easier to migrate to a tool at some point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be a good thing - but it's a very little part of the code, so I'd rather be able to call it from anywhere in the app and have it behave in the same way and build an abstraction around it when we need to.
"forceConsistentCasingInFileNames": true, | ||
"outDir": "dist", | ||
"allowJs": true, | ||
//"declaration": true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not valid JSON, just delete the line.
I would actually like if we could delete the whole tsconfig.json here, what is the reason this could not follow the same config as the root project?
"check-type" | ||
] | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with this tslint.json - any reasons we cannot use the main projects linting here?
const fullpath = fsPath.resolve(path, file.filename) | ||
if (debug) { | ||
console.log('--- path: ' + fullpath) | ||
console.log(file.content) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No console.logs except if it's strictly needed .. alternatively use a logger.
"dependencies": { | ||
"fs-extra": "^4.0.2" | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am tempted to say this shouldn't go in .. we might eventually want to release this as its own package, but I think we should leave it out for now. Especially with the generic name and description that it has now.
src/main/MainMenu.ts
Outdated
if (ModelDefinitions && ModelDefinitions.submenu) { | ||
(ModelDefinitions.submenu as Electron.Menu).items.map( | ||
item => | ||
((item as Electron.MenuItemConstructorOptions).enabled = enable), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of enable vs. disable, I think it should be visible vs hidden.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kraenhansen I think that the common pattern in desktop app is enables/disables, also in the old app, we are using it like this.
src/main/Application.ts
Outdated
window.on('close', () => { | ||
this.mainMenu.enableModelDefinitions(false); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this - I think we should have a way to configure what menus should be used when a specific type of window gets into focus. It could be an extra field returned when calling windowOptions: https://github.com/realm/realm-studio/blob/master/src/windows/WindowType.ts
And then move the on window blur, focus and close event handlers to the WindowManager.ts.
src/main/MainMenu.ts
Outdated
} | ||
|
||
public enableModelDefinitions(enable: boolean) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think its obvious from this name what the function does.
src/main/MainMenu.ts
Outdated
): Electron.MenuItemConstructorOptions => | ||
menu.items.find( | ||
item => (item as Electron.MenuItemConstructorOptions).label === name, | ||
) as Electron.MenuItemConstructorOptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this being multiple lines, I would like curly-brackes {} and a return.
@IvanCoronado @kraenhansen The code I sent should, by all means, be updated to reflect the style you want. It was just something to get going on the export specific part :-). And my first ever JS/TS code - so I imagine it's quite poor. Refactor and adapt to your liking :-) |
|
||
const fs = require('fs-extra'); | ||
|
||
const debug = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set to false
@bmunkholm @kraenhansen Yes, I had supposed that we need adapt this code but I wasn't sure if I had to do it myself or someone was working on this task already. I wanted to be sure before to start with this 👍 |
Perfect. Feel absolutely free to adapt it, merge it in right and whatever. Then others can add the missing exports, as that's "trivial code" people from outside can contribute with. Perhaps even myself :-) |
@bmunkholm I will fix TS errors and I will update @kraenhansen feedback. After that, we should add tests before than refactor your code. But I am not sure if I have the knowledge enough about realm and swift for adding the tests coverage. |
Re. test we should just make a simple one that compares the output of the generated text with that of a file. If you do that I can update the file to compare to. (there are already files in the tests/ directories from OSX Browser. They will have to be fixed up a bit though as what we generate now may differ a bit from the other generated files.). |
@IvanCoronado If you are cleaning anything up, it would be good to do that quickly, as @nhachicha will help out on specific export for Java (and perhaps the rest) |
}); | ||
} | ||
|
||
public makeSchema(schema: Realm.ObjectSchema) {} // tslint:disable-line |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are doing this anyway, why have a lint check for it ;-)
Isn't it easier to just have the ending brace on the next line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably just be an abstract method instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or throw an error saying it must be implemented.
ObjC = 'objC', | ||
Swift = 'swift', | ||
Java = 'java', | ||
CS = 'CS', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'C#'
case Language.JS: | ||
return new JSSchemaExporter(); | ||
default: | ||
return new AbstractSchemaExporter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not useful? Throw instead?
@IvanCoronado Others can fix the exporter, or rather, in this case, the models we are comparing against should be updated (as listed in the readme). Those are examples from the OSX browser which has a few bugs in the exporter and other preferences for how to output the model. @nhachicha can take that, and check up with the Cocoa team if needed. |
this.appendLine('package your.package.name.here;'); | ||
this.appendLine(''); | ||
|
||
const realmImports = new Set<string>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get an error from the TypeScript compiler here:
TS2495: Type 'Set' is not an array type or a string type.
I would probably just use an array of strings.
const realmImports: string[] = [];
realmImports.push('import io.realm.RealmObject;');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange I didn't get this error locally.
I need a Set
otherwise I'll end up with duplicates since I'm adding imports as I iterate through the properties ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As soon as the tests pass, I believe this should get merged in and released.
this.settersContent += `${JavaSchemaExporter.PADDING}public void set${this.capitalizedString( | ||
prop.name, | ||
)}(${this.javaNameForProperty(prop)} ${prop.name}) { | ||
${JavaSchemaExporter.PADDING}${JavaSchemaExporter.PADDING}this.${prop.name} = ${prop.name}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line gets two spaces two much padding in the export - or the return ☝️ two few.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm changing this part to match the expected model in the tests
I'm reassigning this to @nhachicha - who will investigate the failing tests and merge this when they pass. |
before(() => { | ||
fs.removeSync(`${TESTS_PATH}/realms`); | ||
fs.removeSync(`${TESTS_PATH}/temporal`); | ||
sampleRealm = makeRealm(`${TESTS_PATH}/realms/sample/SampleTypes.realm`, [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Realm is not used for anything, so this can be deleted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is used in exp.exportSchema(sampleRealm);
https://github.com/realm/realm-studio/pull/428/files/c6f962d12f9f4595718979ccc6f9be67515ead88#diff-ea0caba4a04c40a26970f338eb0139c1R36
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahh yeah, sure. I was too fast there :-)
]); | ||
}); | ||
|
||
it('JS exporter model with sample types', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is too repetitive. We should have a generic test testModel(language, model)
that will compare a directory of files with the expected output.
We should test the AllTypes
model as that includes everything. The Sample model is just useful for development of a new exporter.
…o ic/export-schemas
I figured that these should have been in the options object - but it doesn't feel practical
I believe mutating the menu items are generally disincuraged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a few changes - anticipating that we soon will be adding more menu items on the different window types.
Added "Save model definitions" in the bar menu.
"Save model definitions" options will be enabled just when you have focused a realm browser window.
Languages supported JS and Swift.
closes (partially) #158