def _get_standard_path(): if OSInfo.is_win(): return 'C:/Program Files (x86)/Arduino' elif OSInfo.is_linux(): return '/usr/share/arduino' elif OSInfo.is_mac(): return '/Applications/Arduino.app/Contents/Resources/Java'
def _install_cmake(user_io, bii_paths): user_io.out.writeln('Downloading and installing CMake %s' % _CMAKE_VERSION, front=Color.GREEN) if OSInfo.is_win(): return _install_cmake_win(user_io, bii_paths) elif OSInfo.is_mac(): return _install_cmake_mac(user_io) elif OSInfo.is_linux(): return _install_cmake_linux(user_io, bii_paths)
def get_arduino_download_url(version): if OSInfo.is_win(): url = S3_URL + "arduino-%s-windows.zip" % version elif OSInfo.is_mac(): url = S3_URL + "arduino-%s-macosx.zip" % version elif OSInfo.is_linux(): if OSInfo.architecture() == "64bit": url = S3_URL + "arduino-%s-linux64.tgz" % version elif OSInfo.architecture() == "32bit": url = S3_URL + "arduino-%s-linux32.tgz" % version return url
def install_linux_x32_compatibility(user_io): if OSInfo.is_linux() and OSInfo.architecture() == Architecture("64bit"): cmd = "dpkg-query -S lib32z1" exit_code, _ = execute(cmd, UserIO(out=BiiOutputStream(StringIO()))) if exit_code == 0: user_io.out.writeln('x86 compatibility for 64bits already installed', front=Color.GREEN) else: user_io.out.writeln('Installing x86 compatibility for 64bits architecture...', front=Color.GREEN) user_io.out.warn('Installing lib32z1 as "sudo", enter "sudo" password if requested') os.system('sudo apt-get install lib32z1')
def virtual_test(self): references = References() references[va].add('a.h') code = ( 'def virtual(settings):\n\tif(settings.os.family == "windows"):return "win"\n' '\telse: return "nix"') a = Resource(VirtualCell('user/blocka/a.h', code, {'win', 'nix'})) awin = Resource(SimpleCell('user/blocka/win/a.h')) anix = Resource(SimpleCell('user/blocka/nix/a.h')) b = Resource(SimpleCell('user/blockb/b.h')) d1 = Resource(SimpleCell('user/blockd/d.h')) awin.cell.dependencies.explicit.add(b.name) anix.cell.dependencies.explicit.add(d1.name) tables = {va: [vb, vd1], vb: [], vd1: []} api = FakeApi(zip([va, va, va, vb, vd1], [a, awin, anix, b, d1]), tables) #With windows settings settings = Settings(OSInfo(OSFamily("Windows"))) biiout = OutputStream() graph, closure, _ = build_closure(api, references, {}, settings, biiout) expected_graph = BlockVersionGraph() expected_graph.add_nodes([va, vb]) expected_graph.add_edge(va, vb) self.assertEqual(expected_graph, graph) expected_closure = Closure({ a.name: ClosureItem(a, va), awin.name: ClosureItem(awin, va), b.name: ClosureItem(b, vb), }) self.assertEqual(expected_closure, closure) self.assertEqual("", str(biiout)) #Change settings settings = Settings(OSInfo(OSFamily("Linux"))) biiout = OutputStream() graph, closure, _ = build_closure(api, references, {}, settings, biiout) expected_graph = BlockVersionGraph() expected_graph.add_nodes([va, vd1]) expected_graph.add_edge(va, vd1) self.assertEqual(expected_graph, graph) expected_closure = Closure({ a.name: ClosureItem(a, va), anix.name: ClosureItem(anix, va), d1.name: ClosureItem(d1, vd1), }) self.assertEqual(expected_closure, closure) self.assertEqual("", str(biiout))
def _get_cmake_download_url(): if OSInfo.is_win(): url = S3_URL + "cmake-%s-win32-x86.zip" % _CMAKE_VERSION elif OSInfo.is_mac(): url = S3_URL + 'cmake-%s-Darwin64-universal.dmg' % _CMAKE_VERSION elif OSInfo.is_linux(): import platform if OSInfo.architecture() == "64bit": url = S3_URL + "cmake-%s-Linux-64.tar.gz" % _CMAKE_VERSION elif OSInfo.architecture() == "32bit": url = S3_URL + "cmake-%s-Linux-i386.tar.gz" % _CMAKE_VERSION if platform.machine() == "armv6l" or platform.machine() == "armv7l": url = S3_URL + "cmake-%s-Linux-armv6.tar.gz" % _CMAKE_VERSION return url
def valid_arduino_sdk_version(sdk_path, biiout=None): """Returns None or version supported as string Parameters: sdk_path: BASE_FOLDER[/Arduino.app/Contents/Resources/Java] """ path_version = os.path.join(sdk_path, "lib", "version.txt") if not os.path.exists(path_version): return None with open(path_version) as versiontxt: data = versiontxt.read() if OSInfo.is_linux(): if _incompatible_avr_gcc_version_in_path(): if biiout: biiout.warn("There isn't a fully compatible version of gcc-avr" " so it can fail compiling some modules like WiFi.h\n" "It's not a biicode issue, official arduino SDK will fail too. " "More information is available here: http://goo.gl/AldCzv\n" "You can solve this issue by uninstalling apt-get version of gcc-avr:\n" " $ sudo apt-get remove gcc-avr\n" " $ bii setup:arduino\n" " $ bii clean\n" " $ bii arduino:configure\n") for version in ARDUINO_SDK_COMPATIBLE_VERSIONS: if version in data: return version return None
def get_biicode_env_folder_path(): """ this folder is used to store automatically downloaed ArduinoSDK and RPI cross compilers """ if OSInfo.is_win(): return os.path.normpath("C:/biicode_env") else: return os.path.expanduser("~/.biicode_env")
def valid_arduino_sdk_version(sdk_path, biiout=None): """Returns None or version supported as string Parameters: sdk_path: BASE_FOLDER[/Arduino.app/Contents/Resources/Java] """ path_version = os.path.join(sdk_path, "lib", "version.txt") if not os.path.exists(path_version): return None with open(path_version) as versiontxt: data = versiontxt.read() if OSInfo.is_linux(): if _incompatible_avr_gcc_version_in_path(): if biiout: biiout.warn( "There isn't a fully compatible version of gcc-avr" " so it can fail compiling some modules like WiFi.h\n" "It's not a biicode issue, official arduino SDK will fail too. " "More information is available here: http://goo.gl/AldCzv\n" "You can solve this issue by uninstalling apt-get version of gcc-avr:\n" " $ sudo apt-get remove gcc-avr\n" " $ bii setup:arduino\n" " $ bii clean\n" " $ bii arduino:configure\n") for version in ARDUINO_SDK_COMPATIBLE_VERSIONS: if version in data: return version return None
def _os_constraint(self, *args, **kargs): os_info = OSInfo.capture() if os_info.family == os_name: func(self, *args, **kargs) else: self.user_io.out.error('You need to use a {} OS'.format(os_name))
def install_linux_x32_compatibility(user_io): if OSInfo.is_linux() and OSInfo.architecture() == Architecture("64bit"): cmd = "dpkg-query -S lib32z1" exit_code, _ = execute(cmd, UserIO(out=BiiOutputStream(StringIO()))) if exit_code == 0: user_io.out.writeln( 'x86 compatibility for 64bits already installed', front=Color.GREEN) else: user_io.out.writeln( 'Installing x86 compatibility for 64bits architecture...', front=Color.GREEN) user_io.out.warn( 'Installing lib32z1 as "sudo", enter "sudo" password if requested' ) os.system('sudo apt-get install lib32z1')
def _os_constraint(self, *args, **kargs): os_info = OSInfo.capture() if os_info.family == os_name: func(self, *args, **kargs) else: self.user_io.out.error( 'You need to use a {} OS'.format(os_name))
def install_gnu(user_io, optional): if _valid_gnu_version(user_io): return if OSInfo.is_mac(): user_io.out.warn('A new window will open, please click on "Obtain Xcode" and install' 'Xcode from AppStore') os.system('xcode-select --install') user_io.request_string('Please press ENTER when finished installing cmake') elif OSInfo.is_linux(): user_io.out.warn('Installing as "sudo", enter "sudo" password if requested') if OSInfo.is_debian_based_linux(): os.system('sudo apt-get install build-essential') elif OSInfo.is_redhat_based_linux(): os.system('sudo yum -y install wget make automake gcc gcc-c++ kernel-devel') else: return install_mingw(user_io, optional)
def _sphere_os_checks(self, name): vsphere = self.block_holder[name].cell self.assertTrue(isinstance(vsphere, VirtualCell), '%s is not a VirtualCell' % vsphere.name) self.assertEqual(set(['win', 'nix']), vsphere.leaves) self.assertEqual(set(['user/block/win/%s' % name, 'user/block/nix/%s' % name]), set(vsphere.resource_leaves)) settings = Settings(OSInfo('linux')) self.assertEqual('user/block/nix/%s' % name, vsphere.evaluate(settings)) settings = Settings(OSInfo('windows')) self.assertEqual('user/block/win/%s' % name, vsphere.evaluate(settings)) winsphere = self.block_holder['win/%s' % name].cell self.assertTrue(isinstance(winsphere, SimpleCell)) nixsphere = self.block_holder['nix/%s' % name].cell self.assertTrue(isinstance(nixsphere, SimpleCell))
def _get_all_arduino_sdk_paths(): """Get all the paths we need to look at an SDK""" paths_to_look = [_get_standard_path()] for compatible in ARDUINO_SDK_COMPATIBLE_VERSIONS: version_path = os.path.join(get_biicode_env_folder_path(), "arduino-%s" % compatible) if OSInfo.is_mac(): version_path = os.path.join(version_path, "Arduino.app/Contents/Resources/Java") paths_to_look.append(version_path.replace('\\', '/')) return paths_to_look
def get_server_info(self): """Gets a ServerInfo and sends os_info + client version to server""" os_info = OSInfo.capture() from biicode.common import __version__ data = (os_info, str(__version__)) serialized_data = Serializer().build(("data", data)) info = self.bson_jwt_call('get_server_info', data=serialized_data, deserializer=ServerInfo, timeout=1) return info
def __init__(self, name_id, biiType, version_id=None, language_version=None, os_info=None, tool_info=None, path=""): self.name_id = name_id self.biiType = biiType self.__version_id = version_id self.__language_version = language_version or Version() self.os_info = os_info or OSInfo() self.tool_info = tool_info or ToolInfo() self.path = path
def __init__(self, os_info=None): self.os = os_info or OSInfo.capture() self.cmake = CMakeSettings() self.cpp = CPPSettings() self.rpi = RPiSettings() self.arduino = ArduinoSettings() self.node = LanguageSettings() self.fortran = LanguageSettings() self.python = LanguageSettings() self.user = UserSettings()
def deserialize(data): return SystemID( data[SystemID.SERIAL_NAME_ID_KEY], version_id=Version.deserialize(data[SystemID.SERIAL_VERSION_ID_KEY]), biiType=BiiType.deserialize(data[SystemID.SERIAL_BIITYPE_KEY]), language_version=Version.deserialize(data[SystemID.SERIAL_LANGUAGE_VERSION_KEY]), os_info=OSInfo.deserialize(data[SystemID.SERIAL_OS_INFO_KEY]), tool_info=ToolInfo.deserialize(data[SystemID.SERIAL_TOOL_INFO_KEY]), path=data[SystemID.SERIAL_PATH_KEY], )
def ssh_upload(self, possible_firmwares, ip): '''Uploading the firmware to Arduino''' firmware = _firmware_to_upload(self.bii, possible_firmwares) self.bii.user_io.out.writeln('Uploading...') if not OSInfo.is_win(): scp_command = "scp %s.hex root@%s:/tmp/" % (firmware, ip) ssh_command = "ssh root@%s /usr/bin/run-avrdude /tmp/%s.hex -q -q" % (ip, firmware) bii_paths = self.bii.bii_paths self._execute_command(scp_command, bii_paths.bin) self._execute_command(ssh_command)
def upload(self, possible_firmwares): '''Uploading the firmware to Arduino''' firmware = _firmware_to_upload(self.bii, possible_firmwares) self.bii.user_io.out.writeln('Uploading...') build_command = 'make' if sys.platform != 'win32' else 'mingw32-make' if OSInfo.is_linux(): build_command = "sudo %s" % build_command build_command = "%s %s-upload" % (build_command, firmware) self._execute_upload_command(build_command)
def unzip(filename, destination): import zipfile with zipfile.ZipFile(filename, "r") as z: if OSInfo.is_linux() or OSInfo.is_mac(): for zinfo in z.filelist: zinfo.create_system = 3 # UNIX if OSInfo.is_mac(): for thefile in z.filelist: name = thefile.filename perm = ((thefile.external_attr >> 16L) & 0777) if name.endswith('/'): os.mkdir(os.path.join(destination, name), perm) else: outfile = os.path.join(destination, name) fh = os.open(outfile, os.O_CREAT | os.O_WRONLY, perm) os.write(fh, z.read(name)) os.close(fh) z.close() else: z.extractall(destination)
def ssh_upload(self, possible_firmwares, ip): '''Uploading the firmware to Arduino''' firmware = _firmware_to_upload(self.bii, possible_firmwares) self.bii.user_io.out.writeln('Uploading...') if not OSInfo.is_win(): scp_command = "scp %s.hex root@%s:/tmp/" % (firmware, ip) ssh_command = "ssh root@%s /usr/bin/run-avrdude /tmp/%s.hex -q -q" % ( ip, firmware) bii_paths = self.bii.bii_paths self._execute_command(scp_command, bii_paths.bin) self._execute_command(ssh_command)
def install_gnu(user_io, optional): if _valid_gnu_version(user_io): return if OSInfo.is_mac(): user_io.out.warn( 'A new window will open, please click on "Obtain Xcode" and install' 'Xcode from AppStore') os.system('xcode-select --install') user_io.request_string( 'Please press ENTER when finished installing cmake') elif OSInfo.is_linux(): user_io.out.warn( 'Installing as "sudo", enter "sudo" password if requested') if OSInfo.is_debian_based_linux(): os.system('sudo apt-get install build-essential') elif OSInfo.is_redhat_based_linux(): os.system( 'sudo yum -y install wget make automake gcc gcc-c++ kernel-devel' ) else: return install_mingw(user_io, optional)
def settings(self, *parameters): '''Configure Raspberry Pi project settings''' parser = argparse.ArgumentParser(description=self.settings.__doc__, prog="bii %s:settings" % self.group) parser.add_argument('--user', help='Your RPi user session, e.g.: pi') parser.add_argument("--ip", help="Your RPi IP, e.g.: 50.1.2.3") parser.add_argument( "--directory", help="Directory where you'll send the binary files, e.g.: bin") args = parser.parse_args(*parameters) # for -h settings = self.hive_disk_image.settings if any([args.user, args.ip, args.directory]): rpi_settings_args(args, settings) else: rpi_settings_wizard(self.user_io, settings) #Write to disk self.hive_disk_image.settings = settings self.user_io.out.info('Settings saved in: %s' % self.paths.settings) toolchain_rpi_path = os.path.join(self.paths.bii, "rpi_toolchain.cmake") if not os.path.exists(toolchain_rpi_path): if OSInfo.is_linux(): self.user_io.out.write('Creating toolchain for Raspberry PI\n', Color.BLUE) c_path, cpp_path = find_gnu_arm() if not c_path or not cpp_path: self.user_io.out.error( "Unable to find RPI cross-compilers.\n" "Try executing bii setup:rpi") content = [] content.append("INCLUDE(CMakeForceCompiler)") content.append("SET(CMAKE_SYSTEM_NAME Linux)") content.append("SET(CMAKE_SYSTEM_VERSION 1)") content.append("SET(CMAKE_C_COMPILER %s)" % c_path) content.append("SET(CMAKE_CXX_COMPILER %s)" % cpp_path) content = os.linesep.join(content) save_blob_if_modified(toolchain_rpi_path, Blob(content)) self.user_io.out.success( 'Run "bii configure -t rpi" to activate it') self.user_io.out.success( 'Run "bii configure -t" to disable it') else: self.user_io.out.error( "Toolchain for R-Pi only available in Linux now") self.user_io.out.error( "You can try to define your own bii/rpi_toolchain.cmake")
def _install_arduino_sdk(user_io): url = get_arduino_download_url(CURRENT_VERSION) decompress_to_folder = _get_install_arduino_sdk_path(CURRENT_VERSION) if url: filename = download(url, url.split("/")[-1]) user_io.out.info("Unzipping arduino SDK. Please wait, this can take a while...") if not os.path.exists(decompress_to_folder): os.makedirs(decompress_to_folder) decompress(filename, decompress_to_folder) osinfo = OSInfo.capture() if osinfo.family == 'Windows' and osinfo.subfamily == '8': drivers = '%s/drivers' % decompress_to_folder user_io.out.warn('Windows 8 does not automatically detect Arduino drivers.\n' 'When installing the drivers, please use this folder: %s' % drivers)
def rpi(self, *parameters): '''Setup cross compiler tools for Raspberry Pi (must be linux)''' parser = argparse.ArgumentParser(description=self.rpi.__doc__, prog="bii %s:rpi" % self.group) parser.add_argument( "-i", "--interactive", default=False, action='store_true', help='Runs in interactive mode, can require user input') args = parser.parse_args(*parameters) if not OSInfo.is_linux(): raise BiiException('You need to use a linux OS') # If we are installing c++ cross compiler... we need the other c++ tools install_gnu_arm(self.bii.user_io) self._setup_cpp(args.interactive)
def _setup_cpp(self, interactive): restart_console = False try: paths = self.bii.bii_paths install_cmake(self.bii.user_io, paths, interactive) gnu_optional = OSInfo.is_win() # GNU in windows is optional, you could use Visual restart_console2 = install_gnu(self.bii.user_io, gnu_optional) restart_console = restart_console or restart_console2 except BiiException as e: self.bii.user_io.out.error(str(e)) raise BiiException( "The cpp setup has failed. Please fix problems and launch bii " "setup:cpp again") finally: if restart_console: self.bii.user_io.out.warn( 'The PATH has changed, it is necessary ' 'to CLOSE this window') self.bii.user_io.out.warn('Please close this window')
def install_gnu_arm(user_io): if not OSInfo.is_linux(): raise ClientException("ARM Cross compile only works on Linux") install_linux_x32_compatibility(user_io) c_path, cpp_path = find_gnu_arm() if c_path is None or cpp_path is None: url = S3_URL + "raspberry_cross_compilers.tgz" filename = download(url, url.split("/")[-1]) user_io.out.info("Unzipping arm gnu SDK") install_path = get_biicode_env_folder_path() if not os.path.exists(install_path): os.mkdir(install_path) decompress(filename, install_path) user_io.out.success('Installed GNU ARM compilers for RPI') # Try to find again c_path, cpp_path = find_gnu_arm() else: user_io.out.writeln('The arm gnu is already downloaded', front=Color.GREEN) return c_path, cpp_path
def test_os_local_info(self): #TODO test this on different os os_info = OSInfo.capture() os = platform.system().lower() family = OSInfo.platforms.get(os) self.assertEquals(os_info.family, family) if family == 'linux': subfamily = platform.linux_distribution()[0] version = Version(platform.linux_distribution()[1]) elif family == 'windows': subfamily = platform.release() version = Version(platform.version()) elif family == 'macos': subfamily = None version = Version(platform.mac_ver()[0]) else: subfamily = "" version = "" self.assertEquals(os_info.subfamily, subfamily) self.assertEquals(os_info.version, version)
def _handle_generator(self, generator): """ update current settings with the arg passed generator, or define a default generator. If settings for the toolchain do not exist, they might be created, as defaults or requested to user by wizard (e.g. arduino board) param generator: possible None. Text string with the Cmake generator """ hive_disk_image = self.hive_disk_image settings = hive_disk_image.settings if generator: if generator != settings.cmake.generator: if settings.cmake.generator: self.bii.user_io.out.warn( "Changed CMake generator, regenerating project") hive_disk_image.delete_build_folder() settings.cmake.generator = generator hive_disk_image.settings = settings else: if not settings.cmake.generator: if OSInfo.is_win(): settings.cmake.generator = "MinGW Makefiles" else: settings.cmake.generator = "Unix Makefiles" hive_disk_image.settings = settings
def _reset_serial(out, serial_port, wait_for_upload_port=False): ''' Code original from https://github.com/Robot-Will/Stino/tree/master/app adapted to biicode to reset Arduino ports Reset any serial port. parameters: out: bii.user_io.out serial_port: current serial port detected wait_for_upload_port: True if board == 'leonardo' return: selected port ''' caterina_serial_port = '' before_serial_list = _detect_arduino_port() if serial_port in before_serial_list: non_serial_list = before_serial_list[:] non_serial_list.remove(serial_port) out.success('Forcing reset using 1200bps open/close on port %s' % serial_port) _touch_serial_port(serial_port, 1200) if not wait_for_upload_port: time.sleep(0.4) return serial_port # Scanning for available ports seems to open the port or # otherwise assert DTR, which would cancel the WDT reset if # it happened within 250 ms. So we wait until the reset should # have already occurred before we start scanning. time.sleep(3 if OSInfo.is_win() else 0.3) # Wait for a port to appear on the list elapsed = 0 while (elapsed < 10000): now_serial_list = _detect_arduino_port() diff_serial_list = [v for v in now_serial_list if v not in non_serial_list] out.success('Ports {%s}/{%s} => {%s}' % (before_serial_list, now_serial_list, diff_serial_list)) if len(diff_serial_list) > 0: caterina_serial_port = diff_serial_list[0] out.success('Found new upload port: %s' % caterina_serial_port) break # Keep track of port that disappears # before_serial_list = now_serial_list time.sleep(0.25) elapsed += 250 # On Windows, it can take a long time for the port to disappear and # come back, so use a longer time out before assuming that the selected # port is the bootloader (not the sketch). if (((not OSInfo.is_win() and elapsed >= 500) or elapsed >= 5000) and (serial_port in now_serial_list)): out.success('Uploading using selected port: %s' % serial_port) caterina_serial_port = serial_port break if not caterina_serial_port: out.error("Couldn't find a Leonardo on the selected port. " "Check that you have the correct port selected. " "If it is correct, try pressing the board's reset" " button after initiating the upload.") return caterina_serial_port or 'None'
def __init__(self, os_name_mock): os_info.capture = Mock(return_value=OSInfo(os_name_mock)) self.user_io = Mock()
def _get_install_arduino_sdk_path(version): if OSInfo.is_mac(): decompress_to_folder = os.path.join(get_biicode_env_folder_path(), "arduino-%s" % version) else: decompress_to_folder = get_biicode_env_folder_path() return decompress_to_folder
def set_generic_system(self): self.language_version = Version() self.os_info = OSInfo()