Git Product home page Git Product logo

solidarity's Introduction

Solidarity is an environment checker for project dependencies across multiple machines.


Build Status Build Status Codecov npm version

When the same exact code works on one machine but not another, Solidarity is the answer

Docs Website

https://infinitered.github.io/solidarity/


We now return you to your regularly scheduled ReadMe


Install

Install the command globally OR use via node_modules. It's suggested you install your snapshot plugins in the same place.

Note: Node.js version must be >= 7.6.0.

# example of installing global with npm and react-native snapshot
$ npm i -g solidarity solidarity-react-native

# example of installing local with yarn and elixir snapshot (dev dependencies)
$ yarn add solidarity solidarity-elixir --dev

How do I use it?

Using solidarity is easy! Run the following command to check the current project environment.

$ solidarity

This command looks for the .solidarity file in the working directory, and then runs a check of the containing rules against your environment. The command exit code is tied to the success of the solidarity check for testing frameworks.

Write your Solidarity file by hand, or use a snapshot.

How do I update it to my machine specs?

Environment updates can be stored to solidarity quickly.

$ solidarity snapshot

The snapshot parameter will update the rules in the .solidarity file to the current system specs. By default a snapshot will be strict with the versions of everything detected. But, semantic versioning is supported.

How do I create my first snapshot?

If no .solidarity file is present, then solidarity snapshot prompts you to identify the technology your project depends on.

$ solidarity snapshot
No `.solidarity` file found for this project.  Would you like to create one? (Y/n)

Custom rule-sets can be created by modifying the .solidarity file by hand, or by creating a solidarity plugin for a given technology. See documentation for how you can create your own.

How do I update my snapshots?

Given there is already a .solidarity file present, then you can run solidarity snapshot [rule]

$ solidarity snapshot cli node

Solidarity will follow up with aditional questions to help drill down your new snapshot rule.

Cross Platform

Solidarity works with Mac/Linux/Windows environments. CI tests all rules with each platform on every update.

Using Solidarity for GitHub Reports

Solidarity Reports You've already identified everything that's important to your project. So when anyone files bugs on your repo, they can just report using Solidarity!

Just run solidarity report

The resulting output is copy/paste markdown. If you're confused, here's the full blog post.

Project Support

Open Source

Solidarity, as open source, is free to use and always will be ❤️. It's MIT Licensed and we'll always do our best to help and quickly answer issues. If you'd like to get a hold of us, join our community slack and look for the #solidarity room.

Premium

Infinite Red offers premium Solidarity support and general mobile app design/development services. Email us at [email protected] to get in touch with us for more details.

Additional Info

You can help!

License

The MIT License (MIT). Please see License File for more information.

NPM Details

NPM

solidarity's People

Contributors

201flaviosilva avatar adrienthiery avatar bnaya avatar campionfellin avatar charpeni avatar danielmschmidt avatar ddncn avatar deiga avatar dependabot[bot] avatar gantman avatar grigori-gru avatar jamonholmgren avatar jokosu10 avatar kevinvangelder avatar loiclouvet avatar mattathompson avatar mishra-ankit avatar mknsri avatar morgandonze avatar patrickkempff avatar piecioshka avatar rmnegatives avatar ryanlntn avatar siakaramalegos avatar skellock avatar tabrindle avatar taylanken avatar thedeany avatar travisbuddy avatar willrax avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

solidarity's Issues

Add Standard JS linting

The code in here is Standard JS compliant, but we have no standard checker for the CI. Someone should simply add Standard to the lib test command so it is enforced by CI on all PRs.

// Enforcing JS tests
https://github.com/standard/standard

// Enforcing TS files

// Comments ok in TS JSON files
// I'm the `tslint.json 
{
  "extends": "tslint-config-standard"
  // Option to modify standard if we want
  // "rules": {
  //   "trailing-comma": [true, {"multiline": "always", "singleline": "never"}]
  // }
}

Support for config files other than JSON?

Solidarity isn't tech or system specific... should the config files be?

How about .solidarity.yaml and .solidarity.json and .solidarity.toml?

Basically, the file extension will tell solidarity HOW to read and write the file. No need to force the users into JSON, and having those extensions will allow editors to easily colorize/check manual edits for errors.

Feedback welcome!
cc: @skellock @jfairbank

Make solidarity file keep requirements under that key

As @skellock pointed out, the requirements being the ONLY object means zero chance for upgrades later. So for now, move everything under the key "requirements" so we can later add other toplevel keys, like "config", or "snapshot" etc.

Making this structural change now means we have the opportunity for unknown-unknowns later.

  • Update code
  • Update docs
  • Update test
  • Update existing plugins
  • Update blog article

Snapshot version of only 1 thing

solidarity snapshot yarn where yarn is already active in the rules.

This should only update yarn dep to system, even if other things were failing.

Properly work with Non-semver apps

Apps like Xcode will output invalid semver (e.g. 9.0, or xcrun outputs 35)

These should be able to be integrated and get rules like ^9.0 if someone so chooses.

Add Silent flag

passing -s or --silent should enforce that no output happens, just a return code.

cannot find watchman on zsh

I'm using zsh and can confirm that I have watchman installed. But solidarity reports that watchman is not installed. applesimutils and ANDROID_HOME also reported missing

"Watchman": [
  {
    "rule": "cli",
    "binary": "watchman",
    "error": "Please install watchman on this machine. Refer to the official Watchman installation instructions for additional help.",
    "platform": [
      "darwin",
      "linux"
    ]
  }
],
"Detox": [
  {
    "rule": "cli",
    "binary": "detox"
  },
  {
    "rule": "cli",
    "binary": "applesimutils",
    "error": "Try `brew install --HEAD applesimutils`",
    "platform": "darwin"
  }
],
"Android": [
  {
    "rule": "cli",
    "binary": "emulator"
  },
  {
    "rule": "cli",
    "binary": "android"
  },
  {
    "rule": "env",
    "variable": "ANDROID_HOME",
    "error": "The ANDROID_HOME environment variable must be set to your local SDK.  Refer to getting started docs for help."
  }
],

The following are from the cli:

~/D/D ❯❯❯ which applesimutils
/usr/local/bin/applesimutils
~/D/D ❯❯❯ which watchman
/usr/local/bin/watchman
~/D/D❯❯❯ export
ANDROID_HOME=/Users/.../Library/Android/sdk

Update Plugin Architecture

Plugins currently work, but they require that you pass in the current directory path (See React Native Plugin).

Use callsite to to gather that information automatically
LINK

Simpler Output

I'd love to see less verbose output by default.

For Success

So if everything passes, instead of this:

image

Show this:

image

I think it's important to show a success message instead of going full-on "Rule of Silence".

For Failures

Instead of this:

image

Show this list of only the ones failling:

image

And show the details behind --details or something.

😻

Catch suffixes

currently version crazed, not detecting things like -beta or -rc1 etc. on versions.

Example fail:
image

image

^ fix this

Contribution Documentation.

Having a hard time just setting up this repository locally w/ a passing test suite. It would be nice to have some sort of guidelines i.e: Node versioning and any other requirements.

Bring code coverage over 75%

Wouldn't be hard at all to grab the low hanging fruit and make the code coverage less abysmal.

yarn test tells you where we're missing coverage.

Add coverage report

Tests exist, but I know their coverage can't be great. Would love to have a coverage badge. I guess I'll need to run the AVA tests through nyc to get coverage reports.

Fix fail reporting

As of right now when something fails it gets added to an array and printed out. The printing isn't exactly as nice as it should be.
image
See? We can make that grouping of errors on their own line at least... and definitely prettier.

Dependency Check Yourself!!!

If a user does not have node 7.6+ then gluegun 2.0 fails to run, and therefore solidarity fails.

Perhaps this should be checked here: https://github.com/infinitered/solidarity/blob/master/bin/solidarity

Give them a friendly message. Instead of an annoying one, like we saw in #40

FYI: Gluegun has some code for this check for us ->
https://github.com/infinitered/gluegun/blob/master/docs/sniff.md
https://github.com/infinitered/gluegun/blob/master/packages/gluegun/sniff.js

Easily add a new rules with snapshot

CLI with no version

$ solidarity snapshot cli detox
Would you like to add the binary `detox` to your Solidarity file? (Y/n) True
Update complete

CLI with a version

$ solidarity snapshot cli node
Would you like to add the binary `node` to your Solidarity file? (Y/n) True
Would you like to enforce a version requirement? (Y/n) True
Your system currently has version 8.6.0
Semver requirement for `node` binary : ^8.6.0
Update complete

ENV var

$ solidarity snapshot env PATH
Would you like to add the environment requirement `PATH` to you Solidarity file? (Y/n) True
Update complete

File/Dir also.

$ solidarity snapshot file ./nachos
Would you like to add the file requirement `./nachos` to you Solidarity file? (Y/n) True
Update complete

Solidarity report and doctor

Soldiarity Report/Doctor

should use the .solidarity file to report the values of any given machine.

This would be ideal for people filing tickets. If I identify my technology depends on 20 things in my solidarity file. Then I could add "Please run yarn solidarity report" with my repo issue template, and it would give me results.

Like ignite doctor but for free.

Make Contributors Guide

It's not 100% clear on how someone should get started contributing. Let's add that to the docs!

Add docs with some kind of tooling (e.g. Docsify)

There needs to be clean way to read and understand how to use solidarity. Preferably, I'd love to have something where I write markdown, and it generates the github site.

I'm looking into Docsify but could really use some help on setup for this portion of the app. I'm terribly distracted while I'm working on the internals, so I haven't spent any time finding the best solution.

Add a Plugin Generator

Would be cool if I wanted to make a plugin, if all I had to do is say solidarity generate plugin and then it would ask me questions and build a plugin for me. The gluegun understructure makes something like this pretty easy.

Definitely need to add documentation of this command, which would replace https://github.com/infinitered/solidarity/blob/master/docs/plugins.md

And the current contents of plugins.md would have to move to something about "writing a plugin by hand" or similar.

Local install with npm doesn't work

Hello,

I wanted to add solidarity to one of my projects, I have the hard constraint of using npm and not yarn, when installing solidarity npm i -D solidarity the package is installed but when I run it like

./node_modules/.bin/solidarity

or even as part of package.jsonscript

  "scripts": {
    "solidarity": "solidarity",
  },

it throws an error

module.js:529
    throw err;
    ^

Error: Cannot find module 'window-size/utils'
    at Function.Module._resolveFilename (module.js:527:15)
    at Function.Module._load (module.js:476:23)
    at Module.require (module.js:568:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (./node_modules/readline-utils/index.js:13:17)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)

if I install it globally or with locally with yarn it works just fine

My Env

node -v
v8.6.0
npm -v
5.4.2

any idea why I get this problem? I also tried no install it as dependency and not devDependency, same result

Convert to Typescript

Typescript all the things from now on. It was easy to iterate with JS, but this library needs to be converted over to Typescript.

That means we're going to need a compile step and a dest folder.

Verify Global plugin install

solidarity works when the plugin is installed locally... but what about globally?

Verify this is so! Probably need to change the runner.

Bring in Types from gluegun et al.

Currently using Typescript now, but it would be ideal if empowered all the strong typing.

Bring in types from gluegun, and add interfaces inside if this project as well.

Deterministic Version Finding

Comes from convo on #23 - where code was adjusted to find the biggest version.

Consider this situation:
The CLI outputs 2 versions for some terrible reason.
On Alice's machine 1.0.1 and 0.47.2. Using your formula this would grab 0.47.2 and a person would ship that rule, happy it found the correct one.

Then on Bob's machine, he has 2 versions 2.0.0-beta and 0.47.2. On this machine, it would match 2.0.0-beta because it's longer.

Solution

By default, the tool should match the first identified semver. The user who is implementing a rule, knows this, and can always identify who will get matched.

We then provide a new property to a rule, perhaps matchIndex? Which is a bit harder to use than line, but properly so, it will help if for some reason there are multiple matches in output, that they can write a stable rule.

Add support for Windows

We need to help our Windows friends! Linux/Mac support looks great, but you never know on window. Let's check!

Custom Rules

Allow rules of type "custom" which will offload to a process owned by plugins.

The popular ones could be promoted back into the core.

Ideas:

  • A plugin that gives you rules that only make sense on a given stack.
  • A plugin that makes sure there are no cuss-words (no client embarrassment)
  • Custom webpack checker
    etc.

Docs test

A test that makes sure that any non-underscored MD file in the Docs/ folder, has a corresponding link in the sidebar

This will do nothing for coverage but will help ensure CI will fail if someone makes the mistake of updating docs and not the site navigation.

^ Good reusable test for all projects with docsify

Support Other Backend Languages

I recently wrote a similar project for Elixir. If we want to use solidarity for Elixir backend (or other) projects, there are some changes we would need to make.

As I see it, solidarity's core concept can be divided into three parts:

  1. Rule file
  2. Plugins
  3. Validator

Rule File

The config file format must be able to specify the following kinds of checks for backend projects:

  • Existence of binary in $PATH
  • Version of binary in $PATH
  • Existence of ENV variable
  • Existence of file at filesystem path
  • Conditional on ENV. Web environments require different checks in each environment. Checks must be able to be made conditional on ENV values.
    • For example, elasticsearch and Postgres are on separate hardware in production
    • The existing platform option is not a good fit for this, because we can't assume that dev environments will not be Linux.

Plugins

Plugins that generate configuration files (snapshots) for a given language or framework should be written in that language. There are several reasons for this.

  1. They can easily read their own, proprietary configuration.

    For example, if my solidarity-elixir plugin were written in Elixir, I could reliably determine which Elixir version to require in the .solidarity file.

    Mix.Project.get().project()[:elixir]
    "~> 1.5"

    If my solidarity-elixir plugin were not written in Elixir, I'd have to a) assume where the project config files are, (not always in the same place) and b) use an unreliable regex scan on the files, since I could not interpret them. In contrast, the Elixir app already knows all of this stuff when it boots.

  2. Idiomatic, tight integration. If my plugin is written in my target language, I can provide idiomatic features and interfaces for it that my target audience expect. (For example, mix or rake tasks for Elixir or Ruby developers) This will boost adoption.

    • This also allows plugins to provide native functions which users can call at runtime or when their app boots
  3. Easier plugin maintenance. The author of an Elixir or Ruby on Rails plugin already knows those languages and can most easily maintain a plugin in those languages. This will lead to higher adoption because you don't have to maintain javascript code in order to maintain a plugin.

Validator

Backend projects must run the validator at the following times:

  • Compile-time. Backend apps must fail to compile/deploy if the production server has invalid configuration. This prevents broken code from making it to production and embarrassing bugs.
  • Run-time. Configuration values can be removed at will from a backend server, without recompiling the code. Therefore, the validator must also run when the app boots. The app should still boot if configuration is invalid, but an error should be reported to Honeybadger, etc.

The validator must also have:

  • Zero runtime dependencies. We cannot assume the presence of the Node runtime for Elixir (or other) backend apps, because:
    • Not all Elixir apps use Node. Many are backend-only.
    • When Node is used, it is only used at compile-time, not run-time. (This is also true for Ruby on Rails)
    • Elixir (and other language devs) will resist adding the entire Node runtime to their dev/prod stack just so they can use solidarity. This will result in low-to-no adoption outside the javascript community.

Proposal

  • Rewrite the validator binary in a language that has zero runtime dependencies, with the following API:
    • solidarity [optional file]
      • Loads.solidarity file at designated location, if provided. Otherwise, assumes project root.
      • Parse file
      • Validate each configuration rule with a system command
      • Returns 0 if all successful
      • Returns 1 if one or more checks failed, printing a list of all failed checks
    • solidarity [optional file] --dry-run
      • Prints a list of the exact system commands that solidarity will use to validate configuration.
      • This will be useful for debugging.
      • Returns 0
    • solidarity merge [file a] [file b]
      • Mergesfile a, a solidarity config file, with file b, another solidarity config file.
      • Returns 0 if successful, removes file b
      • Returns 1 if failed, prints reason, leaves files in place
      • This allows plugins to generate their own solidarity file, which will then be merged into the main file for the project. Plugins only care about their own rules, and don't have to worry about merging them with the existing file.
        • Plugin runs, creates .solidarity-plugin-name file
        • Plugin calls solidarity merge, which merges changes and removes the plugin file.
    • solidarity --help
      • Displays help
      • Returns 0
    • solidarity --version
      • Returns the current version of solidarity
      • Returns 0
    • This API is very limited and simple, and should be easy to achieve in Go or Rust despite our team's limited familiarity with them.
  • Move existing snapshot and javascript-specific plugin functionality to a plugin: solidarity-javascript
  • Document how to make a plugin
    • When installed, each plugin would download the zero-dependencies solidarity binary from the main solidarity repo's releases
    • Each language would get to define its own snapshot extraction logic and functionality in its plugin, as described above.
    • Each plugin would be responsible to build its snapshot to .solidarity-plugin-name, and then call solidarity merge .solidarity .solidarity-plugin-name

Allow naming rules

In some cases, like React Native, a version command returns versions for more than one thing. If we can put a name on each rule the resulting errors will be more readable and user-friendly.

    "react-native": [
      {
        "rule": "cli",
        "binary": "react-native",
        "semver": "2.0.1",
        "line": 1,
        "name": "React Native CLI"
      },
      {
        "rule": "cli",
        "binary": "react-native",
        "semver": "0.42.0",
        "line": 2,
        "name": "React Native"
      }
    ]

`gluegun` Dependency Error on Fresh Install

Greetings,

Just attempted to try solidarity for the first time and hit a dependency issue.

Repro steps (on a fresh project):
yarn add -D solidarity
yarn solidarity

Error is:

$ "./node_modules/.bin/solidarity"
module.js:529
    throw err;
    ^

Error: Cannot find module './node_modules/solidarity/bin/../node_modules/gluegun/sniff'
    at Function.Module._resolveFilename (module.js:527:15)
    at Function.Module._load (module.js:476:23)
    at Module.require (module.js:568:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (./node_modules/solidarity/bin/solidarity:3:38)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)
error Command failed with exit code 1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.