diff --git a/CHANGELOG.md b/CHANGELOG.md index 16b14d15e..b5aa72f9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,15 @@ ## 0.7.2 (unreleased) +FEATURES: + + * builder/parallels: Don't depend on _prl-utils_ [GH-1499] + BUG FIXES: * builder/vmware-vmx: Fix issue with order of boot command support [GH-1492] + * builder/parallels: Ignore 'The fdd0 device does not exist' [GH-1501] + * builder/parallels: Rely on Cleanup functions to detach devices [GH-1502] + * builder/parallels: Create VM without hdd and then add it later [GH-1548] ## 0.7.1 (September 10, 2014) diff --git a/builder/parallels/common/driver.go b/builder/parallels/common/driver.go index babc38c32..771395d8c 100644 --- a/builder/parallels/common/driver.go +++ b/builder/parallels/common/driver.go @@ -15,6 +15,9 @@ import ( // versions out of the builder steps, so sometimes the methods are // extremely specific. type Driver interface { + // Adds new CD/DVD drive to the VM and returns name of this device + DeviceAddCdRom(string, string) (string, error) + // Import a VM Import(string, string, string, bool) error diff --git a/builder/parallels/common/driver_9.go b/builder/parallels/common/driver_9.go index 97002cb86..7661a30c7 100644 --- a/builder/parallels/common/driver_9.go +++ b/builder/parallels/common/driver_9.go @@ -95,6 +95,29 @@ func getAppPath(bundleId string) (string, error) { return pathOutput, nil } +func (d *Parallels9Driver) DeviceAddCdRom(name string, image string) (string, error) { + command := []string{ + "set", name, + "--device-add", "cdrom", + "--image", image, + } + + out, err := exec.Command(d.PrlctlPath, command...).Output() + if err != nil { + return "", err + } + + deviceRe := regexp.MustCompile(`\s+(cdrom\d+)\s+`) + matches := deviceRe.FindStringSubmatch(string(out)) + if matches == nil { + return "", fmt.Errorf( + "Could not determine cdrom device name in the output:\n%s", string(out)) + } + + device_name := matches[1] + return device_name, nil +} + func (d *Parallels9Driver) IsRunning(name string) (bool, error) { var stdout bytes.Buffer diff --git a/builder/parallels/common/driver_mock.go b/builder/parallels/common/driver_mock.go index 77761586a..25e4ea182 100644 --- a/builder/parallels/common/driver_mock.go +++ b/builder/parallels/common/driver_mock.go @@ -5,6 +5,12 @@ import "sync" type DriverMock struct { sync.Mutex + DeviceAddCdRomCalled bool + DeviceAddCdRomName string + DeviceAddCdRomImage string + DeviceAddCdRomResult string + DeviceAddCdRomErr error + ImportCalled bool ImportName string ImportSrcPath string @@ -45,6 +51,13 @@ type DriverMock struct { IpAddressError error } +func (d *DriverMock) DeviceAddCdRom(name string, image string) (string, error) { + d.DeviceAddCdRomCalled = true + d.DeviceAddCdRomName = name + d.DeviceAddCdRomImage = image + return d.DeviceAddCdRomResult, d.DeviceAddCdRomErr +} + func (d *DriverMock) Import(name, srcPath, dstPath string, reassignMac bool) error { d.ImportCalled = true d.ImportName = name diff --git a/builder/parallels/common/step_attach_floppy.go b/builder/parallels/common/step_attach_floppy.go index 8085cf96c..0e8fba021 100644 --- a/builder/parallels/common/step_attach_floppy.go +++ b/builder/parallels/common/step_attach_floppy.go @@ -39,11 +39,10 @@ func (s *StepAttachFloppy) Run(state multistep.StateBag) multistep.StepAction { "set", vmName, "--device-del", "fdd0", } - if err := driver.Prlctl(del_command...); err != nil { - state.Put("error", fmt.Errorf("Error deleting floppy: %s", err)) - } - ui.Say("Attaching floppy disk...") + // This will almost certainly fail with 'The fdd0 device does not exist.' + driver.Prlctl(del_command...) + ui.Say("Attaching floppy disk...") // Attaching the floppy disk add_command := []string{ "set", vmName, diff --git a/builder/parallels/common/step_attach_parallels_tools.go b/builder/parallels/common/step_attach_parallels_tools.go index b80ddd87e..f681a83f1 100644 --- a/builder/parallels/common/step_attach_parallels_tools.go +++ b/builder/parallels/common/step_attach_parallels_tools.go @@ -17,8 +17,8 @@ import ( // vmName string // // Produces: -// attachedToolsIso boolean type StepAttachParallelsTools struct { + cdromDevice string ParallelsToolsMode string } @@ -37,27 +37,25 @@ func (s *StepAttachParallelsTools) Run(state multistep.StateBag) multistep.StepA parallelsToolsPath := state.Get("parallels_tools_path").(string) // Attach the guest additions to the computer - ui.Say("Attaching Parallels Tools ISO onto IDE controller...") - command := []string{ - "set", vmName, - "--device-add", "cdrom", - "--image", parallelsToolsPath, - } - if err := driver.Prlctl(command...); err != nil { - err := fmt.Errorf("Error attaching Parallels Tools: %s", err) + ui.Say("Attaching Parallels Tools ISO to the new CD/DVD drive...") + + cdrom, err := driver.DeviceAddCdRom(vmName, parallelsToolsPath) + + if err != nil { + err := fmt.Errorf("Error attaching Parallels Tools ISO: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - // Set some state so we know to remove - state.Put("attachedToolsIso", true) + // Track the device name so that we can can delete later + s.cdromDevice = cdrom return multistep.ActionContinue } func (s *StepAttachParallelsTools) Cleanup(state multistep.StateBag) { - if _, ok := state.GetOk("attachedToolsIso"); !ok { + if s.cdromDevice == "" { return } @@ -66,14 +64,10 @@ func (s *StepAttachParallelsTools) Cleanup(state multistep.StateBag) { vmName := state.Get("vmName").(string) log.Println("Detaching Parallels Tools ISO...") - cdDevice := "cdrom0" - if _, ok := state.GetOk("attachedIso"); ok { - cdDevice = "cdrom1" - } command := []string{ "set", vmName, - "--device-del", cdDevice, + "--device-del", s.cdromDevice, } if err := driver.Prlctl(command...); err != nil { diff --git a/builder/parallels/common/step_remove_devices.go b/builder/parallels/common/step_remove_devices.go deleted file mode 100644 index 0bcbc6eb3..000000000 --- a/builder/parallels/common/step_remove_devices.go +++ /dev/null @@ -1,67 +0,0 @@ -package common - -import ( - "fmt" - "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/packer" -) - -// This step removes any devices (floppy disks, ISOs, etc.) from the -// machine that we may have added. -// -// Uses: -// driver Driver -// ui packer.Ui -// vmName string -// -// Produces: -type StepRemoveDevices struct{} - -func (s *StepRemoveDevices) Run(state multistep.StateBag) multistep.StepAction { - driver := state.Get("driver").(Driver) - ui := state.Get("ui").(packer.Ui) - vmName := state.Get("vmName").(string) - - // Remove the attached floppy disk, if it exists - if _, ok := state.GetOk("floppy_path"); ok { - ui.Message("Removing floppy drive...") - command := []string{"set", vmName, "--device-del", "fdd0"} - if err := driver.Prlctl(command...); err != nil { - err := fmt.Errorf("Error removing floppy: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - } - - if _, ok := state.GetOk("attachedIso"); ok { - command := []string{ - "set", vmName, - "--device-set", "cdrom0", - "--device", "Default CD/DVD-ROM", - } - - if err := driver.Prlctl(command...); err != nil { - err := fmt.Errorf("Error detaching ISO: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - } - - if _, ok := state.GetOk("attachedToolsIso"); ok { - command := []string{"set", vmName, "--device-del", "cdrom1"} - - if err := driver.Prlctl(command...); err != nil { - err := fmt.Errorf("Error detaching ISO: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - } - - return multistep.ActionContinue -} - -func (s *StepRemoveDevices) Cleanup(state multistep.StateBag) { -} diff --git a/builder/parallels/common/step_remove_devices_test.go b/builder/parallels/common/step_remove_devices_test.go deleted file mode 100644 index 983b6faad..000000000 --- a/builder/parallels/common/step_remove_devices_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package common - -import ( - "github.com/mitchellh/multistep" - "testing" -) - -func TestStepRemoveDevices_impl(t *testing.T) { - var _ multistep.Step = new(StepRemoveDevices) -} - -func TestStepRemoveDevices(t *testing.T) { - state := testState(t) - step := new(StepRemoveDevices) - - state.Put("vmName", "foo") - - driver := state.Get("driver").(*DriverMock) - - // Test the run - if action := step.Run(state); action != multistep.ActionContinue { - t.Fatalf("bad action: %#v", action) - } - if _, ok := state.GetOk("error"); ok { - t.Fatal("should NOT have error") - } - - // Test that ISO was removed - if len(driver.PrlctlCalls) != 0 { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } -} - -func TestStepRemoveDevices_attachedIso(t *testing.T) { - state := testState(t) - step := new(StepRemoveDevices) - - state.Put("attachedIso", true) - state.Put("vmName", "foo") - - driver := state.Get("driver").(*DriverMock) - - // Test the run - if action := step.Run(state); action != multistep.ActionContinue { - t.Fatalf("bad action: %#v", action) - } - if _, ok := state.GetOk("error"); ok { - t.Fatal("should NOT have error") - } - - // Test that ISO was detached - if len(driver.PrlctlCalls) != 1 { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } - if driver.PrlctlCalls[0][2] != "--device-set" { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } - if driver.PrlctlCalls[0][3] != "cdrom0" { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } - if driver.PrlctlCalls[0][5] != "Default CD/DVD-ROM" { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } -} - -func TestStepRemoveDevices_floppyPath(t *testing.T) { - state := testState(t) - step := new(StepRemoveDevices) - - state.Put("floppy_path", "foo") - state.Put("vmName", "foo") - - driver := state.Get("driver").(*DriverMock) - - // Test the run - if action := step.Run(state); action != multistep.ActionContinue { - t.Fatalf("bad action: %#v", action) - } - if _, ok := state.GetOk("error"); ok { - t.Fatal("should NOT have error") - } - - // Test that both were removed - if len(driver.PrlctlCalls) != 1 { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } - if driver.PrlctlCalls[0][2] != "--device-del" { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } - if driver.PrlctlCalls[0][3] != "fdd0" { - t.Fatalf("bad: %#v", driver.PrlctlCalls) - } -} diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index b177bb27d..5b4c628a1 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -294,7 +294,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Command: b.config.ShutdownCommand, Timeout: b.config.ShutdownTimeout, }, - new(parallelscommon.StepRemoveDevices), } // Setup the state bag diff --git a/builder/parallels/iso/step_attach_iso.go b/builder/parallels/iso/step_attach_iso.go index 7f9f699ad..34d7b2fa9 100644 --- a/builder/parallels/iso/step_attach_iso.go +++ b/builder/parallels/iso/step_attach_iso.go @@ -11,10 +11,14 @@ import ( // This step attaches the ISO to the virtual machine. // // Uses: +// driver Driver +// isoPath string +// ui packer.Ui +// vmName string // // Produces: type stepAttachISO struct { - diskPath string + cdromDevice string } func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction { @@ -24,41 +28,78 @@ func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction { vmName := state.Get("vmName").(string) // Attach the disk to the controller - ui.Say("Attaching ISO onto IDE controller...") - command := []string{ - "set", vmName, - "--device-set", "cdrom0", - "--image", isoPath, - "--enable", "--connect", - } - if err := driver.Prlctl(command...); err != nil { + ui.Say("Attaching ISO to the new CD/DVD drive...") + cdrom, err := driver.DeviceAddCdRom(vmName, isoPath) + + if err != nil { err := fmt.Errorf("Error attaching ISO: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - // Set some state so we know to remove - state.Put("attachedIso", true) + // Set new boot order + ui.Say("Setting the boot order...") + command := []string{ + "set", vmName, + "--device-bootorder", fmt.Sprintf("hdd0 %s cdrom0 net0", cdrom), + } + + if err := driver.Prlctl(command...); err != nil { + err := fmt.Errorf("Error setting the boot order: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Disable 'cdrom0' device + ui.Say("Disabling default CD/DVD drive...") + command = []string{ + "set", vmName, + "--device-set", "cdrom0", "--disable", + } + + if err := driver.Prlctl(command...); err != nil { + err := fmt.Errorf("Error disabling default CD/DVD drive: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Track the device name so that we can can delete later + s.cdromDevice = cdrom return multistep.ActionContinue } func (s *stepAttachISO) Cleanup(state multistep.StateBag) { - if _, ok := state.GetOk("attachedIso"); !ok { + driver := state.Get("driver").(parallelscommon.Driver) + ui := state.Get("ui").(packer.Ui) + vmName := state.Get("vmName").(string) + + // Enable 'cdrom0' device back + log.Println("Enabling default CD/DVD drive...") + command := []string{ + "set", vmName, + "--device-set", "cdrom0", "--enable", + } + + if err := driver.Prlctl(command...); err != nil { + ui.Error(fmt.Sprintf("Error enabling default CD/DVD drive: %s", err)) + } + + // Detach ISO + if s.cdromDevice == "" { return } - driver := state.Get("driver").(parallelscommon.Driver) - vmName := state.Get("vmName").(string) - - command := []string{ + log.Println("Detaching ISO...") + command = []string{ "set", vmName, - "--device-set", "cdrom0", - "--enable", "--disconnect", + "--device-del", s.cdromDevice, } - // Remove the ISO, ignore errors - log.Println("Detaching ISO...") - driver.Prlctl(command...) + if err := driver.Prlctl(command...); err != nil { + ui.Error(fmt.Sprintf("Error detaching ISO: %s", err)) + } } diff --git a/builder/parallels/iso/step_create_disk.go b/builder/parallels/iso/step_create_disk.go index abb6ec2aa..8e5fb63d9 100644 --- a/builder/parallels/iso/step_create_disk.go +++ b/builder/parallels/iso/step_create_disk.go @@ -20,7 +20,7 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { command := []string{ "set", vmName, - "--device-set", "hdd0", + "--device-add", "hdd", "--size", strconv.FormatUint(uint64(config.DiskSize), 10), "--iface", config.HardDriveInterface, } diff --git a/builder/parallels/iso/step_create_vm.go b/builder/parallels/iso/step_create_vm.go index 5f9f4b76f..b48b73dbb 100644 --- a/builder/parallels/iso/step_create_vm.go +++ b/builder/parallels/iso/step_create_vm.go @@ -29,6 +29,7 @@ func (s *stepCreateVM) Run(state multistep.StateBag) multistep.StepAction { "--distribution", config.GuestOSType, "--dst", config.OutputDir, "--vmtype", "vm", + "--no-hdd", } commands[1] = []string{"set", name, "--cpus", "1"} commands[2] = []string{"set", name, "--memsize", "512"} diff --git a/builder/parallels/pvm/builder.go b/builder/parallels/pvm/builder.go index 83ac73b12..037641619 100644 --- a/builder/parallels/pvm/builder.go +++ b/builder/parallels/pvm/builder.go @@ -99,7 +99,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Command: b.config.ShutdownCommand, Timeout: b.config.ShutdownTimeout, }, - new(parallelscommon.StepRemoveDevices), } // Run the steps. diff --git a/website/Gemfile b/website/Gemfile index 5aebf0d94..99e3e69cc 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,12 +1,13 @@ -source 'https://rubygems.org' +source "https://rubygems.org" -gem "middleman", "~> 3.1.5" -gem "middleman-minify-html", "~> 3.1.1" -gem "rack-contrib", "~> 1.1.0" -gem "redcarpet", "~> 3.0.0" -gem "therubyracer", "~> 0.12.0" -gem "thin", "~> 1.5.0" +gem "less", "~> 2.6" +gem "middleman", "~> 3.3" +gem "middleman-minify-html", "~> 3.4" +gem "rack-contrib", "~> 1.1" +gem "redcarpet", "~> 3.1" +gem "therubyracer", "~> 0.12" +gem "thin", "~> 1.6" group :development do - gem "highline", "~> 1.6.15" + gem "highline", "~> 1.6" end diff --git a/website/Gemfile.lock b/website/Gemfile.lock index cc154491d..dd50f1ecc 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -1,109 +1,143 @@ GEM remote: https://rubygems.org/ specs: - activesupport (3.2.15) - i18n (~> 0.6, >= 0.6.4) - multi_json (~> 1.0) - chunky_png (1.2.9) - coffee-script (2.2.0) + activesupport (4.1.6) + i18n (~> 0.6, >= 0.6.9) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.1) + tzinfo (~> 1.1) + celluloid (0.16.0) + timers (~> 4.0.0) + chunky_png (1.3.1) + coffee-script (2.3.0) coffee-script-source execjs - coffee-script-source (1.6.3) - compass (0.12.2) + coffee-script-source (1.8.0) + commonjs (0.2.7) + compass (1.0.1) chunky_png (~> 1.2) - fssm (>= 0.2.7) - sass (~> 3.1) - daemons (1.1.9) - eventmachine (1.0.3) - execjs (1.4.0) - multi_json (~> 1.0) - ffi (1.9.0) - fssm (0.2.10) - haml (4.0.3) - tilt - highline (1.6.20) - hike (1.2.3) - i18n (0.6.5) - kramdown (1.2.0) - libv8 (3.16.14.3) - listen (1.3.1) + compass-core (~> 1.0.1) + compass-import-once (~> 1.0.5) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - rb-kqueue (>= 0.2) - middleman (3.1.6) - coffee-script (~> 2.2.0) - compass (>= 0.12.2) - execjs (~> 1.4.0) - haml (>= 3.1.6) + sass (>= 3.3.13, < 3.5) + compass-core (1.0.1) + multi_json (~> 1.0) + sass (>= 3.3.0, < 3.5) + compass-import-once (1.0.5) + sass (>= 3.2, < 3.5) + daemons (1.1.9) + erubis (2.7.0) + eventmachine (1.0.3) + execjs (2.2.1) + ffi (1.9.5) + haml (4.0.5) + tilt + highline (1.6.21) + hike (1.2.3) + hitimes (1.2.2) + hooks (0.4.0) + uber (~> 0.0.4) + htmlcompressor (0.1.2) + i18n (0.6.11) + json (1.8.1) + kramdown (1.4.2) + less (2.6.0) + commonjs (~> 0.2.7) + libv8 (3.16.14.7) + listen (2.7.11) + celluloid (>= 0.15.2) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + middleman (3.3.6) + coffee-script (~> 2.2) + compass (>= 1.0.0, < 2.0.0) + compass-import-once (= 1.0.5) + execjs (~> 2.0) + haml (>= 4.0.5) kramdown (~> 1.2) - middleman-core (= 3.1.6) - middleman-more (= 3.1.6) + middleman-core (= 3.3.6) middleman-sprockets (>= 3.1.2) - sass (>= 3.1.20) - uglifier (~> 2.1.0) - middleman-core (3.1.6) - activesupport (~> 3.2.6) + sass (>= 3.4.0, < 4.0) + uglifier (~> 2.5) + middleman-core (3.3.6) + activesupport (~> 4.1.0) bundler (~> 1.1) - i18n (~> 0.6.1) - listen (~> 1.1) - rack (>= 1.4.5) - rack-test (~> 0.6.1) + erubis + hooks (~> 0.3) + i18n (~> 0.6.9) + listen (>= 2.7.9, < 3.0) + padrino-helpers (~> 0.12.3) + rack (>= 1.4.5, < 2.0) + rack-test (~> 0.6.2) thor (>= 0.15.2, < 2.0) - tilt (~> 1.3.6) - middleman-minify-html (3.1.1) - middleman-core (~> 3.0) - middleman-more (3.1.6) - middleman-sprockets (3.1.4) - middleman-core (>= 3.0.14) - middleman-more (>= 3.0.14) - sprockets (~> 2.1) - sprockets-helpers (~> 1.0.0) - sprockets-sass (~> 1.0.0) - multi_json (1.8.2) + tilt (~> 1.4.1, < 2.0) + middleman-minify-html (3.4.0) + htmlcompressor (~> 0.1.0) + middleman-core (>= 3.2) + middleman-sprockets (3.3.10) + middleman-core (~> 3.3) + sprockets (~> 2.12.1) + sprockets-helpers (~> 1.1.0) + sprockets-sass (~> 1.2.0) + minitest (5.4.2) + multi_json (1.10.1) + padrino-helpers (0.12.3) + i18n (~> 0.6, >= 0.6.7) + padrino-support (= 0.12.3) + tilt (~> 1.4.1) + padrino-support (0.12.3) + activesupport (>= 3.1) rack (1.5.2) rack-contrib (1.1.0) rack (>= 0.9.1) rack-test (0.6.2) rack (>= 1.0) - rb-fsevent (0.9.3) - rb-inotify (0.9.2) + rb-fsevent (0.9.4) + rb-inotify (0.9.5) ffi (>= 0.5.0) - rb-kqueue (0.2.0) - ffi (>= 0.5.0) - redcarpet (3.0.0) + redcarpet (3.1.2) ref (1.0.5) - sass (3.2.12) - sprockets (2.10.0) + sass (3.4.5) + sprockets (2.12.2) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-helpers (1.0.1) + sprockets-helpers (1.1.0) sprockets (~> 2.0) - sprockets-sass (1.0.2) + sprockets-sass (1.2.0) sprockets (~> 2.0) tilt (~> 1.1) - therubyracer (0.12.0) + therubyracer (0.12.1) libv8 (~> 3.16.14.0) ref - thin (1.5.1) - daemons (>= 1.0.9) - eventmachine (>= 0.12.6) - rack (>= 1.0.0) - thor (0.18.1) - tilt (1.3.7) - uglifier (2.1.2) + thin (1.6.3) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0) + rack (~> 1.0) + thor (0.19.1) + thread_safe (0.3.4) + tilt (1.4.1) + timers (4.0.1) + hitimes + tzinfo (1.2.2) + thread_safe (~> 0.1) + uber (0.0.8) + uglifier (2.5.3) execjs (>= 0.3.0) - multi_json (~> 1.0, >= 1.0.2) + json (>= 1.8.0) PLATFORMS ruby DEPENDENCIES - highline (~> 1.6.15) - middleman (~> 3.1.5) - middleman-minify-html (~> 3.1.1) - rack-contrib (~> 1.1.0) - redcarpet (~> 3.0.0) - therubyracer (~> 0.12.0) - thin (~> 1.5.0) + highline (~> 1.6) + less (~> 2.6) + middleman (~> 3.3) + middleman-minify-html (~> 3.4) + rack-contrib (~> 1.1) + redcarpet (~> 3.1) + therubyracer (~> 0.12) + thin (~> 1.6) diff --git a/website/counter.txt b/website/counter.txt deleted file mode 100644 index e2b48f13b..000000000 --- a/website/counter.txt +++ /dev/null @@ -1,4 +0,0 @@ -Just update this if you want to force a website push and it isn't -working: - -1