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

[request] Trimmed version #2

Open
stewe93 opened this issue Sep 28, 2022 · 8 comments
Open

[request] Trimmed version #2

stewe93 opened this issue Sep 28, 2022 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@stewe93
Copy link

stewe93 commented Sep 28, 2022

Hey!

Would you mind to add the trimmed version to this repository as well?

Bests

@Jman012
Copy link
Owner

Jman012 commented Sep 28, 2022

The trimmed version is an artifact of the full version of the spec. I don't fully like that artifacts would be included next to the source in source control.

All of the artifacts are available here: https://jman012.github.io/FloatplaneAPIDocs/ and the trimmed spec specifically at https://jman012.github.io/FloatplaneAPIDocs/floatplane-openapi-specification-trimmed.json. Or if you prefer Git: https://github.com/Jman012/jman012.github.io/blob/main/FloatplaneAPIDocs/floatplane-openapi-specification-trimmed.json (which I think is public).

Do any of the above work for your process?

@stewe93
Copy link
Author

stewe93 commented Sep 29, 2022

My problem is that I want to have the API specs as a git submodule in my Android project. I checked that I couldn't have a single file as a git submodule, and the docs repo You referenced contains many irrelevant other files that aren't needed to my workflow.
If this change is firmly against Your will, I don't mind if I have to manage it manually!

Thanks for your fast reply!

@Jman012
Copy link
Owner

Jman012 commented Sep 29, 2022

In my Wasserflug project, https://github.com/Jman012/Wasserflug-tvOS/, I opted to just copy it in manually from https://jman012.github.io/FloatplaneAPIDocs/.

Being a build artifact, it really should be a versioned document on something akin to npm, but it being just a json file instead of code, and frequently coming with breaking changes as I settle on things, I'm not sure how feasible that would be.

My biggest fear is making changes to the source document, and committing that without remembering to re-generate the trimmed document. That would be embarrassing.

Would it be possible to use git submodules for this repo and then always re-trim the file upon build? All you need to do to trim the document is run src/trim.js or run npm run trim. You don't need any dependencies aside from node.

@stewe93
Copy link
Author

stewe93 commented Sep 30, 2022

My biggest fear is making changes to the source document, and committing that without remembering to re-generate the trimmed document. That would be embarrassing.

I'm not familiar with GitHub actions but maybe you can automate this part with it.

Would it be possible to use git submodules for this repo and then always re-trim the file upon build?

Currently, I use this repo as a submodule and copy-pasted the trimmed version into it.
As an Android dev, I'm not that familiar with node, and to be honest, I don't want to mix in another tech stack just for the trimming.

I completely understand Your point so I will close this issue. Maybe in the future, I will adapt Your JS script to Kotlin and open a PR with it. Until then the copy-paste solution would be fine for me!

Thanks for your time!

@stewe93 stewe93 closed this as completed Sep 30, 2022
@Jman012
Copy link
Owner

Jman012 commented Sep 30, 2022

The trim.js script could easily be adapted to any language. Python and Ruby tend to be installed on most OSes by default, for instance.

I'll re-open this so I don't lose track of this. I'll keep thinking on it. I might end up making the change. I'll be busy soon so it might be a bit.

@Jman012 Jman012 reopened this Sep 30, 2022
@Jman012 Jman012 self-assigned this Sep 30, 2022
@Jman012 Jman012 added the enhancement New feature or request label Sep 30, 2022
@stewe93
Copy link
Author

stewe93 commented Oct 2, 2022

I made some progress here!

My goal with all of this is to make the project as self-contained as possible.
So I found a gradle plugin to run js scripts (https://github.com/node-gradle/gradle-node-plugin), and added the following line to trim.js:

var specLocation = process.argv[2] !== null ? process.argv[2] : "../floatplane-openapi-specification.json"

to handle the path correctly without modifying your original path. Note here: I have zero experience with JS

So my custom gradle task calls your script with the correct path:

tasks.register("generateTrimmedSpecs", NodeTask){
    group = "generator"

    script = file("$rootDir/contract/src/trim.js")
    args = ["$rootDir/contract/floatplane-openapi-specification.json"]
}

But I'm stuck here:

........
Removed: /api/v3/experiments/vpn/profile/download get
Removed: /api/v3/experiments/vpn/profile/ephemeral get
Removed: /api/v3/experiments/vpn/server/list get
C:\Users\stewe\StudioProjects\FightJet\contract\src\trim.js:32
			if (!Object.keys(spec.paths).flatMap(path => Object.keys(spec.paths[path]).map(operation => spec.paths[path] operation])).some(op => op.tags.some(t => t == spec.tags[tag].name))) {
			                             ^

TypeError: Object.keys(...).flatMap is not a function
    at fs.readFile (C:\Users\stewe\StudioProjects\FightJet\contract\src\trim.js:32:33)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateTrimmedSpecs'.
> Process 'command 'node'' finished with non-zero exit value 1

Could you help me out with the above issue?

@Jman012
Copy link
Owner

Jman012 commented Oct 3, 2022

That's odd. flatMap isn't that new of a function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

My guess is that the node that plugin uses is older/out of date and doesn't include flatMap as a method on arrays. If you could see which version of Node it's using, that could be helpful.

Feel free to re-create the trim.js script in Java/Kotlin, if you wish. They can exist side-by-side.

@stewe93
Copy link
Author

stewe93 commented Oct 3, 2022

My fault :"D Actually the plugin primarily uses the locally installed Node instance, I didn't even remember I installed it, but it's v8.12 :D But the plugin can be configured to download any version, so the complete solution:
Gradle config:

plugins {
   ..........
   id "com.github.node-gradle.node" version "3.4.0"
}

..........

node {
    download = true
    version = "16.17.1"
    distBaseUrl = "https://nodejs.org/dist"
}

tasks.register("generateTrimmedSpecs", NodeTask) {
    group = "generator"

    script = file("$rootDir/contract/src/trim.js")
    args = [
            "$rootDir/contract/floatplane-openapi-specification.json",
            "$rootDir/contract/floatplane-openapi-specification-trimmed.json"
    ]
}

Completed trim.js:

const fs = require("fs");

// Nothing to trim for either Frontend nor Chat AsyncAPI files.

var specLocation = process.argv[2] !== null ? process.argv[2] : "../floatplane-openapi-specification.json"
var outputLocation = process.argv[3] !== null ? process.argv[3] : "../floatplane-openapi-specification-trimmed.json"

fs.readFile(specLocation, "utf8", (err, data) => {
	if (err) {
		console.log("Could not read ../floatplane-openapi-specification.json");
	} else {
		const spec = JSON.parse(data);

		for (var path in spec.paths) {
			for (var method in spec.paths[path]) {
				if (spec.paths[path][method].description.indexOf("TODO") == 0) {
					console.log("Removed: " + path + " " + method);
					delete spec.paths[path][method];
				}
			}
		}

		for (var path in spec.paths) {
			if (Object.keys(spec.paths[path]).length == 0) {
				delete spec.paths[path];
			}
		}

		var tagsToRemove = [];
		for (var tag in spec.tags) {
			if (!Object.keys(spec.paths).flatMap(path => Object.keys(spec.paths[path]).map(operation => spec.paths[path][operation])).some(op => op.tags.some(t => t == spec.tags[tag].name))) {
				console.log("Removing tag " + spec.tags[tag].name);
				tagsToRemove.push(spec.tags[tag].name);
			}
		}
		for (var tagToRemove of tagsToRemove) {
			spec.tags = spec.tags.filter(tag => tag.name != tagToRemove);
		}

		fs.writeFile(outputLocation, JSON.stringify(spec, null, 4), "utf8", (err) => {
			if (err) {
				console.log("Cound not write to ../floatplane-openapi-specification-trimmed.json");
			} else {
				console.log("Done");
			}
		});
	}
});

And for a newer Android project turn off the dependency resolution strategy in setting.gradle:

dependencyResolutionManagement {
    //repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

This way every step is done by gradle and I can build tasks around it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants