summaryrefslogtreecommitdiff
path: root/wiki/dev
diff options
context:
space:
mode:
authorOwen Jacobson <owen.jacobson@grimoire.ca>2014-05-28 16:11:01 -0400
committerOwen Jacobson <owen.jacobson@grimoire.ca>2014-05-28 16:11:01 -0400
commitb0c376d2a7ded722cd49f88e515c53632ec75730 (patch)
treede354549a8285063f482975bf44db7ba97f47c29 /wiki/dev
parent693eec80b65299ff679a458bb7039d656ece550f (diff)
Typographic fixes around double quotes.
Diffstat (limited to 'wiki/dev')
-rw-r--r--wiki/dev/builds.md14
-rw-r--r--wiki/dev/commit-messages.md12
-rw-r--r--wiki/dev/debugger-101.md16
-rw-r--r--wiki/dev/liquibase.md6
-rw-r--r--wiki/dev/merging-structural-changes.md16
-rw-r--r--wiki/dev/rich-shared-models.md10
-rw-r--r--wiki/dev/trackers-from-first-principles.md78
-rw-r--r--wiki/dev/twigs.md6
-rw-r--r--wiki/dev/why-scm.md8
9 files changed, 83 insertions, 83 deletions
diff --git a/wiki/dev/builds.md b/wiki/dev/builds.md
index f559459..8f334a1 100644
--- a/wiki/dev/builds.md
+++ b/wiki/dev/builds.md
@@ -29,9 +29,9 @@ person's physical and mental well-being on the premise that all the items at
the lowest level of the hierarchy must be met before a person will be able to
focus usefully on higher-level needs. Maslow's hierarchy begins with a set of
needs that, without which, you do not have a person (for long)—physiological
-needs like "breathing," "food," and "water." At the peak, there are extremely
+needs like “breathing,” “food,” and “water.” At the peak, there are extremely
high-level needs that are about being a happy and enlightened
-person—"creativity," "morality," "curiosity," and so on.
+person—“creativity,” “morality,” “curiosity,” and so on.
![A three-tier pyramid. At the bottom: Automatable. Repeatable. Standardized.
Extensible. Understood. In the middle tier: Simple. Fast. Unit tests. Part of
@@ -50,7 +50,7 @@ Before a build is a build, there are five key needs to meet:
* **It must be repeatable**. Every time you start your build on a given source
tree, it must build exactly the same products without any further
intervention. Without this, you can't reliably decide whether a given build
- is "good," and can easily wind up with a build that needs to be run several
+ is “good,” and can easily wind up with a build that needs to be run several
times, or a build that relies on running several commands in the right
order, to produce a build.
* **It must be automatable**. Build systems are used by developers sitting at
@@ -69,7 +69,7 @@ Before a build is a build, there are five key needs to meet:
descriptor before it can compile anything. There must be affordances within
the standard build that allow developers to describe the ways their build is
different. Without this, you have to write what amounts to a second build
- tool to ensure that all the "extra" steps for certain projects happen.
+ tool to ensure that all the “extra” steps for certain projects happen.
* **Someone must understand it**. A build nobody understands is a time bomb:
when it finally breaks (and it will), your project will be crippled until
someone fixes it or, more likely, hacks around it.
@@ -77,7 +77,7 @@ Before a build is a build, there are five key needs to meet:
If you have these five things, you have a working build. The next step is to
make it comfortable. Comfortable builds can be used daily for development
work, demonstrations, and tests as well as during releases; builds that are
-used constantly don't get a chance to "rust" as developers ignore them until a
+used constantly don't get a chance to “rust” as developers ignore them until a
release or a demo and don’t hide surprises for launch day.
* **It must be simple**. When a complicated build breaks, you need someone who
@@ -100,7 +100,7 @@ release or a demo and don’t hide surprises for launch day.
uniform on any environment, any developer can cook up a build for a test or
demo at any time.
-Finally, there are "chrome" features that take a build from effective to
+Finally, there are “chrome” features that take a build from effective to
excellent. These vary widely from project to project and from organization to
organization. Here are some common chrome needs:
@@ -125,7 +125,7 @@ organization. Here are some common chrome needs:
builds amplifies the benefits of early testing and, if your acceptance tests
are good, when your project is done.
* **It should not need repeating**. Once you declare a particular set of build
- products "done", you should be able to use those products as-is any time you
+ products “done,” you should be able to use those products as-is any time you
need them. Without this, you will eventually find yourself rebuilding the
same code from the same release over and over again.
diff --git a/wiki/dev/commit-messages.md b/wiki/dev/commit-messages.md
index 6661671..6b3702d 100644
--- a/wiki/dev/commit-messages.md
+++ b/wiki/dev/commit-messages.md
@@ -1,6 +1,6 @@
# Writing Good Commit Messages
-Rule zero: "good" is defined by the standards of the project you're on. Have a
+Rule zero: “good” is defined by the standards of the project you're on. Have a
look at what the existing messages look like, and try to emulate that first
before doing anything else.
@@ -8,13 +8,13 @@ Having said that, here are some things that will help your commit messages be
useful later:
* Treat the first line of the message as a one-sentence summary. Most SCM
- systems have an "overview" command that shows shortened commit messages in
+ systems have an “overview” command that shows shortened commit messages in
bulk, so making the very beginning of the message meaningful helps make
those modes more useful for finding specific commits. _It's okay for this to
- be a "what" description_ if the rest of the message is a "why" description.
+ be a “what” description_ if the rest of the message is a “why” description.
* Fill out the rest of the message with prose outlining why you made the
- change. The guidelines for a good "why" message are the same as [the
+ change. The guidelines for a good “why” message are the same as [the
guidelines for good comments](comments), but commit messages can be
signifigantly longer. Don't bother reiterating the contents of the change in
detail; anyone who needs that can read the diff themselves.
@@ -27,8 +27,8 @@ useful later:
of the way, such as on a line of its own at the end of the message.
* Pick a tense and a mood and stick with them. Reading one commit with a
- present-tense imperative message ("Add support for PNGs") and another commit
- with a past-tense narrative message ("Fixed bug in PNG support") is
+ present-tense imperative message (“Add support for PNGs”) and another commit
+ with a past-tense narrative message (“Fixed bug in PNG support”) is
distracting.
* If you need rich commit messages (links, lists, and so on), pick one markup
diff --git a/wiki/dev/debugger-101.md b/wiki/dev/debugger-101.md
index 8698c3b..6d7e773 100644
--- a/wiki/dev/debugger-101.md
+++ b/wiki/dev/debugger-101.md
@@ -3,7 +3,7 @@
(Written largely because newbies in [##java](http://evanchooly.com) never seem
to have this knowledge.)
-A "debugger" is a mechanism for monitoring and controlling the execution of
+A “debugger” is a mechanism for monitoring and controlling the execution of
your program, usually interactively. Using a debugger, you can stop your
program at known locations and examine the _actual_ values of its variables
(to compare against what you expected), monitor variables for changes (to see
@@ -14,7 +14,7 @@ Pretty much every worthwhile language has debugging support of some kind,
whether it's via IDE integration or via a command-line debugger.
(Of course, none of this helps if you don't have a mental model of the
-"expected" behaviour of the program. Debuggers can help you read, but can't
+“expected” behaviour of the program. Debuggers can help you read, but can't
replace having an understanding of the code.)
## Debugging Your First Program
@@ -43,8 +43,8 @@ program - generally in one of five ways:
* Execute the _next_ statement. Execution proceeds for one statement in the
current function, then stops again. If the statement is, for example, a
function or method call, the call will be completely evaluated (unless it
- contains breakpoints of its own). (In some debuggers, this is labelled "step
- over", since it will step "over" a function call.)
+ contains breakpoints of its own). (In some debuggers, this is labelled “step
+ over,” since it will step “over” a function call.)
* _Step_ forward one operation. Execution proceeds for one statement, then
stops again. This mode can single-step into function calls, rather than
@@ -54,8 +54,8 @@ program - generally in one of five ways:
reaches the end of the current function, then halts the program again.
* _Continue to a specific statement_. Some debuggers support this mode as a
- way of stepping over or through "uninteresting" sections of code quickly and
- easily. (You can implement this yourself with "Continue" and normal
+ way of stepping over or through “uninteresting” sections of code quickly and
+ easily. (You can implement this yourself with “Continue” and normal
breakpoints, too.)
Whenever the debugger halts your program, you can do any of several things:
@@ -67,7 +67,7 @@ Whenever the debugger halts your program, you can do any of several things:
having to rerun your code with extra debug output.
* Inspect the result of an expression. The debugger will evaluate an
- expression "as if" it occurred at the point in the program where the
+ expression “as if” it occurred at the point in the program where the
debugger is halted, including any local variables. In languages with static
visibility controls like Java, visibility rules are often relaxed in the
name of ease of use, allowing you to look at the private fields of objects.
@@ -75,7 +75,7 @@ Whenever the debugger halts your program, you can do any of several things:
like a variable.
* Modify a variable or field. You can use this to quickly test hypotheses: for
- example, if you know what value a variable "should" have, you can set that
+ example, if you know what value a variable “should” have, you can set that
value directly and observe the behaviour of the program to check that it
does what you expected before fixing the code that sets the variable in a
non-debug run.
diff --git a/wiki/dev/liquibase.md b/wiki/dev/liquibase.md
index 6e5e97d..01e989f 100644
--- a/wiki/dev/liquibase.md
+++ b/wiki/dev/liquibase.md
@@ -1,7 +1,7 @@
# Liquibase
-Note to self: I think this (a) needs an outline and (b) wants to become a "how
-to automate db upgrades for dummies" page. Also, this is really old (~2008)
+Note to self: I think this (a) needs an outline and (b) wants to become a “how
+to automate db upgrades for dummies” page. Also, this is really old (~2008)
and many things have changed: database migration tools are more
widely-available and mature now. On the other hand, I still see a lot of
questions on IRC that are based on not even knowing these tools exist.
@@ -74,4 +74,4 @@ The liquibase developers deserve a lot of credit for solving a hard problem
very cleanly.
*[DDL]: Data Definition Language
-*[DML]: Data Manipulation Language \ No newline at end of file
+*[DML]: Data Manipulation Language
diff --git a/wiki/dev/merging-structural-changes.md b/wiki/dev/merging-structural-changes.md
index f597d39..a47fdcc 100644
--- a/wiki/dev/merging-structural-changes.md
+++ b/wiki/dev/merging-structural-changes.md
@@ -40,21 +40,21 @@ merged in. On the right, a working copy of the branch where the structure
changed is checked out, then the changes from the branch where the content
changed are merged in. In both cases, the result of the merge has the new
directory name, and the original file contents. In one case, the merge
-triggers a rather opaque warning about a "missing file"; in the other, the
+triggers a rather opaque warning about a “missing file”; in the other, the
merge silently ignores the content changes.
This is a consequence of the way Subversion implements renames and copies.
When Subversion assembles a changeset for committing to the repository, it
comes up with a list of primitive operations that reproduce the change. There
-is no primitive that says "this object was moved," only primitives which say
-"this object was deleted" or "this object was added, as a copy of that
-object." When you move a file in Subversion, those two operations are
+is no primitive that says “this object was moved,” only primitives which say
+“this object was deleted” or “this object was added, as a copy of that
+object.” When you move a file in Subversion, those two operations are
scheduled. Later, when Subversion goes to merge content changes to the
original file, all it sees is that the file has been deleted; it's completely
unaware that there is a new name for the same file.
-This would be fairly easy to remedy by adding a "this object was moved to that
-object" primitive to the changeset language, and [a bug report for just such a
+This would be fairly easy to remedy by adding a “this object was moved to that
+object” primitive to the changeset language, and [a bug report for just such a
feature](http://subversion.tigris.org/issues/show_bug.cgi?id=898) was filed in
2002. However, by that time Subversion's repository and changeset formats had
essentially frozen, as Subversion was approaching a 1.0 release and more
@@ -73,8 +73,8 @@ change.](/media/dev/merging-structural-changes/mercurial-merge-results)
Interestingly, there are tools which get this merge scenario right: the
diagram above shows how [Mercurial](http://www.selenic.com/mercurial/) handles
-the same two tests. Since its changeset language does include an "object
-moved" primitive, it's able to take a content change for `dir-a/file` and
+the same two tests. Since its changeset language does include an “object
+moved” primitive, it's able to take a content change for `dir-a/file` and
apply it to `dir-b/file` if appropriate.
## Git
diff --git a/wiki/dev/rich-shared-models.md b/wiki/dev/rich-shared-models.md
index 7309dbe..7fac072 100644
--- a/wiki/dev/rich-shared-models.md
+++ b/wiki/dev/rich-shared-models.md
@@ -23,7 +23,7 @@ models slightly differently.
With the rise of object-oriented development, explicit models became the focus
of several well-known practices. Many medium-to-large projects are built
-"model first", with the interfaces to that model being sketched out later in
+“model first,” with the interfaces to that model being sketched out later in
the process. Since the model holds the system's understanding of its task,
this makes sense, and so long as you keep the problem you're actually solving
in mind, it works well. Unfortunately, it's too easy to lose sight of the
@@ -37,7 +37,7 @@ best.
* Unmanaged growth
* Adding features to an existing system
* Building new systems on top of existing tools
- * Misguided applications of "simplicity" and "reuse"
+ * Misguided applications of “simplicity” and “reuse”
* Encouraged by distributed object systems (CORBA, EJB, SOAP, COM)
* What are the consequences?
* Models end up holding behaviour and data relevant to many applications
@@ -69,16 +69,16 @@ functionality was already in one place, it became psychologically easy to add
one more responsibility to its already-bloated interface.
What had been a clean model in the problem space eventually became one of a
-handful of "glue" pieces in a [big ball of
+handful of “glue” pieces in a [big ball of
mud](http://www.laputan.org/mud/mud.html#BigBallOfMud) program. The User
object did not come about through conscious design, but rather through
evolution from a simple system. There was no clear point where User became
-"too big"; instead, the vagueness of its role slowly grew until it became the
+“too big”; instead, the vagueness of its role slowly grew until it became the
default behaviour-holder for all things user-specific.
The same problem modeling exercise also points at a better way to design the
same system: it describes a number of capabilities the system needed to be
-able to perform, each of which is simpler than "build a gaming website." Each
+able to perform, each of which is simpler than “build a gaming website.” Each
of these capabilities (accept or reject logins, process deposits, accept and
settle wagers, and send out notification emails to players) has a much simpler
model and solves a much more constrained of problem. There is no reason the
diff --git a/wiki/dev/trackers-from-first-principles.md b/wiki/dev/trackers-from-first-principles.md
index cd4148f..d7c7a4c 100644
--- a/wiki/dev/trackers-from-first-principles.md
+++ b/wiki/dev/trackers-from-first-principles.md
@@ -10,11 +10,11 @@ Why do we track tasks?
* Otherwise we'd just remember it in our heads.
* Wishlist tasks are not a bad thing!
-Bugs/defects are a kind of task but not the only kind. Most teams have a "bug
-tracker" that contains a lot more than bugs. Let's not let bugs dictate the
+Bugs/defects are a kind of task but not the only kind. Most teams have a “bug
+tracker” that contains a lot more than bugs. Let's not let bugs dictate the
system.
-* Therefore, "steps to reproduce" should not be a required datum.
+* Therefore, “steps to reproduce” should not be a required datum.
Bugs are an _important_ kind of task.
@@ -59,11 +59,11 @@ team-specific.
There may be other people _involved_ in a task that are not _responsible_ for
a task, in a number of roles. Just because I developed the code for a feature
does not mean I am necessarily responsible for the feature any more, but it
-might be useful to have a "developed by" list for the feature's task.
+might be useful to have a “developed by” list for the feature's task.
Ways of identifying people:
-* Natural-language names ("Gianna Grady")
+* Natural-language names (“Gianna Grady”)
* Email addresses
* Login names
* Distinguished names in some directory
@@ -74,7 +74,7 @@ communicate it, but do not normally define it.
## Workflow
-"Workflow" describes both the implications of the states a task can be in and
+“Workflow” describes both the implications of the states a task can be in and
the implications of the transitions between states. Most task trackers are, at
their core, workflow engines of varying sophistication.
@@ -93,10 +93,10 @@ work it describes.
Elemental states:
-* "Open": in this state, the task has not yet been completed. Work may or may
+* “Open”: in this state, the task has not yet been completed. Work may or may
not be ongoing.
-* "Completed": in this state, all work on a task has been completed.
-* "Abandoned": in this state, no further work on a task will be performed, but
+* “Completed”: in this state, all work on a task has been completed.
+* “Abandoned”: in this state, no further work on a task will be performed, but
the task has not been completed.
Most real-world workflows introduce some intermediate states that tie into
@@ -104,29 +104,29 @@ process-related handoffs.
For software, I see these divisions, in various combinations, frequently:
-* "Open":
- * "Unverified": further work needs to be done to decide whether the task
+* “Open”:
+ * “Unverified”: further work needs to be done to decide whether the task
should be completed.
- * "In Development": someone is working on the code and asset changes
+ * “In Development”: someone is working on the code and asset changes
necessary to complete the task. This occasionally subsumes preliminary
work, too.
- * "In Testing": code and asset changes are ostensibly complete,
+ * “In Testing”: code and asset changes are ostensibly complete,
but need testing to validate that the task has been completed
satisfactorially.
-* "Completed":
- * "Development Completed": work (and possibly testing) has been completed
+* “Completed”:
+ * “Development Completed”: work (and possibly testing) has been completed
but the task's results are not yet available to external users.
- * "Released": work has been completed, and external users can see and use
+ * “Released”: work has been completed, and external users can see and use
the results.
-* "Abandoned":
- * "Cannot Reproduce": common in bug/defect tasks, to indicate that the
+* “Abandoned”:
+ * “Cannot Reproduce”: common in bug/defect tasks, to indicate that the
task doesn't contain enough information to render the bug fixable.
- * "Won't Complete": the task is well-understood and theoretically
+ * “Won't Complete”: the task is well-understood and theoretically
completable, but will not be completed.
- * "Duplicate": the task is identical to, or closely related to, some other
+ * “Duplicate”: the task is identical to, or closely related to, some other
task, such that completing either would be equivalent to completing
both.
- * "Invalid": the task isn't relevant, is incompletely described, doesn't
+ * “Invalid”: the task isn't relevant, is incompletely described, doesn't
make sense, or is otherwise not appropriate work for the team using the
tracker.
@@ -135,14 +135,14 @@ None of these are universal.
Transitions show how a task moves from state to state.
* Driven by external factors (dev work leads to tasks being marked completed)
- * Explicit transitions: "mark this task as completed"
- * Implicit transitions: "This commit also completes these tasks"
+ * Explicit transitions: “mark this task as completed”
+ * Implicit transitions: “This commit also completes these tasks”
* Drive external factors (tasks marked completed are emailed to testers)
States implicitly describe a _belief_ or a _desire_ about the future of the
task, which is a human artifact and may be wrong or overly hopeful. Tasks can
-transition to "Completed" or "Abandoned" states when the work hasn't actually
-been completed or abandoned, or from "Completed" or "Abandoned" to an "Open"
+transition to “Completed” or “Abandoned” states when the work hasn't actually
+been completed or abandoned, or from “Completed” or “Abandoned” to an “Open”
state to note that the work isn't as done as we thought it was. _This is a
feature_ and trackers that assume every transition is definitely true and
final encourage ugly workarounds like duplicating tickets to reopen them.
@@ -150,7 +150,7 @@ final encourage ugly workarounds like duplicating tickets to reopen them.
## Speciation
I mentioned above that bugs are a kind of task. The ways in which bugs are
-"different" is interesting:
+“different” is interesting:
* Good bugs have a well-defined reproduction case - steps you can follow to
demonstrate and test them.
@@ -165,11 +165,11 @@ necessary.
Supporting structure helps if it leads to more interesting or efficient ways
of using tasks to drive and understand work.
-Bugs are not the only "special" kind of task:
+Bugs are not the only “special” kind of task:
-* "Feature" tasks show up frequently, and speciate on having room for
+* “Feature” tasks show up frequently, and speciate on having room for
describing specs and scope.
-* "Support ticket" tasks show up in a few trackers, and speciate dramatically
+* “Support ticket” tasks show up in a few trackers, and speciate dramatically
as they tend to be tasks describing the work of a single incident rather
than tasks describing the work on some shared aspect, so they tend to pick
up fields for relating tickets to the involved parties. (Arguably, incident
@@ -183,20 +183,20 @@ repro is a good example; every task whose goal is to fix a defect should
include a clear understanding of the defect, both to allow it to be fixed and
to allow it to be tested. Adding specialized data for bugs supports that by
encouraging clearer, more structured descriptions of the defect (with implicit
-"fix this" as the task).
+“fix this” as the task).
## Implementation notes
-If we reduce task tracking to "record changes to fields and record discussion
-comments, on a per task basis", we can describe the current state of a ticket
-using the "most recent" values of each field and the aggregate of all recorded
+If we reduce task tracking to “record changes to fields and record discussion
+comments, on a per task basis,” we can describe the current state of a ticket
+using the “most recent” values of each field and the aggregate of all recorded
comments. This can be done ~2 ways:
-1. "Centralized" tracking, where each task has a single, total order of
+1. “Centralized” tracking, where each task has a single, total order of
changes. Changes are mediated through a centralized service.
-2. "Decentralized" tracking, where each task has only a partial order over the
+2. “Decentralized” tracking, where each task has only a partial order over the
history of changes. Changes are mediated by sharing sets of changes, and by
- appending "reconciliation" changes to resolve cases where two incomparable
+ appending “reconciliation” changes to resolve cases where two incomparable
changes modify the same field/s. The most obvious partial order is a
digraph.
@@ -204,16 +204,16 @@ Centralized tracking is a well-solved problem. Decentralized tracking so far
seems to rely heavily on DSCM tools (Git, Mercurial, Fossil) for resolving
conflicts.
-The "work offline" aspect of a distributed tracker is less interesting in as
+The “work offline” aspect of a distributed tracker is less interesting in as
much as task tracking is a communications tool. Certain kinds of changes
should be published and communicated as early as possible so as to avoid
misunderstandings or duplicated work.
Being able to separate the mechanism of how changes to tasks are recorded from
-the policy of which library of tasks is "canonical" is potentially useful as
+the policy of which library of tasks is “canonical” is potentially useful as
an editorial tool and for progressive publication to wider audiences as work
progresses.
Issue tracking is considerably more amenable to append-only implementations
than SCM is, even if you dislike history-editing SCM workflows. This suggests
-that Git is a poor choice of issue-tracking storage backends... \ No newline at end of file
+that Git is a poor choice of issue-tracking storage backends...
diff --git a/wiki/dev/twigs.md b/wiki/dev/twigs.md
index ebc875c..c3c7505 100644
--- a/wiki/dev/twigs.md
+++ b/wiki/dev/twigs.md
@@ -5,7 +5,7 @@
* Relatively short-lived
* Share the commit policy of their parent branch
* Gain little value from global names
-* Examples: most "topic branches" are twigs
+* Examples: most “topic branches” are twigs
## Branches
@@ -17,8 +17,8 @@
## Commit policy
-* Decisions like "should every commit pass tests?" and "is rewriting or
- deleting a commit acceptable?" are, collectively, the policy of a branch
+* Decisions like “should every commit pass tests?” and “is rewriting or
+ deleting a commit acceptable?” are, collectively, the policy of a branch
* Can be very formal or even tool-enforced, or ad-hoc and fluid
* Shared understanding of commit policy helps get everyone's expectations
lined up, easing other SCM-mediated conversations
diff --git a/wiki/dev/why-scm.md b/wiki/dev/why-scm.md
index c6c8b86..5985982 100644
--- a/wiki/dev/why-scm.md
+++ b/wiki/dev/why-scm.md
@@ -27,11 +27,11 @@ also helps with less-drastic solutions by letting you run comparisons between
your broken code and working code, which helps narrow down whatever problem
you've created for yourself.
-(Aside: if you're in a shop that "doesn't use source control", and for
+(Aside: if you're in a shop that “doesn't use source control,” and for
whatever insane reason you haven't already run screaming, this safety net is a
good reason to use source control independently of the organization as a
whole. Go on, it's easy; modern DSCM tools like Mercurial or Git make
-importing "external" trees pretty straightforward. Your future self thanks
+importing “external” trees pretty straightforward. Your future self thanks
you.)
## Historical record
@@ -51,11 +51,11 @@ the loop agree on what, exactly, the software being released looks like and
whether or not various releasability criteria have been met. It doesn't matter
if you use rolling releases or carefully curate and tag every release after
months of discussion, you still need to be able to point to a specific version
-of your project's source code and say "this will be our next release".
+of your project's source code and say “this will be our next release.”
SCM systems can help direct and contextualize that discussion by recording the
way your project has changed during those discussion, whether that's part of
-development or a separate post-"freeze" release process.
+development or a separate post-“freeze” release process.
## Proposals and speculative development