Skip to content
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

Merged
merged 40 commits into from
Nov 23, 2017
Merged

Export schemas #428

merged 40 commits into from
Nov 23, 2017

Conversation

IvanCoronado
Copy link
Contributor

@IvanCoronado IvanCoronado commented Nov 16, 2017

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

* master:
  Context menu revisited (#426)
  Browser row caching (#425)
  Prepare version v1.7.3
  Removing the override of default ports (#416)
  feat (Cell): Show dates in ISO format (#403)
  feat (realms): Remove timeout while opening realm (#402)

# Conflicts:
#	src/ui/realm-browser/RealmBrowserContainer.tsx
@IvanCoronado
Copy link
Contributor Author

@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?

Copy link
Member

@kraenhansen kraenhansen left a 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);
Copy link
Member

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);
});
};
Copy link
Member

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).

Copy link
Contributor

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?

Copy link
Member

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
Copy link
Member

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"
]
}
}
Copy link
Member

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)
Copy link
Member

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"
}
}
Copy link
Member

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.

if (ModelDefinitions && ModelDefinitions.submenu) {
(ModelDefinitions.submenu as Electron.Menu).items.map(
item =>
((item as Electron.MenuItemConstructorOptions).enabled = enable),
Copy link
Member

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.

Copy link
Contributor Author

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.

window.on('close', () => {
this.mainMenu.enableModelDefinitions(false);
});

Copy link
Member

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.

}

public enableModelDefinitions(enable: boolean) {
Copy link
Member

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.

): Electron.MenuItemConstructorOptions =>
menu.items.find(
item => (item as Electron.MenuItemConstructorOptions).label === name,
) as Electron.MenuItemConstructorOptions;
Copy link
Member

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.

@bmunkholm
Copy link
Contributor

bmunkholm commented Nov 16, 2017

@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 :-)
Surely needs some cleanup various places.


const fs = require('fs-extra');

const debug = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set to false

@IvanCoronado
Copy link
Contributor Author

@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 👍

@bmunkholm
Copy link
Contributor

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 :-)

@IvanCoronado
Copy link
Contributor Author

@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.

@bmunkholm
Copy link
Contributor

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.).

@kraenhansen kraenhansen changed the title Ic/export schemas Export schemas Nov 17, 2017
@bmunkholm
Copy link
Contributor

@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
Copy link
Contributor

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?

Copy link
Member

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.

Copy link
Member

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',
Copy link
Contributor

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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not useful? Throw instead?

@bmunkholm
Copy link
Contributor

@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>();
Copy link
Member

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;');

Copy link
Contributor

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 ...

kraenhansen
kraenhansen previously approved these changes Nov 21, 2017
Copy link
Member

@kraenhansen kraenhansen left a 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};
Copy link
Member

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.

Copy link
Contributor

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

@kraenhansen
Copy link
Member

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`, [
Copy link
Contributor

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

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', () => {
Copy link
Contributor

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.

Copy link
Member

@kraenhansen kraenhansen left a 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.

@kraenhansen kraenhansen merged commit f52def5 into master Nov 23, 2017
@nirinchev nirinchev deleted the ic/export-schemas branch September 25, 2018 08:44
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants