Skip to content

Conversation

@XedinUnknown
Copy link
Member

@XedinUnknown XedinUnknown commented Jul 2, 2020

  • Added PHPUnit.
  • Added DB client service and configuration.
  • xDebug integration for debugging during tests (web request not supported).
  • Psalm.
  • PHPCS.
  • Continuous Integration with GH Actions.

@XedinUnknown XedinUnknown added the enhancement New feature or request label Jul 2, 2020
@XedinUnknown XedinUnknown added this to the v0.1 milestone Jul 2, 2020
@XedinUnknown XedinUnknown requested a review from mecha July 2, 2020 01:12
@XedinUnknown XedinUnknown self-assigned this Jul 2, 2020
This includes a modules list file, an application bootstrap file, and a basic test.
Copy link

@mecha mecha left a comment

Choose a reason for hiding this comment

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

The comments that I wanted to leave are mostly cross-cutting - I couldn't decide what file or line I should leave my comments on. So I'll stick with my usual format of a single message with comments first and suggestions later.


Comments

I'm personally not a fan of bootstrappers, but I understand the appeal of quickly spinning up a new WordPress plugin project, especially for project-level things like Docker, PHPUnit, PHPStorm, etc.

That said, I have to ask the question: what problem does this package actually solve? To me it seems like there are multiple answers to that, and ideally there's only one per package. Which leads me to my next point:

It's not fair to call this package a "bootstrapper", since it not only provides project-level stuff but also provides runtime functionality such as the main plugin file, module loading, container construction, etc. If, hypothetically, I just want to use the ready-made plugin functionality and module runtime logic, I have to contend with the rest of the stuff that is bundled with it like Docker, PHPUnit, Psalm, etc. Not to mention that some of the code here isn't even WordPress-related and can genuinely be useful for other projects.

Finally, the module loading. I don't even know where to begin honestly; it seems so unnecessarily complicated. I'm also surprised to see that you went with a composite container approach, rather than a composite service provider. There are many clear benefits to the latter, most notably performance, easier compiling, works with any SP-compatible container implementation out of the box, and fits in well with the idea of having a root plugin module that "parents" the other modules. I'm even more surprised to see that you are still sticking with separating factories and extensions in their own .php files.


Suggestions

I would split this package up into multiple ones, be them WordPress-related or otherwise.

First off, the modules. This is probably going to be controversial due to how differently you and I see modules. Personally, I don't like to attach "extra" code to modules. What I mean is that a module is just a single class, not a package that bundles sources that specific to it. It's just a class that provides a preset for services, integrations with other modules and execution logic; a thin object that utilizes functionality that is already available on its own without necessitating the module.

For this reason, I don't see the need for the modules.local directory and the wikimedia/composer-merge-plugin dependency. For the most part, plugin modules will most likely exist within the same package as the plugin (speaking from experience). And when not, which is fine and I can see many use cases for, the module is just a class that resides in vendor that the plugin instantiates and uses.

At RebelCode, we keep a modules.php file in the root directory that looks something like this:

return [
	'my_cpt' => new MyCptModule(),
	'my_tax' => new MyTaxonomyModule(),
	'logger' => new LoggerModule(),
];

As you can see, it makes no difference where the module classes come from - they are all autoloaded equally. We also make an effort to not depend on the plugin's location on the file system when creating the modules - if modules need path info, a CoreModule will provide services for those.

Now onto module loading. I understand that this is not a simple one-liner; containers need setting up, the module list needs to be fetched, then providers need getting, and so on.

But solving that problem should not be the concern of this package. In a perfect world, there should be a one-line solution such that f(m) -> c where m is a list of modules and c is your container, or application (honestly, I'm of the opinion that this should be part of the module standard. But I know you disagree with that).

With such a package, all you'd need to do is composer install it, and use its provided logic in your plugin's main file.

// plugin.php

// The CoreModule I mentioned.
// Has aware of the plugin's location, and parents the other modules
// by acting as a composite module
$coreModule = new CoreModule(__FILE__, require 'modules.php');
// Any SP-compatible container will do
$c = new Container($coreModule);
// Run Forrest run!
$coreModule->run($c);

Speaking of which, the plugin stuff. When it comes to doing things modularly, the plugin main file takes a backseat in that it does nothing except load stuff. But there are other useful features that modular plugins can leverage, such as accessing parts of WordPress using services, or having the plugin's services be filterable using WordPress hooks.

I would create a library for this stuff, that depends on the previously mentioned proposed package, that acts as a sort of "unofficial SDK" for WordPress plugins (something I'm actually working on myself). This package can provide simple one-liners that, when put in the plugin.php file, give you a working plugin.

Finally, you can use those in this package which on its own does not offer any runtime stuff, but merely gives you a good starting point with some bundled tools to boot. This way, you have a clean bootstrapper that you can use to spin up a ready-to-go development environment.

@XedinUnknown
Copy link
Member Author

Most probably, your comment is a result of me not communicating the goals of this project clearly. I'll explain some of the decisions here, and hope it will help understand what I'm trying to achieve.

  • It's not fair to call this package a "bootstrapper"

    You're right. I'd rename the package to plugin-boilerplate. Will do that soon.

  • I have to contend with the rest of the stuff that is bundled with it like Docker, PHPUnit, Psalm, etc

    Yes, this is an opinionated plugin starter template. The opinion is as follows: when you create a plugin, you want to be able to test its code, acceptance-test its behaviour, etc. You should need to run static code analysis tools. Most serious pros use PHPStorm. All these things are a pain to set up, and it took me many days to fit all these things together, such that only a few variables need to be changed, and everything runs: test for your code, a completely isolated and tailored environment for the plugin, Continuous Integration, PHPStorm integrations with DB, Composer, PHPUnit, xDebug, etc. For this reason, most people will not even bother doing this, especially for smaller projects. But this stuff ideally should be done anyway. This is the problem that this package aims to solve. Besides, if you don't want to use it, you don't have to "contend" with it: just use the tools you want, and don't use the tools you don't want. I guarantee you: setting up the Docker environment is 1000 times harder than removing it.

  • Finally, the module loading. I don't even know where to begin honestly; it seems so unnecessarily complicated.

    But it is not. Most of this code is too application-level to be extracted. Every project may need to easily modify its initialization procedures to suit its requirements. It's boilerplate code anyway, except now it's centralized in this package.

    I also have a lot of experience with modules, as I have architected 2 large systems now. I deal with this every day, solving architectural problems, reviewing, and even writing modules. From my experience:

    • Many modules will come from external packages. Ideally, this would be true for all modules. However, that is not feasible. Furthermore, developing module packages in parallel is hard, and having modules be shipped in the package is often very convenient. This is especially true if you have concerns that are application-specific, but it is still desirable to separate them from each other; this need is very common. Eventually, when a module grows in size and/or is normalized/generalized, it is desirable to move it to a dedicated package, and this procedure is a huge pain if appropriate preliminary measures are not taken.

    • It is often desirable to black-box-test certain parts of the code, as part of the application. You'd mock system boundaries, like I/O, network, or DB, but everything within your system is for real. These components need to be initialized. This initialization code is already represented as a cascade of service definitions. By fetching components directly from the container, you avoid having to replicate init code in the tests, and test the system segment exactly how it is in the system. This is very useful, and with containers this is a breeze. The only thing is, the system still needs to be bootstrapped and configured for this to be possible. Having a separate bootstrap.php file provides the much needed re-usability and consistency.

    • Having module classes without ctor args is very inconvenient, and often leads to the module being aware of stuff that isn't its concern. A simple module factory in a module.php file takes care of this: it is always invoked with consistent parameters. Meanwhile, the module class itself can require dependencies, which can be derived from the factory params, the environment, etc. The module stays clean. However, this is just a convention, and the modules.php file that returns a list of modules may initialize modules in any way required, including by simply invoking their parameter-less constructor; it can adapt to the way the module needs to be initialized.

    • In the future, there will be some kind of build procedure. This procedure should support building the application with various module configurations from e.g. the command line. For example, a free version that ships certain modules, and a pro version that includes additional modules. At the same time, the loading mechanism needs a consistent source of modules. Having the modules.php file is a stepping stone in this direction, while also providing a way to programmatically retrieve the list of application modules.

  • I'm also surprised to see that you went with a composite container approach, rather than a composite service provider

    I did not "trade" the composite SP approach for the composite container approach. They both exist in this architecture. Module service providers are being retrieved, and merged into one, which is then given to a container. This is mostly the job of the ModularModule. It provides a way to use the plugin code as a module, without the knowledge of its submodules.

    At the same time, the container that provides access to the modules' services is not enough. For example, it may be necessary override certain configuration from the database, such as by using wp_options. Or, it could be desirable to mock certain services for testing. Another case could be the need to provide some sort of fallback values for services. Meanwhile, the application container must remain the single source of truth for all configuration. This is achieved by using a composite container, where the modules' services container is just one of the possible sources of values.

  • Now onto module loading. [...] But solving that problem should not be the concern of this package

    Module loading is the concern of this package, because it is the application's concern, and this is the application package. As I wrote before, module loading code is too small and too application-specific to be a reasonable candidate for re-use across multiple packages.

I think that the choices you are concerned with are quite justified. If a new plugin author doesn't want the large feature set provided by this package, they are free to start a plugin from scratch, and use any module loading method they want (even a 20-line one). This package tackles a very large amount of problems that regularly present when I create new enterprize-grade modular plugins.

That said, if you have other problems associated with creating new modular plugins, or you believe that there's a better way of doing something here while maintaining the goal of the package, or you find a feature that really is extra, I am very open to ideas/suggestions.

@mecha
Copy link

mecha commented Jul 8, 2020

You are right. And I will explain at the end why, but first I must fulfill my duty as reviewer to leave comments


Besides, if you don't want to use it, you don't have to "contend" with it: just use the tools you want, and don't use the tools you don't want.

I can extend that logic quite easily into the following statement: All PHP Composer packages can be combined into just one package. Just use the classes you want and don't use the classes you don't want. Hopefully that demonstrates what I'm trying to say.

except now it's centralized in this package.

That's exactly what I mean. It has nothing to do with WordPress and is, quoting myself: "genuinely useful for other projects".

Many modules will come from external packages. Ideally, this would be true for all modules ... when a module grows in size ..., it is desirable to move it to a dedicated package

I hold a different, but not opposite, opinion. It's simply: who cares where they come from? They're just classes. For that reason, I don't see how the premise of module size/complexity leads to a dedicated package becoming desirable.

So naturally, I can't see why a boilerplate package needs to be the package that solves that problem.

It is often desirable to black-box-test ...

Again, I see what you're saying, but I don't see how the premise implies the conclusion you arrive to, that a bootstrap.php is the ideal solution. If there exists a unit that sets up your application, is tested, standard and easy to use, you can use that unit in every scenario you mentioned in this paragraph. Not only that, it would be superior in every way, as it's a formal unit that can be referenced, autoloaded, properly depended on and even formally mocked.

In the future, there will be some kind of build procedure ...

I have one. Will trade for nudes.

Re. composite container, you brought up these points:

it may be necessary override certain configuration from the database, such as by using wp_options

Well that sounds like application-specific logic. And in a modular application, all such logic is a module. So, make a module accept $wpdb as ctor arg and generate the factories.

it could be desirable to mock certain services for testing

Plenty of ways to do that, but mock objects would probably be best. But if you insist on composite containers, you can just create a composite container inside the test and give it your application container. Not that I'm endorsing that in any way. Use mocks.

Another case could be the need to provide some sort of fallback values for services

Much like the first point, sounds like the job for a module. Maybe even a "core" module.

Meanwhile, the application container must remain the single source of truth for all configuration. This is achieved by using a composite container ...

I agree with the premise, but I don't know what exactly is being "achieved" by the composite container. There's no scenario where adding a new container into the system is better than adding a new module. And if modules is all you have, you don't need the container to be composite. Just my 2 cents.

Module loading is the concern of this package, ... and is too small and too application-specific to be a reasonable candidate for re-use across multiple packages.

I strongly disagree. Every application will follow the same module loading procedure:

  1. Acquire a variable of type ModuleInterface[], somehow (up to the application)
  2. Set up a container with all the factories and extensions
    • Option A: Composite module and a SP-compat container
    • Option B: Composite SP-compat container
    • Option C: Completely custom container
  3. Run the modules in sequence with that container (or a parent)

The only things that change are the steps before 1 and after 3. Yes it's small, but yet again I don't see how that leads you to the conclusion that it's not reasonable to create a reusable module system that provides a loading mechanism that achieves the above.

If a new plugin author doesn't want the large feature set provided by this package, they are free to start a plugin from scratch

Well, this is not the right attitude IMO. While the statement is true and I do agree with it, I don't feel like it has a place in this discussion, unless it's being used defensively to justify being opinionated. Which leads me nicely into the conclusion:


In the beginning I said that you're right and that I'd explain why.

You said it in plain words: this is an opinionated package. And I have to respect that. There's no objective right or wrong - only a package that fulfills your needs as best as you can design it, with the hope that it attracts others with similar needs. So I can't argue much there. I'd take back everything I said in this comment, but I know you wouldn't appreciate that.

At the same time ... I don't think my reviews are going to be of much help to you here. Our differing views on modules and package organization is going to conflict way too much, especially given the nature of the project. It's quite a match made in hell if you think about it 🤣

I at least hope that this comment is deserving of my role as reviewer, and that you got something out of it; even if it's just something that makes you pause and think, 6 months from now.

@XedinUnknown
Copy link
Member Author

Besides, if you don't want to use it, you don't have to "contend" with it: just use the tools you want, and don't use the tools you don't want.

I can extend that logic quite easily into the following statement: All PHP Composer packages can be combined into just one package. Just use the classes you want and don't use the classes you don't want. Hopefully that demonstrates what I'm trying to say.

No, that statement would not be a correct extension, because all PHP Composer packages are not something that is frequently used together.

except now it's centralized in this package.

That's exactly what I mean. It has nothing to do with WordPress and is, quoting myself: "genuinely useful for other projects".

Didn't understand how your reply agrees with or contradicts my point.

Many modules will come from external packages. Ideally, this would be true for all modules ... when a module grows in size ..., it is desirable to move it to a dedicated package

I hold a different, but not opposite, opinion. It's simply: who cares where they come from? They're just classes. For that reason, I don't see how the premise of module size/complexity leads to a dedicated package becoming desirable.

For the consumers it doesn't matter where modules come from. But for the author who will need to extract modules into separate packages - it does. You really haven't ever have to extract built-in code into a different package..?

It is often desirable to black-box-test ...

Again, I see what you're saying, but I don't see how the premise implies the conclusion you arrive to, that a bootstrap.php is the ideal solution. If there exists a unit that sets up your application, is tested, standard and easy to use, you can use that unit in every scenario you mentioned in this paragraph. Not only that, it would be superior in every way, as it's a formal unit that can be referenced, autoloaded, properly depended on and even formally mocked.

There can be no such unit because, like I said before, all this stuff is quite application-level. There's nothing about the bootstrap process that can be re-usable, with the exception of perhaps ModularModule, but that tiny class does not justify having its own package. If you believe that there is a better re-usable bootstrap process, we can discuss this separately. Perhaps, a future contribution?

In the future, there will be some kind of build procedure ...

I have one. Will trade for nudes.

Deal! 🎉

it may be necessary override certain configuration from the database, such as by using wp_options

Well that sounds like application-specific logic. And in a modular application, all such logic is a module. So, make a module accept $wpdb as ctor arg and generate the factories.

It is application-specific logic. Which is why it belongs to the application. I have not yet found a way to override the application container via modules (although I didn't look much). In any case, it's likely to still take advantage of some form of composite container.

Didn't understand the part about $wpdb and factories. What factories?

it could be desirable to mock certain services for testing

Plenty of ways to do that, but mock objects would probably be best. But if you insist on composite containers, you can just create a composite container inside the test and give it your application container. Not that I'm endorsing that in any way. Use mocks.

Of course, I would use mock objects. But how would those mocks get into the application container?

Another case could be the need to provide some sort of fallback values for services

Much like the first point, sounds like the job for a module. Maybe even a "core" module.

Perhaps. This package ships such a module.

Meanwhile, the application container must remain the single source of truth for all configuration. This is achieved by using a composite container ...

I agree with the premise, but I don't know what exactly is being "achieved" by the composite container. There's no scenario where adding a new container into the system is better than adding a new module. And if modules is all you have, you don't need the container to be composite. Just my 2 cents.

I mentioned such a scenario: a case where any service is automatically overridable with data from somewhere else. So, look into the e.g. WP Options container, and if not there - look into the modules' services container.

Module loading is the concern of this package, ... and is too small and too application-specific to be a reasonable candidate for re-use across multiple packages.

I strongly disagree. Every application will follow the same module loading procedure:

  1. Acquire a variable of type ModuleInterface[], somehow (up to the application)
  2. Set up a container with all the factories and extensions
  • Option A: Composite module and a SP-compat container
  • Option B: Composite SP-compat container
  • Option C: Completely custom container
  1. Run the modules in sequence with that container (or a parent)

The only things that change are the steps before 1 and after 3. Yes it's small, but yet again I don't see how that leads you to the conclusion that it's not reasonable to create a reusable module system that provides a loading mechanism that achieves the above.

That 2nd point is also quite a variable thing. Of course, it's possible to go around this with an ApplicationContainerFactory that gets injected. In the future, I would be willing to consider having such a package, if it provides enough re-usable value.

If a new plugin author doesn't want the large feature set provided by this package, they are free to start a plugin from scratch

Well, this is not the right attitude IMO. While the statement is true and I do agree with it, I don't feel like it has a place in this discussion, unless it's being used defensively to justify being opinionated.

Well, yes, because it's the truth. This package is the one that brings together many technologies, and it is the whole point of this package. If you wanna start fresh, and don't need all of this, then why not start from 0? After all, just a WP plugin is simply 1 file with a comment...

@XedinUnknown
Copy link
Member Author

I still don't quite understand what are the things that are deal-breaking for you. Without the combination of these different technologies, this package is pretty useless.

I disagree that this is a match made in hell. There's also no wrong opinion here. I thought about having a re-usable module loader before starting this package. I started building it, and concluded that it is mostly useless, and does not deserve its own package. If you think you can make one that is useful, I encourage you to try it, and then if it turns out well, I will gladly consider using it here. Is there something else that you really are against having in this package? Maybe, we can do a video call, where I walk you through the code? I think that some of my decision-making will be more clear this way.

In any case, thank you for your contribution, and your time.

@mecha
Copy link

mecha commented Jul 9, 2020

No, that statement would not be a correct extension, because all PHP Composer packages are not something that is frequently used together.

The logic that I wanted to combat here was not frequency of use as a whole, but the availability of subsystems on their own.

Didn't understand how your reply agrees with or contradicts my point.

You're "centralizing" in a boilerplate package. Need I say more?

You really haven't ever have to extract built-in code into a different package..?

I have. But not for modules. Like I said before, a module is a preset of existing technologies. I never build modules that need to be shipped with their own dedicated sources. Modules are configuration, not libraries. So I've never had to, and don't think anyone should, need to extract a module into its own package.


I'm actually going to stop replying there, because frankly replying to your last message is more meaningful IMO.

I still don't quite understand what are the things that are deal-breaking for you ...

I'd just like to see a boilerplate package that merely brings together existing technologies, rather than provide its own. Like I said, there's code in here that is genuinely useful as a dependency for other projects.

Moreover, I'd like to see something that promotes good module usage. What I see here goes against what I would consider to be "idiomatic" for the module system that I initially envisioned. That doesn't mean it's bad - it just means I'm biased by my different ideals.

Maybe if I shorten my suggestion down it might make more sense:

  • WordPress Plugin SDK
  • Standard module loading
  • Boilerplate that uses the above two and provide Docker, PHPUnit, Psalm, etc..

@XedinUnknown
Copy link
Member Author

XedinUnknown commented Jul 9, 2020

The logic that I wanted to combat here was not frequency of use as a whole, but the availability of subsystems on their own.

All of the systems are already available on their own, with the exception of a 20-line module loading algorithm, which is dead simple, and out of which maybe 10 lines can really be re-used. This package configures these subsystems to work together.

You're "centralizing" in a boilerplate package. Need I say more?

Oh, I see 😆. Well, maybe the word "centralizing" is the wrong word to use here, but I think you get that I was trying to say "combines" or "aggregates".

I have. But not for modules. Like I said before, a module is a preset of existing technologies. I never build modules that need to be shipped with their own dedicated sources. Modules are configuration, not libraries. So I've never had to, and don't think anyone should, need to extract a module into its own package.

Well, I have. Many times. SDK, HTTP client, WP events wrapper, session control, admin notices, and many many more. A lot of those are libraries that additionally ship a module declaration, for ease of use. Some are more about doing something specific in the application itself. This is a very common case, and I wanted to build this into this pacakge

Even if it is not common, it is useful to know at a glance which dependencies belong to which modules. Modules definitely can have their own sources, like event handlers for example.


I'd just like to see a boilerplate package that merely brings together existing technologies, rather than provide its own.

For the most part, this boilerplate simply brings existing technologies together.

there's code in here that is genuinely useful as a dependency for other projects.

  • WordPress Plugin SDK: Sure thing! This is the beginning of that SDK. The Plugin class is in here because there isn't yet a package for implementations, as there's barely anything to implement yet, and what there is is rather trivial. I look forward to adding more interfaces, and writing an SDK implementation!
  • Standard Module Loading: Like I wrote, I don't see any code that can be meaningfully re-used for this purpose. But, like I also wrote, if you have ideas - please, write a package, and I will be happy to contribute, and to consider it for use here if it turns out well.
  • Boilerplate that uses the above two - So, basically, it's what we have now, minus the above points extracted to their own packages? If so, like I mention above, at least one of those points is already planned, and one of them is not impossible either. I really hope that this is sufficient for you to stay on board with this boilerplate, to use it, promote it, contribute to it, and make everything naissse.

@XedinUnknown
Copy link
Member Author

I just realized that I haven't yet committed the changes that use the "WP SDK". Coming up.

@mecha
Copy link

mecha commented Jul 9, 2020

a 20-line module loading algorithm, which is dead simple, and out of which maybe 10 lines can really be re-used

Even if its only 5 lines, the only runtime stuff that is acceptable IMO is a preset entry point that users can edit or replace, like an index.html for web apps. In this case, it would be the plugin main PHP file, in its simplest form.

but I think you get that I was trying to say "combines" or "aggregates".

I didn't, but even so I was still referring to code that is exclusively hosted in this repo.

Modules definitely can have their own sources, like event handlers for example.

They can, which is why I'm very vocal against it. But that's a discussion for another thread.

So, basically, it's what we have now, minus the above points extracted to their own packages?

Pretty much, yeah!

like I mention above, at least one of those points is already planned, and one of them is not impossible either.

My review for this boilerplate is quite simply to de-bloat it. And you've expressed that you are going to do that. Fantastic.

I really hope that this is sufficient for you to stay on board with this boilerplate, to use it, promote it, contribute to it, and make everything naissse.

Use it? Probably not. My setups and even general architectures are too different. I'd be tearing out everything except for the developer tools.
Contribute? Don't know. Probably not for the same reason.
Promote it? Most certainly.

@XedinUnknown
Copy link
Member Author

a 20-line module loading algorithm, which is dead simple, and out of which maybe 10 lines can really be re-used

Even if its only 5 lines, the only runtime stuff that is acceptable IMO is a preset entry point that users can edit or replace, like an index.html for web apps. In this case, it would be the plugin main PHP file, in its simplest form.

Not sure I understand. We were talking about extracting the loading algorithm. Now you're talking about an entry point.

Also, there is an entry point that users can edit or replace: it's the bootstrap function in bootstrap.php. It's not in the plugin's main file, because the modularity bootstrap is valuable on its own, besides the plugin or webpage. Right now it is used in 2 places: in the plugin, and in tests.

but I think you get that I was trying to say "combines" or "aggregates".

I didn't, but even so I was still referring to code that is exclusively hosted in this repo.

And again, I don't understand what that should tell me.

Modules definitely can have their own sources, like event handlers for example.

They can, which is why I'm very vocal against it. But that's a discussion for another thread.

My point is that there's nothing wrong with that. But OK, a different discussion.

I really hope that this is sufficient for you to stay on board with this boilerplate, to use it, promote it, contribute to it, and make everything naissse.

Use it? Probably not. My setups and even general architectures are too different. I'd be tearing out everything except for the developer tools.
Contribute? Don't know. Probably not for the same reason.
Promote it? Most certainly.

I'm really confused. I want to make something useful, including for you. And you're saying that your architecture is too different, which is why you wouldn't use it or contribute. But you are going to promote it? Why? And how would you, if you are not using it? 🤔

@XedinUnknown
Copy link
Member Author

XedinUnknown commented Jul 10, 2020

Now available on Packagist as wp-oop/plugin-boilerplate. It would be great if someone tested it, from the ground up. But if you're not gonna use it, I'll just post on Twitter, I guess.

@mecha
Copy link

mecha commented Jul 10, 2020

But you are going to promote it? Why? And how would you, if you are not using it?

If I deem this project to be worth people's time, I can very easily recommend it. Having developed most of the tech here, I have a pretty good idea of how it works. I don't need to be personally using it myself to know that.

Like I said, certain things here don't really align with my ideals. But my ideals aren't absolute law, and they shouldn't reflect anything about the project or how it works. The fact is that this project does work. It works for you and it can work for others. I just have my own way of doing things.

@XedinUnknown XedinUnknown merged commit 81fcaf0 into develop Jul 10, 2020
@XedinUnknown XedinUnknown deleted the initial branch July 10, 2020 14:44
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

Successfully merging this pull request may close these issues.

3 participants