-
-
Notifications
You must be signed in to change notification settings - Fork 3
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
everything #1
everything #1
Conversation
Makefile
Outdated
SHELL = /bin/bash | ||
|
||
NPM = npm | ||
SHELLCHECK = shellcheck |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ShellCheck looks like a nice tool :)
written in Haskell, if you're into that sort of thing
I'm sold!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this project a lot! I enjoy seeing advanced* bash scripting.
* By advanced, I mean anything I couldn't pull off myself.
README.md
Outdated
@@ -0,0 +1,3 @@ | |||
# sanctuary-scripts | |||
|
|||
Shell scripts used in multiple Sanctuary projects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be more information here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite possibly. What sort of information do you have in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚡
bin/generate-readme
Outdated
set -euf -o pipefail | ||
|
||
transcribe() { | ||
local -r project="$(node --print 'require("./package.json").repository.url.replace(/[.]git$/, "").split("/").slice(-2).join("/")')" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The repository
field in a package.json
doesn't have to be an object with a url
property. It can be a string representation with a variety of formats. Do we want to support these formats? If not, we should mention that in the README.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know about the --print
option in Node. That's great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My goal is to make using these scripts in Sanctuary projects (and other projects with the same conventions) as convenient as possible. This means I'm willing to make the scripts less flexible in order to avoid configuration (in some cases default values can be used to let us have our 🍰 and eat it too).
We could add a lint-package-json
script which performs some package.json-specific checks in addition to the sanity check performed by lint-json
. It could assert that repository.url
is present and that its value is suitable. What do you think of this idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚡
bin/generate-readme
Outdated
transcribe() { | ||
local -r project="$(node --print 'require("./package.json").repository.url.replace(/[.]git$/, "").split("/").slice(-2).join("/")')" | ||
local -r version="${VERSION?Environment variable not set}" | ||
local -r url="https://github.com/$project/blob/v$version/{filename}#L{line}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see we rely explicitly on version being prefixed by v
. I don't see a script for XYZ specified in this repo, so this means that one has to configure XYZ properly for sanctuary-scripts
to work. Maybe we can add a release.sh
script or something to this repo which ensures the correct tagging convention? Or if not, we should add a note to the README.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I had not noticed this unstated assumption. I had been unsure as to whether sanctuary-scripts should manage the xyz dependency; you've made it clear to me that it should.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚡
bin/lint-commit-message
Outdated
echo 0 ; | ||
} \ | ||
| head -n 1 \ | ||
| xargs expr 1 + 25 + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than adding an arbitrary buffer to the PR number, can't we just add a single character buffer? So an additional reserved character to allow for the expansion of the PR number? That would mean that:
After the 1st PR, we reserve 9 slots
Once we reach 10 PR's, we reserve 990 slots
Once we reach 100 PR's, we reserve 9900 slots
...etc...
To me this approach seems less arbitrary, and more scalable. On the other hand, it might be overkill, and it may be upsetting to have 90% of all merge commit messages needlessly limited to -1 characters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me this approach seems less arbitrary, and more scalable.
I dislike arbitrariness. I like your suggestion. I will make the change. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚡
bin/lint-commit-message
Outdated
|
||
project_name() { | ||
git config --get remote.origin.url \ | ||
| sed -e 's,^git@github[.]com:,,' -e 's,^https://github[.]com/,,' \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a nice way to avoid escape-hell (\\\\.
) in this case. I will remember. :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, using s,,,
rather than s///
avoids lots of confusion when matching URLs. :)
bin/update-copyright-year
Outdated
exit 1 | ||
fi | ||
|
||
mv "$updated" "$license" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be forced? Won't bash complain that the file is already at this destination?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's certainly a reasonable expectation. By default, though, mv
will quite happily replace an existing file (there are flags for changing this behaviour).
README.md
Outdated
|
||
## `lint-package-json` | ||
|
||
Asserts that __package.json__ exists and contains certain fields with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
certain some important? (to match check-required-files
and remove air of mystery)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚡
README.md
Outdated
|
||
## `lint-json` | ||
|
||
Asserts that the specified JSON files exist and are neatly formatted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the script doesn't do what this says. It should say something like: Asserts that the specified JSON files exist and have no syntax error, and then formats these files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It really does assert that the files are neatly formatted. After reformatting a file it runs git --no-pager diff --exit-code -- "$file"
. The --exit-code
flag is important here:
--exit-code Make the program exit with codes similar to diff(1). That is, it exits with 1 if there were differences and 0 means no differences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh. I see. But it does leave the working tree "dirty" (with neat files) afterwards?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having put this script through its paces I no longer think involving git
is a good idea. I'll rework the script to use cp
and diff
instead. This will avoid making a mess, and will allow linting of untracked JSON files.
bin/release
Outdated
node_modules/.bin/xyz \ | ||
--increment "${increment}" \ | ||
--repo "git@github.com:${owner}/${name}.git" \ | ||
--script scripts/prepublish \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that there's way to configure some of these scripts, should this field remain hard-coded? Maybe
prepublish-script = scripts/prepublish
Allowing it to be emptied, similarly to the version-prefix
option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. I'll make this change. We can keep scripts/prepublish
as the default value, and have check-required-files
assert that the (explicitly or implicitly) specified file is present and executable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided not to make this change after all, as we're already relying on convention for overriding the behaviour of scripts. To override sanctuary-lint
, for example, one would create an executable at scripts/lint.
Note that this pull request includes a default prepublish script suitable for use in most Sanctuary projects.
0fbf6e4
to
64d6cac
Compare
8ed1313
to
3d870d3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed you squashed, so I gave it a last good look.
```json | ||
{ | ||
"root": true, | ||
"extends": ["./node_modules/sanctuary-style/eslint-es3.json"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use a short notation, like "sanctuary-style/eslint-es3".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I didn't know that. I'll keep it as it is for consistency with the handful of projects I updated over the weekend.
README.md
Outdated
| `heading-level` | `4` | The `<h[1-6]>` level of headings transcribed from `heading-prefix` comments. | | ||
| `heading-prefix` | `#` | The character which follows `//` to signify a heading to transcribe. | | ||
| `comment-prefix` | `.` | The character which follows `//` to signify documentation to transcribe. | | ||
| `version-tag-prefix` | `v` | The prefix of annotated version tags (use _null_ for `X.Y.Z` format). | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not immediately clear to me what is meant by use null. Do I set the value to literal null
? Or do I omit the value part of my expression ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it's unclear.
I consulted the Bash Reference Manual many times in the days prior to writing this. It uses null, null string, and null value to refer to the empty string (in JavaScript parlance).
I'm attempting to convey that a user should add
version-tag-prefix =
to her .config if she wants to use X.Y.Z
format rather than vX.Y.Z
format. The problem with referring to the empty string is it suggests she should add
version-tag-prefix = ''
instead, which is incorrect.
Can you think of a better explanation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with this:
The prefix of annotated version tags (use
version-tag-prefix =
for).
⚡
branches="$(get min-branch-coverage)" | ||
|
||
node_modules/.bin/istanbul cover node_modules/.bin/_mocha | ||
node_modules/.bin/istanbul check-coverage --branches "$branches" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider updating to nyc
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Do you think we should do so? What are the advantages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's wait for a tool that uses V8 native code coverage reporting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just spawned into existence https://github.com/bcoe/c8
bin/update-copyright-year
Outdated
fi | ||
|
||
declare -r creator="${1-Sanctuary}" | ||
declare -r license="${2-LICENSE}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the logic which determines a script using command line arguments over a value in .config
? Incidentally, could you teach me about ${1-foo}
-syntax?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the logic which determines a script using command line arguments over a value in
.config
?
This script is inconsistent in this respect, but for good reasons (I believe). It seems to me the script most likely to be used in non-Sanctuary projects. It's thus important that the name of the licence file is configurable (check-required-files
actually requires a file named LICENSE, so this is only relevant to projects using scripts à la carte).
I'd like to support those who wish to use only this script. It would be burdensome and a little messy to require a configuration file in order to use a single shell script.
Perhaps I'm overthinking this. It would certainly be more consistent to move these to .config, and to remove from check-required-files
the hard-coded reference to LICENSE. Is this what you suggest?
Incidentally, could you teach me about
${1-foo}
-syntax?
The first thing to know is that $var
is shorthand for ${var}
:
$ VAR=hello bash -c 'var=world ; echo "$VAR $var"'
hello world
$ VAR=hello bash -c 'var=world ; echo "${VAR} ${var}"'
hello world
As you're no doubt aware, $1
, $2
, $3
, etc. refer to command-line arguments. We now know that these can be written as ${1}
, ${2}
, ${3}
, etc.
§ 3.5.3 Shell Parameter Expansion:
${parameter:-word}
If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
$ bash -c 'foo=42 ; bar= ; echo "foo: ${foo:-default}, bar: ${bar:-default}, baz: ${baz:-default}"'
foo: 42, bar: default, baz: default
We are omitting the colon, though, which changes the handling of null:
When not performing substring expansion, using the form described below (e.g., ‘
:-
’), Bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for bothparameter
’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence.
$ bash -c 'foo=42 ; bar= ; echo "foo: ${foo-default}, bar: ${bar-default}, baz: ${baz-default}"'
foo: 42, bar: , baz: default
So, ${1-Sanctuary}
evaluates to the value of the first command-line argument if at least one command-line argument is provided; Sanctuary
otherwise. As is so often the case with Bash, this convenient functionality is hidden behind arcane syntax few will ever discover.
bin/check-required-files
Outdated
fi | ||
} | ||
|
||
check -f .circleci/config.yml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unfortunate that this script creates a circleci lock-in. I've tried using sanctuary-script on my own project which uses Travis, and avoiding this check is not that straightforward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! Shall we simply remove this check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would certainly solve my issue. Perhaps we can also check that all source-files
are present (not sure if we want to though), and in that spirit, we could add a dev-files
options or something that defaults to .circleci/config.yml
. In that case I could avoid this check by adding the following to my config:
dev-files = .travis.yml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The benefit of such a check is marginal if one must remember to enable the check. In other words, one could just as easily touch .travis.yml && git add .travis.yml
as add dev-files = .travis.yml
to .config.
I've removed the check above. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
bin/lint-readme
Outdated
--no-stdout \ | ||
--use remark-lint-no-undefined-references \ | ||
--use remark-lint-no-unused-definitions \ | ||
--use validate-links \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validate-links
plugin fails all README's generated by generate-readme
, because it does not take HTML heading elements into account when verifying links to anchors.
bin/generate-readme
Outdated
')" | ||
|
||
local -r pattern1='^<h4 name="([^"]*)#([^"]*)">' | ||
local -r pattern2='^(.+) ([Vv]):(.+)/([^#]+)' # V => 1.2.3 ; v => v1.2.3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bin/lint-package-json
Outdated
|
||
assert "pkg.name === '$name' || pkg.name === '@$owner/$name'" | ||
|
||
assert "matches(pkg.version, /^[0-9]+[.][0-9]+[.][0-9]+$/)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used /^\d+[.]\d+[.]\d+(?:-[a-z0-9.]+)?(?:[+][a-z0-9.]+)?$/
in one of my own projects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just use /./
here. All I really want to ensure is that the field is present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I've used such specific checking, is because another part of my code relies on this value having that specific format.
The same might be said about bin/release
depending on the format of pkg.version
, so I think it's worth considering the strict validation so to prevent release
from failing in an unexpected way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
release
would fail with a message such as Invalid version: XXX
before performing any irreversible actions, so I don't think extra validation is warranted. Furthermore, one should rarely need to edit pkg.version
manually so invalid values are unlikely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ready to merge?
bca5846
to
8c4ce48
Compare
e565b47
to
3f2ae5f
Compare
We've spent a lot of time developing the infrastructure surrounding the various Sanctuary projects. Here are some of the pull requests:
When creating a new Sanctuary project we usually copy an existing makefile, a couple of shell scripts, and a dozen or so dev dependencies. There are two problems with this approach:
To address these problems, this pull request brings together (and improves) a number of scripts currently found in various Sanctuary repositories.
These compare views provide an idea of the amount of common code which we'll be able to remove from the various Sanctuary repositories:
Note that the diff is less impressive for sanctuary-def, but this is because some of the infrastructure added to the Sanctuary repository has not yet propagated to other repositories.