-
Notifications
You must be signed in to change notification settings - Fork 79
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
Architecture, Config, CLI, API — Recommendations & Discussion #91
Comments
I disagree. I think the code base is in better shape now and that we should try to move our focus onto features and bug fixes. Code improvements can be introduced combined into those features and fixes.
This is already supported via https://github.com/davidtheclark/cosmiconfig.
I do not understand what you mean by this. The cli currently ensures type correctness.
I disagree. I think we should flesh out and finish support for the basic languages we already have. There are plenty of critical bugs here and there. Once we have a working solution we can start looking at branching it out into other languages.
In what cases do we need instances as our graph values? The graph is currently
I dislike |
I also think the cli is better to stay "handily made". That aside I have planned to do a function to generate the help message. Manually adding spaces for text alignments is messy in my opinion. |
I see, apologies for not seeing this earlier. Great news!
Perhaps I'll add some time into test coverage #80 instead :)
It's fine for just file paths, but will there ever be a case where we may need to add more information than just a file path? I think we would if expanding to other file extensions. A use case could be interacting with destiny in a callback function. I'd want a callback with all the details about a node, with access to navigate the graph via the abstraction. FileNode {
path: "/home/user/Documents/project/src/index.ts",
isProcessed: true,
testFiles: [ ... ],
// absolute locations. These would be other "FileNode" instances.
nodes: [
"/home/user/Documents/project/src/index/dependency-1.ts",
"/home/user/Documents/project/src/index/dependency-2.ts",
],
// relative import paths. Only one needed because they're the same.
edges: [ ... ]
} I'm sure there's more applicable uses.
I don't think it's perfect by design and can be misused in terms of maintainability: neat and declarative. My biggest reason for using I'm not fussed, but definitely something I'll be using in my personal projects from now on.
Why would you say that it is difficult? I don't believe it would be hard to test against. Wouldn't it be just like any other CLI?
I like the option API used and the |
I've already tried something about a week ago, but never found time to continue working on it. const parseArgs = (args: string[]) => {
let isValue = false;
args.reduce<Partial<Config>>((acc, arg, i) => {
if (isValue) {
isValue = false;
return acc;
}
switch (arg) {
case "-h":
case "--help":
acc.help = true;
break;
case "-V":
case "--version":
acc.version = true;
break;
case "-w":
case "--write":
acc.write = true;
break;
case "--flag-with-value":
acc.flagWithValue = args[i + 1];
isValue = true;
break;
default: {
if (fs.existsSync(arg) || glob.hasMagic(arg)) {
acc.include = [...(acc.include ?? []), arg];
}
}
}
return acc;
}, {});
}; So you can do:
And For a list something like this is possible:
Then in the Maybe there's a better way to do this, but that's the way I did it.
In my opinion it would be great to have something like this. We could for example store the file's extension, the file's parent, etc... in it so we don't have to manually search (again) for these everywhere in the engine. Because currently there's a lot of repetition about this. |
It's more than enough to use what we already have. If we in the future see a need to expand this we'll do that but we should not try to fix something that is a maybe. We need to keep it as simple as possible for as long as possible.
I think
What do you mean by it being typesafe? It's not more typesafe than the current cli implementation.
It's hard because it abstracts and binds things together. The current cli can be unit tested easily because all moving parts are isolated and in our control. A Try to unit test the cli you wrote and try for yourself. |
This should be implemented with a while loop which would give us the best flexibility. That would allow us to parse multiple values for a specific option etc. |
@AnatoleLucet Something like this: const parseArgs = (args: string[]) => {
const parsedArgs: Partial<Config> = {};
while (args.length > 0) {
const arg = args.shift();
if (arg == null) break;
switch (arg) {
case "-h":
case "--help":
parsedArgs.help = true;
break;
case "-V":
case "--version":
parsedArgs.version = true;
break;
case "-w":
case "--write":
parsedArgs.write = true;
break;
case "-G":
case "--gimme": {
const nextOptionIdx = args.findIndex(x => x.startsWith("-"));
parsedArgs.gimme = args.splice(0, nextOptionIdx);
break;
}
default: {
if (fs.existsSync(arg) || glob.hasMagic(arg)) {
parsedArgs.include = [...(parsedArgs.include ?? []), arg];
}
}
}
}
return parsedArgs;
}; |
This allows us to more easily juggle args. In the near future we need to parse specific args for specific options which this implementation facilitates easily. An example of this would be: ``` case "--gimme": { const nextOptionIdx = args.findIndex(x => x.startsWith("-")); parsedArgs.gimme = args.splice(0, nextOptionIdx); break; } ``` See #91 for context.
@sQVe Yep that's better 👍 |
I think this discussion has served its purpose. Closing off. |
I've been thinking about and working on this project for weeks and am growing a passion towards it.
Thank you for all being so accepting, patient and prompt in your responses.
I'd like to voice some ideas and possible solutions. There's a lot here, so take your time to read and respond if you choose to do so.
Quality of life
Refactor
A great idea, but some of the code is messy, hard to interpret and difficult to test. I've posted a few pulls to refactor code. I will keep doing this, taking anything from this discussion into account.
Config File
I personally would prefer a configuration that supports
destiny.config.(ts|js)
, with the default export as what will be read.If typescript, the user should have
ts-node
installed . This way we can assign an interface to the object. I'm pretty sure webpack and/or rollup have this feature built in.Architecture
I think we can start researching how we may implement an architecture that can support other file extensions via middleware. Prettier has something similar for each language they support, which include parsers and formatting rules.
The way this program could be laid out:
a. Find a file
b. Add import path to graph
a. ...details
There are some details that I've overlooked, but it's general.
Graphs
Currently we're managing our own graphs. It is simple with object-index pattern:
{ [index: string]: string }
.It works with strings as the nodes, but what if we ever needed to use an instance on each end? We'd have to rewrite it.
I believe we should go down the OOP route for our graph generation and management. It would make extensibility and management easier. I love functional programming, but well managed mutability is where the power is in graphs!
We could use a library for manipulating graphs called cytoscape.js, which comes with some fantastic abstractions.
On first glance it looks like it's built to support the DOM. However, it can run in headless mode, meaning all the rendering capabilities are disabled and it can be used to strictly manipulate data. Score!
CLI API
I wrote a cli in
yargs
and came up with this:Generated by this:
The text was updated successfully, but these errors were encountered: